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;
}