C 中的双三次插值

2023-12-31

我正在尝试处理c中的双三次图像插值。因此我构建了这个小脚本。

1.“resize_image”函数:

    void resize_image(PPMImage *source_image, PPMImage *destination_image, float scale) {

        uint8_t sample[3];
        int y, x;

        destination_image->x = (long)((float)(source_image->x)*scale);
        destination_image->y = (long)((float)(source_image->y)*scale);

        for (y = 0; y < destination_image->y; y++) {

            float v = (float)y / (float)(destination_image->y - 1);

            for (x = 0; x < destination_image->x; ++x) {

                float u = (float)x / (float)(destination_image->x - 1);
                sample_bicubic(source_image, u, v, sample);

                destination_image->data[x+((destination_image->y)*y)].red   = sample[0];
                destination_image->data[x+((destination_image->y)*y)].green = sample[1];  
                destination_image->data[x+((destination_image->y)*y)].blue  = sample[2];  
            }
        }
    }

2.“sample_bicubic”函数

    void sample_bicubic(PPMImage *source_image, float u, float v, uint8_t sample[]) {

        float x = (u * source_image->x)-0.5;
        int xint = (int)x;
        float xfract = x-floor(x);

        float y = (v * source_image->y) - 0.5;
        int yint = (int)y;
        float yfract = y - floor(y);

        int i;

        uint8_t p00[3];
        uint8_t p10[3];
        uint8_t p20[3];
        uint8_t p30[3];

        uint8_t p01[3];
        uint8_t p11[3];
        uint8_t p21[3];
        uint8_t p31[3];

        uint8_t p02[3];
        uint8_t p12[3];
        uint8_t p22[3];
        uint8_t p32[3];

        uint8_t p03[3];
        uint8_t p13[3];
        uint8_t p23[3];
        uint8_t p33[3];

        // 1st row
        get_pixel_clamped(source_image, xint - 1, yint - 1, p00);   
        get_pixel_clamped(source_image, xint + 0, yint - 1, p10);
        get_pixel_clamped(source_image, xint + 1, yint - 1, p20);
        get_pixel_clamped(source_image, xint + 2, yint - 1, p30);

        // 2nd row
        get_pixel_clamped(source_image, xint - 1, yint + 0, p01);
        get_pixel_clamped(source_image, xint + 0, yint + 0, p11);
        get_pixel_clamped(source_image, xint + 1, yint + 0, p21);
        get_pixel_clamped(source_image, xint + 2, yint + 0, p31);

        // 3rd row
        get_pixel_clamped(source_image, xint - 1, yint + 1, p02);
        get_pixel_clamped(source_image, xint + 0, yint + 1, p12);
        get_pixel_clamped(source_image, xint + 1, yint + 1, p22);
        get_pixel_clamped(source_image, xint + 2, yint + 1, p32);

        // 4th row
        get_pixel_clamped(source_image, xint - 1, yint + 2, p03);
        get_pixel_clamped(source_image, xint + 0, yint + 2, p13);
        get_pixel_clamped(source_image, xint + 1, yint + 2, p23);
        get_pixel_clamped(source_image, xint + 2, yint + 2, p33);

        // interpolate bi-cubically!
        for (i = 0; i < 3; i++) {

            float col0 = cubic_hermite(p00[i], p10[i], p20[i], p30[i], xfract);
            float col1 = cubic_hermite(p01[i], p11[i], p21[i], p31[i], xfract);
            float col2 = cubic_hermite(p02[i], p12[i], p22[i], p32[i], xfract);
            float col3 = cubic_hermite(p03[i], p13[i], p23[i], p33[i], xfract);

            float value = cubic_hermite(col0, col1, col2, col3, yfract);

            CLAMP(value, 0.0f, 255.0f);

            sample[i] = (uint8_t)value;

            printf("sample[%d]=%d\n",i,sample[i]);      

        }
    }

3.“插值助手”

    float cubic_hermite(float A, float B, float C, float D, float t) {

        float a = -A / 2.0f + (3.0f*B) / 2.0f - (3.0f*C) / 2.0f + D / 2.0f;
        float b = A - (5.0f*B) / 2.0f + 2.0f*C - D / 2.0f;
        float c = -A / 2.0f + C / 2.0f;
        float d = B;

        return a*t*t*t + b*t*t + c*t + d;
    }

    void get_pixel_clamped(PPMImage *source_image, int x, int y, uint8_t temp[])  {

        CLAMP(x, 0, source_image->x - 1);
        CLAMP(y, 0, source_image->y - 1);

        temp[0] = source_image->data[x+(W*y)].red;
        temp[1] = source_image->data[x+(W*y)].green;
        temp[2] = source_image->data[x+(W*y)].blue;
    }

