Opencv 图像尺寸调整双线性插值算法

Opencv 图像尺寸调整双线性插值算法

双线性内插
1、是由原图像位置在她附近的2*2区域4个邻近像素的值通过加权平均计算得到。
2、低通滤波性质,使高频分量受损,图像轮廓可能会有一点模糊

这里写图片描述

#include<iostream>
#include<stdio.h>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
using namespace std;
//自己实现

void resize1(Mat &src, Mat &des, double scale_x, double scale_y)
{
    //最近邻插值
    for (int i = 0; i < des.cols;i++)
    {
        int sx = cvFloor(i*scale_x);
        sx = min(sx, src.cols - 1);//防止超出原图像的边界
        for (int j = 0; j < des.rows; j++)
        {
            int sy = cvFloor(j*scale_y);
            sy = min(sy, src.rows - 1);
            des.at<Vec3b>(j, i) = src.at<Vec3b>(sy, sx);
        }
    }
}
void resize2(Mat &src, Mat &des, double scale_x, double scale_y)
{
    //双线性插值
    uchar* dataDst = des.data;
    int stepDst = des.step;//1024*3=3072
    uchar* dataSrc = src.data;
    int stepSrc = src.step;//1536
    int iWidthSrc = src.cols;//512
    int iHiehgtSrc = src.rows;//512
    for (int j = 0; j < des.rows; ++j)
    {
        float fy = (float)((j + 0.5) * scale_y - 0.5);//-0.25
        int sy = cvFloor(fy);//-1
        fy -= sy;//0.75
        sy = std::min(sy, iHiehgtSrc - 2);//-1
        sy = std::max(0, sy);//0

        short cbufy[2];
        cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);//512
        cbufy[1] = 2048 - cbufy[0];//1536

        for (int i = 0; i < des.cols; ++i)
        {
            float fx = (float)((i + 0.5) * scale_x - 0.5);//-0.25
            int sx = cvFloor(fx);//-1
            fx -= sx;//0.75

            if (sx < 0) {
                fx = 0, sx = 0;
            }
            if (sx >= iWidthSrc - 1) {
                fx = 0, sx = iWidthSrc - 2;
            }
            //这里不大懂
            short cbufx[2];
            cbufx[0] = cv::saturate_cast<short>((1.f - fx) * 2048);//2048
            cbufx[1] = 2048 - cbufx[0];//0

            for (int k = 0; k < src.channels(); ++k)
            {
                *(dataDst + j*stepDst + 3 * i + k) = 
                    (*(dataSrc + sy*stepSrc + 3 * sx + k) * cbufx[0] * cbufy[0] +
                    *(dataSrc + (sy + 1)*stepSrc + 3 * sx + k) * cbufx[0] * cbufy[1] +
                    *(dataSrc + sy*stepSrc + 3 * (sx + 1) + k) * cbufx[1] * cbufy[0] +
                    *(dataSrc + (sy + 1)*stepSrc + 3 * (sx + 1) + k) * cbufx[1] * cbufy[1]) >> 22;
            }
        }
    }
}
int main(int argc, char *argv)
{
    //调整对比度和亮度
    Mat matSrc, matDst1, matDst2;
    matSrc = imread("lena.jpg");
    matDst1 = Mat(Size(1024, 1024), matSrc.type());
    matDst2 = Mat(matDst1.size(), matSrc.type());
    double scale_x = (double)matSrc.cols / matDst2.cols;
    double scale_y = (double)matSrc.rows / matDst2.rows;

    //resize1(matSrc, matDst2, scale_x, scale_y);
    resize2(matSrc, matDst2, scale_x, scale_y);

    namedWindow("matSrc");
    namedWindow("matDst2");
    imshow("matSrc", matSrc);
    imshow("matDst2", matDst2);
    waitKey(0);

    return 0;
}
发布了38 篇原创文章 · 获赞 29 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/ruotianxia/article/details/79851009