OpenCV中resize函数五种插值算法的实现过程

本文介绍了OpenCV 2.4.7版本中resize函数的五种插值算法,包括最近邻、双线性、双三次、基于像素区域关系和兰索斯插值的实现过程。内容通过for循环来详细解释每种算法的细节,部分代码来源于cv::resize的源码。
摘要由CSDN通过智能技术生成

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

最新版OpenCV2.4.7中,cv::resize函数有五种插值算法:最近邻、双线性、双三次、基于像素区域关系、兰索斯插值。下面用for循环代替cv::resize函数来说明其详细的插值实现过程,其中部分代码摘自于cv::resize函数中的源代码。

每种插值算法的前部分代码是相同的,如下:

 cv::Mat matSrc, matDst1, matDst2; matSrc = cv::imread("lena.jpg", 2 | 4); matDst1 = cv::Mat(cv::Size(800, 1000), matSrc.type(), cv::Scalar::all(0)); matDst2 = cv::Mat(matDst1.size(), matSrc.type(), cv::Scalar::all(0)); double scale_x = (double)matSrc.cols / matDst1.cols; double scale_y = (double)matSrc.rows / matDst1.rows;

1、最近邻:公式,

                  

 for (int i = 0; i < matDst1.cols; ++i) {  int sx = cvFloor(i * scale_x);  sx = std::min(sx, matSrc.cols - 1);  for (int j = 0; j < matDst1.rows; ++j)  {   int sy = cvFloor(j * scale_y);   sy = std::min(sy, matSrc.rows - 1);   matDst1.at<cv::Vec3b>(j, i) = matSrc.at<cv::Vec3b>(sy, sx);  } } cv::imwrite("nearest_1.jpg", matDst1); cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 0); cv::imwrite("nearest_2.jpg", matDst2);

2、双线性:由相邻的四像素(2*2)计算得出,公式,


 uchar* dataDst = matDst1.data; int stepDst = matDst1.step; uchar* dataSrc = matSrc.data; int stepSrc = matSrc.step; int iWidthSrc = matSrc.cols; int iHiehgtSrc = matSrc.rows; for (int j = 0; j < matDst1.rows; ++j) {  float fy = (float)((j + 0.5) * scale_y - 0.5);  int sy = cvFloor(fy);  fy -= sy;  sy = std::min(sy, iHiehgtSrc - 2);  sy = std::max(0, sy);  short cbufy[2];  cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);  cbufy[1] = 2048 - cbufy[0];  for (int i = 0; i < matDst1.cols; ++i)  {   float fx = (float)((i + 0.5) * scale_x - 0.5);   int sx = cvFloor(fx);   fx -= sx;   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);   cbufx[1] = 2048 - cbufx[0];   for (int k = 0; k < matSrc.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;   }  } } cv::imwrite("linear_1.jpg", matDst1); cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1); cv::imwrite("linear_2.jpg", matDst2);

3、双三次:由相邻的4*4像素计算得出,公式类似于双线性

 int iscale_x = cv::saturate_cast<int>(scale_x); int iscale_y = cv::saturate_cast<int>(scale_y); for (int j = 0; j < matDst1.rows; ++j) {  float fy = (float)((j + 0.5) * scale_y - 0.5);  int sy = cvFloor(fy);  fy -= sy;  sy = std::min(sy, matSrc.rows - 3);  sy = std::max(1, sy);  const float A = -0.75f;  float coeffsY[4];  coeffsY[0] = ((A*(fy + 1) - 5*A)*(fy + 1) + 8*A)*(fy + 1) - 4*A;  coeffsY[1] = ((A + 2)*fy - (A + 3))*fy*fy + 1;  coeffsY[2] = ((A + 2)*(1 - fy) - (A + 3))*(1 - fy)*(1 - fy) + 1;  coeffsY[3] = 1.f - coeffsY[0] - coeffsY[1] - coeffsY[2];  short cbufY[4];  cbufY[0] = cv::saturate_cast<short>(coeffsY[0] * 2048);  cbufY[1] = cv::saturate_cast<short>(coeffsY[1] * 2048);  cbufY[2] = cv::saturate_cast<
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值