常见图像插值方法比较(opencv)

本文介绍了OpenCV中两种常用的图像插值方法——Nearest差值和Bi-linear双线性插值。Nearest插值采用最近邻点匹配,而Bi-linear插值通过四邻点加权平均减少误差。文章提供了实现原理、代码示例,并讨论了插值过程中确保中心点对齐的重要性。
摘要由CSDN通过智能技术生成

图像插值方法比较

本文介绍几种经典插值的原理,代码过程以及对性能作出比较。

简单说来,在对原始图像进行缩放、旋转变换的时候,因为在目标图像中像素分布发生了变换,所以需根据一定的映射规则建立从原始图像到目标图像的转换。

Nearest 差值

顾名思义,最近邻插值就是从原始目标中找到最匹配的位置。不多说,直接上代码。

static int nearestArea(Mat &src, float scale_x, float scale_y, char *argc)
{
    Mat dstMat1 = Mat(src.rows * scale_y, src.cols * scale_x, src.type());
    typedef BOOST_TYPEOF(*src.data) ElementType;
    int WidthSrc = src.cols;
    int HeightSrc = src.rows;
    int WidthDst = dstMat1.cols;
    int HeightDst = dstMat1.rows;
    int chal_num = src.channels();
    char name[128];
    char **ful_name = &argc;
    char *prefix = nullptr;
    char *subfix = nullptr;
    prefix = strsep(ful_name, ".");
    subfix = strsep(ful_name, ".");
    if (!prefix || !subfix) {
        printf("Get subfix from file name failed\n");
        return -1;
    }
    snprintf(name, sizeof(name), "%s_%.2f_%.2f_Nearest.%s", prefix, scale_x, scale_y, subfix);

    clock_t start = clock();

    for (int w = 0; w < WidthDst; w++) {
        float rx = ((float)w + 0.5) / scale_x - 0.5;
        int sx = cvFloor(rx);
        sx = MIN(sx, WidthSrc - 2);
        sx = MAX(0, sx);

        short rx_sh_buf[2];
        rx_sh_buf[0] = (short)((1.f - rx) * 2048);
        rx_sh_buf[1] = 2048 - rx_sh_buf[0];

        for (int h = 0; h < HeightDst; h++) {
            float ry = ((float)h + 0.5) / scale_y - 0.5;
            int sy = cvFloor(ry);
            sy = MIN(sy, HeightSrc - 2);
            sy = MAX(0, sy);

            switch (chal_num) {
            case 1:
                dstMat1.at<ElementType>(h, w) =
                    src.at<ElementType>(sy, sx);
                break;
            case 2:
                for (int m = 0; m < 2; m++) {
                    dstMat1.at<Vec<ElementType, 2>>(h, w)[m] =
                        src.at<Vec<ElementType, 2>>(sy, sx)[m];
                }
                break;
            case 3:
                for (int m = 0; m < 3; m++) {
                    dstMat1.at<Vec<ElementType, 3>>(h, w)[m] =
                        src.at<Vec<ElementType, 3>>(sy, sx)[m];
                }
                break;
            default:
                break;
            }
        }
    }
    clock_t end = clock();
    printf("Interpolation time: %f\n", (float)(end - start) / CLOCKS_PER_SEC * 1000);
    if (dstMat1.data) {
        imwrite(name, dstMat1);
    }

    return 1;
}

Bi-linear 双线性插值

双线性插值的思路就是利用映射到原始图像匹配点像素临近四个点对目标图像的像素点进行求解。原因在于反向求解匹配像素点的时候,会产生小数,舍入之后会产生较大误差。计算思路可以用下图表示:
这里写图片描述
X方向
f(R1)xx1x2xf(Q21

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值