图像内插-最近邻内插法

来源:互联网 发布:2016年淘宝卖什么好做 编辑:程序博客网 时间:2024/05/10 05:07

一、数学原理

     当一幅二维数字图像从源图像N*M被放为(j*N) * (k*M)目标图像是,参照数学斜率计算公式

     必然有: (X1 – Xmin)/(Xmax - Xmin) = (Y1 - Ymin)/(Ymax-Ymin)

     当Xmin 和 Ymin均为从零开始的像素点时,公式可以简化为:X=Y1 (Xmax/Ymax)

     对于任意一幅源图像来说,假设放大后目标图像的宽为Dw高为Dh,任意目标像素点(Dx, Dy)

     在源图像上的位置为:

      Sx= Dx * (Sh/Dh) // row

      Sy= Dy * (Sw/Dw) // column

     最简单的图像缩放算法就是最近邻插值。顾名思义,就是将目标图像各点的像素值设为源图像中与其最近的点。假设源图像的宽度和高度分别为w0和h0, 缩放后的目标图像的宽度和高度分别为w1和h1, 那么比例就是float fw = float(w0)/w1; float fh = float(h0)/h1; 对于目标图像中的(x,y)点坐标对应着源图像中的(x0, y0)点。其中:x0 = int(x*fw), y0 = int(y*fh)。

二、代码实现

int _tmain(int argc, _TCHAR* argv[]){//导入图像Mat src = imread("1.jpg");//显示imshow("src",src);//创建矩阵Mat dst = Mat::zeros(Size(800,1000),CV_8UC3);//放大的比例double fRows = 1000 / (float)src.rows;double fCols = 800 / (float)src.cols;int primaryX = 0;int primaryY = 0;//近邻内插法for (int i =0; i != dst.rows; ++ i){for (int j = 0; j != dst.cols; ++ j){primaryX = cvRound(i / (double)fRows); primaryY = cvRound(j / (double)fCols);if(primaryX<src.rows&&primaryX>= 0&&primaryY>= 0&& primaryY<src.cols){dst.at<cv::Vec3b>(i,j)[0] = src.at<cv::Vec3b>(primaryX,primaryY)[0];dst.at<cv::Vec3b>(i,j)[1] = src.at<cv::Vec3b>(primaryX,primaryY)[1];dst.at<cv::Vec3b>(i,j)[2] = src.at<cv::Vec3b>(primaryX,primaryY)[2];}}}imshow("dst",dst);waitKey(0);return 0;}

三、结果显示与分析

得到的结果如下图所示:


    临近点插值算法会产生锯齿效果, 不是一个很好的图像放缩算法,临近点插值算法不改变源像素点到目标像素点的值,只是最简单的位置匹配而已,相比之下,双线性内插值算法和双立方插值算法效果更好,但是计算量更大,临近点插值是计算量最小的防缩算法。


原创粉丝点击