双线性插值算法

来源:互联网 发布:放置江湖武功数据排行 编辑:程序博客网 时间:2024/05/22 15:31
#include <opencv.hpp>




using namespace std;
using namespace cv;


bool mlinear_interpolation(Mat &src, Mat &dst)
{
if (!src.data)
{
return false;
}
//源/目的图像每行所占字节数
int nSrcWidthStep = src.step;
int nDstWidthStep = dst.step;
//源和目的几何中心对齐
double scaleX = static_cast<double>(src.cols) / static_cast<double>(dst.cols);
double scaleY = static_cast<double>(src.rows) / static_cast<double>(dst.rows);


for (int i = 0; i < dst.rows; i++) {
//原图中对应的纵坐标
double y = (static_cast<double>(i) + 0.5)*scaleY - 0.5;
//指向目标图像中的行数据
unsigned char *pDstLine = dst.data + i*nDstWidthStep;
for (int j = 0; j < dst.cols; j++) {
//原图中对应的横坐标
double x = (static_cast<double>(j) + 0.5)*scaleX -0.5;
//u和v为y,x的小数部分,并放大2048倍避免浮点运算
int u = static_cast<int>((y - static_cast<int>(y)) * 2048);
int v = static_cast<int>((x - static_cast<int>(x)) * 2048);
//dx和dy分别存储x和y的整数部分
int dx = int(x);
int dy = int(y);
//调整dx,dy和u,v
//dy = std::min(dy, dst.rows - 2);
//dy = std::max(0,dy);
//进行插值计算f(p) = f(0,0)*(1-u)(1-v)+f(1,0)*(1-y)x+f(0,1)*(1-x)y+f(1,1)*xy
for (int k = 0; k < 3; k++) {
pDstLine[j * 3 + k] = (src.data[dy*nSrcWidthStep + dx * 3 + k] * (2048 - u)*(2048 - v)
+ src.data[dy*nSrcWidthStep + (dx + 1) * 3 + k] * (2048 - u)*(v)
+src.data[(dy + 1)*nSrcWidthStep + dx * 3 + k] * (2048 - v)*(u)+
+src.data[(dy + 1)*nSrcWidthStep + (dx + 1) * 3 + k] * (v)*(u)) >> 22;
}
}
}
return true;
}
int main()
{
cv::Mat matSrc, matDst, check;


matSrc = cv::imread("lena.png", 2 | 4);
//自己插值算法的结果
matDst = cv::Mat(cv::Size(1000, 1000), matSrc.type(), cv::Scalar::all(0));
//opecv resize的结果
check = cv::Mat(matDst.size(), matSrc.type(), cv::Scalar::all(0));


mlinear_interpolation(matSrc, matDst);
cv::imwrite("linear_1.jpg", matDst);
cv::resize(matSrc, check, matDst.size(), 0, 0, 1);
cv::imwrite("linear_2.jpg", check);
}

原创粉丝点击