我已经上传了完整的代码以及所有相关内容here http://pastebin.com/sQDQg7SG.

执行此代码没有语法错误。

但输出图像让我困惑。

输入图像(21x20像素):

该输入图像放大 2 倍(42x40 像素):

插值在某些点上似乎工作正常,但图像看起来像素发生了偏移。

有人可以告诉我我做错了什么吗? 该脚本是在以下人员的帮助下编写的:http://blog.demofox.org/2015/08/15/resizing-images-with-bicubic-interpolation/ http://blog.demofox.org/2015/08/15/resizing-images-with-bicubic-interpolation/

多谢你们!

(请不要考虑这段代码的效率......我知道它很棒)


从您的 resize_image() 函数:

destination_image->data[x+((destination_image->y)*y)].red   = sample[0];

那大概应该是

destination_image->data[x+((destination_image->x)*y)].red   = sample[0];

有助于调试此类情况的方法是使用实​​际数据中不存在的一些“神奇颜色”初始化目标图像(例如一些可怕的粉红色:-))。然后您可能会注意到,在 resize_image() 调用之后,某些目标像素仍然具有该颜色。这就暗示了问题所在。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 中的双三次插值 的相关文章

  • CMake 和 Visual Studio:如何获得快速、安静的命令行构建?

    我有一个 cmake 项目 它成功地完成了我想要的一切 但我有大约 100 个文件 当我只需要重新编译一个文件时 我厌倦了每次看到生成的巨大输出 每个文件 30 行 明确地说 我正在编译cmake build 得到这个结果 我需要传递给编译
  • C 中的复合语句表达式

    下面的代码不起作用 int i void 999 100 添加括号就可以了 为什么 int i void 999 100 还有另一种方法可以完成此类分配 int i void 999 100 是什么让他们与众不同 在这份声明中 int i
  • 如何在 MFC 中调整对话框大小时移动控件?

    我已经在 MFC 中创建了对话框视图 从下图中可以清楚地看到 如滑块控件和编辑框等 当我调整对话框大小时 这些控件不会移动 在此输入图像描述 https i stack imgur com 7OxAK jpg 我想移动控件以适应对话框 但不
  • 将指针转换为浮点数?

    我有一个unsigned char 通常 这指向一块数据 但在某些情况下 指针就是数据 即 铸造一个int的价值unsigned char 指针 unsigned char intData unsigned char myInteger 反
  • 避免集合已修改错误

    Issue 我有以下代码 foreach var ItemA in GenericListInstanceB ItemA MethodThatCouldRemoveAnyItemInGenericListInstanceB 显然我得到一个错
  • 在 Python 中倾斜数组

    我有一个 2D 数组 我将使用它保存为灰度图像scipy misc toimage 在此之前 我想将图像倾斜给定角度 像这样进行插值scipy ndimage interpolation rotate 上图只是为了说明倾斜过程 我知道我必须
  • 如何“杀死”Pthread?

    我正在学习 Pthreads 并且想知道杀死这样一个对象的最佳方法是什么 在寻找类似的问题后 我无法找到 明确 的答案 但请随时向我指出任何相关问题 我正在使用一个小型客户端服务器应用程序 其中服务器主线程正在侦听套接字上的客户端连接 每次
  • 在桌面应用程序中,类库的连接字符串存储在哪里?我可以在app.config中使用吗?

    我是桌面应用程序开发的新手 目前正在使用分层架构 用户界面 DAL BLL 构建桌面应用程序 在 Web 开发中 我曾经将连接字符串存储在 web config 中 我的类库从那里访问它 请指导我在桌面应用程序中如何以及在何处存储 DAL
  • 具有多重继承的类的 sizeof

    首先 我知道 sizeof 取决于机器和编译器的实现 我使用的是 Windows 8 1 x64 gcc 5 3 0 没有标志传递给编译器 我从大学讲座中得到了以下代码 include
  • 返回指向 std::vector 中的对象的 a

    我有一个关于返回对向量元素的引用的非常基本的问题 有一个向量vec存储类的实例Foo 我想访问这个向量中的一个元素 不想使用向量索引 我应该如何编码该方法getFoo here include
  • 枚举器上的 [[maybe_unused]]

    查看规格 maybe unused http en cppreference com w cpp language attributes 它指出 出现在类 typedef 变量 非静态数据成员 函数 枚举或枚举器的声明中 如果编译器对未使用
  • 简单的文档管理系统和API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • C# 的空条件委托调用线程安全吗? [复制]

    这个问题在这里已经有答案了 这就是我一直以来编写事件引发者的方式 例如属性更改 public event PropertyChangedEventHandler PropertyChanged private void RaisePrope
  • System.diagnostics.process 进程在托管后无法在 IIS 上运行?

    我正在尝试从网络应用程序安装 exe 当我在本地运行应用程序 从 asp 开发服务器 时 它安装正确 但当我托管在 IIS 上时 它不起作用 我在asp net页面的Page load方法上编写了这段代码 想要在客户端计算机上安装Test
  • 如何使用 libpq 获取双精度值?

    The examples http www postgresql org docs 9 3 interactive libpq example htmllibpq 文档中展示了如何通过将整数值转换为主机字节序表示来获取整数值 我很好奇必须做
  • 需要使用 openssl 加密和解密文件的示例 C 代码

    我正在用 Linux C 编写代码 我需要使用以下命令来加密和解密文件 openssl 目前 我使用系统命令 des3 e nosalt k 0123456789012345 in inp file out out file 进行加密 使用
  • 如何分析 VSCode 中函数的性能

    我用 C Golang 编写了一个程序 如何找到占用最高 CPU 周期的函数 目的是提高正在执行的程序的性能 2021 年 10 月 金香儿哈娜 https github com hyangah宣布 tweet https twitter
  • 如何使用简历实现一个“一网打尽”的异常处理程序?

    我想知道我怎样才能写一个抓住他们全部应用程序级别的异常处理程序将为用户提供恢复应用程序流程的选项 如果您正在运行 Windows 窗体应用程序 将处理程序添加到Application ThreadException event
  • 将小数格式化为两位或整数

    对于 10 我想要 10 而不是 10 00 对于 10 11 我想要 10 11 没有代码可以实现吗 即通过指定格式字符串类似于 0 N2 decimal num 10 11M Console WriteLine num ToString
  • 致命错误 C1001:编译器中发生内部错误(编译器文件“msc1.cpp”,第 1325 行)

    当我编译代码时 错误指向以下类 该错误在两行上突出显示 如下所示 tm validFrom tm validUntil struct t SslCertData final struct t Contact TCHAR Organizati

随机推荐

  • SwiftUI 暂停/恢复旋转动画

    到目前为止 我已经看到了以下用于停止动画的技术 但我在这里寻找的是旋转视图停止在当前的角度 而不是返回到 0 struct DemoView View State private var isRotating Bool false var
  • 如果父窗口关闭了,如何关闭子窗口?

    我有一个弹出另一个窗口的网络应用程序 如果该人关闭主浏览器窗口 我也需要关闭子窗口 这可能吗 如果是这样 怎么办 当您调用 window open 时 返回值是所创建的新窗口的句柄 使用此功能 您可以保留已打开的窗口数组 然后在卸载事件处理
  • swift 中的 HTTP 请求不起作用

    我正在尝试了解如何在 Swift 中使用 API 作为一个很好的第一次测试 我想我应该使用 itunes API 并只返回一些搜索结果 我在操场上使用以下代码 我没有收到任何错误 但我的 println 没有输出任何内容 有谁知道出了什么问
  • 插入字符串 c# 6.0 和 Stylecop

    我正在使用 Stylecop 版本 4 7 49 0 有没有人使用过 c 6 0 中最新的插值字符串功能 example var totalUnits GetUnitsGetTotalIssuedShares myId var testSt
  • 如何使用 Borland 数据库引擎和 Delphi 应用程序解决“无法在封闭数据集上执行此操作”? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 该应用程序运行完美 直到我在 Ope
  • Swift 3:tableView 复制从 Firebase 加载的图像

    我正在尝试显示带有图像的用户列表 这是代码 override func tableView tableView UITableView cellForRowAt indexPath IndexPath gt UITableViewCell
  • 从csv中获取关联数组

    我从 url 打开一个 csv 文件 每行有 4 个字段 每个字段都有一个名称 Field1 Field2 Field3 Field4 现在我的脚本将 csv 数据作为一行处理 但我想这样处理 Array 0 gt array field1
  • 詹金斯后期构建步骤和操作 - 有什么区别

    听起来可能是一个非常基本的问题 但我找不到任何文章可以解释为什么 Jenkins 提供构建后步骤和操作 在詹金斯 我确实看到构建后步骤与操作中的选项是不同的 但是 执行顺序是什么 我们什么时候应该使用哪个选项 最佳实践是什么 乍一看 这是
  • 了解网格列属性

    我最近回答了一个关于 CSS 网格的问题 但在我的回答中 我使用了一种有效的风格 但与我认为的标准方式相反 看看下面的代码片段 红细胞具有以下样式 grid column 3 4 grid width 200px display grid
  • 有没有办法在 Firefox 中将 HTML5 Gamepad API 与多个窗口或选项卡一起使用?

    我正在设计一个应用程序 该应用程序使用 HTML5 游戏手柄 API 来利用游戏手柄的输入 我的应用程序可以在 Firefox 和 Chrome 中运行 但是 Firefox 似乎不允许在前一个选项卡访问游戏手柄后第二个窗口或选项卡访问游戏
  • 有效获取elasticsearch索引中的所有文档

    我想从 Elasticsearch 集群中的所有匹配查询中获取所有结果 我不关心结果是否是最新的 也不关心顺序 我只想稳步地继续检查所有结果 然后从头开始 滚动和扫描最适合这种情况吗 拍摄我不需要的快照似乎有点麻烦 我将考虑处理数千万个文档
  • 在 GWT 中使用参数发出 POST 请求

    我正在尝试使用一组参数对给定 URL 执行 POST 请求 我遇到的问题是发出了 POST 请求 但没有传递任何参数 RequestBuilder builder new RequestBuilder RequestBuilder POST
  • 使用 d3.js 的多个地图:更改比例和中心的值

    我正在构建一个 d3 v4 地图可视化它允许用户在许多数据集 json 文件 之间切换两个不同的地区 一个国家的行政单位和较小的行政单位进入其首都 实际上 通过按钮和 jquery 在初始国家级别上从一个数据集到另一个数据集的切换效果很好
  • VBA 捕获“计算工作表 (shift+f9)”和“计算工作簿”事件

    我不知道这是否是微不足道的或实际上很棘手 是否有可能捕获 VBA 中的 计算工作表 shift f9 和 计算工作簿 事件 我想隐藏一些操作几千行的进程 只显示一些关键值 我正在计算分布 数千行 并且只想输出百分位数和一些统计数据 以及图表
  • jquery-ui datepicker 多语言集成

    我正在尝试将不同的 jquery ui datepicker 选项组合到一个函数中 我可以让大部分脚本脱离语言而工作 我拥有所有 i18n 文件 并且我正在使用 select 元素来更改值 但似乎没有任何效果 我做错了什么
  • API 请求错误 - 请求的资源上不存在“Access-Control-Allow-Origin”标头

    我尝试获取 API 请求 但返回此错误 Access to XMLHttpRequest at https api deezer com chart from origin http localhost 3000 已被 CORS 策略阻止
  • 文件夹目录中的子文件夹数量

    我有一个包含两个数据文件的文件夹 txt等 和子文件夹 在Java中 如何获取任何指定目录路径中的子文件夹数量 因此排除数据文件 仅计算子文件夹 我读过有关计算数量的内容 txt文件 但似乎找不到任何有关仅计算子文件夹的信息 我不知道从哪里
  • 为什么 Net::FTP 无法连接到服务器?

    我正在尝试创建一个脚本来使用 Ruby 列出并从 FTP 服务器下载数据 我是 Ruby 新手 所以我寻找了如何使用 Net FTP 的文档 我无法理解为什么这不起作用 require net ftp server ftp server c
  • 在 D3.js 中导入并解析 SVG 文件

    我在其他地方 使用 MS Visio 创建了 SVG 文件 我想将其用作可视化的背景 其中一些定位是由 SVG 图形中项目的放置驱动的 理想情况下 我能够直接操作导入的 SVG 数据 然后使用它通过 D3 在调用文档中创建元素 是否有一种简
  • C 中的双三次插值

    我正在尝试处理c中的双三次图像插值 因此我构建了这个小脚本 1 resize image 函数 void resize image PPMImage source image PPMImage destination image float