最邻近插值法原理分析及c++实现

最邻近插值法原理分析及c++实现


最邻近插值法 : 其核心思想是选取离目标点最近的点作为待插入的新值点

公式推导过程
请添加图片描述

上述图片中像素点的说明:
Q11,Q21,Q12,Q22 分别为四个真实存在的像素点
P 为最邻近插值法待插值点

因为P点与Q12很接近,所以P ( i , j )=Q12 ( x , y+1 )

用opencv进行图像处理时,根据下面公式来计算目标像素值在源图像中所处的位置:
(src:原图像 dst:目的图像)

srcX =dstX * ( srcWidth / dstWidth)
srcY =dstY * ( srcHeight / dstHeight)

以原图尺寸3x3为例,来计算扩展后5*5图像的像素值:在这里插入图片描述
目标像素(1,1)所对应的原像素的像素值为:
srcX =1 * ( 3 / 5) = 0.6 ~ 1(四舍五入约等于1)
srcY =1 * ( 3 / 5) = 0.6 ~ 1(四舍五入约等于1)
目标像素(1,1)= 原图像(1,1),所以目标像素(1,1)位置所对应的像素值为1

目标像素(1,5)所对应的原像素的像素值为:
srcX =1 * ( 3 / 5) = 0.6 ~ 1(四舍五入约等于1)
srcY =5 * ( 3 / 5) = 3
目标像素(1,5)= 原图像(1,3),所以目标像素(1,5)位置所对应的像素值为1

从而算出5 * 5整幅图像的所对应的像素值

示例代码

#include "stdafx.h"
#include "iostream"
#include "opencv2/opencv.hpp"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"

using namespace std;
using namespace cv;    

#pragma comment(lib,"./opencv_world300d.lib")

void Linera(cv::Mat& src, cv::Mat& dst, double sx, double sy)
{
	int dst_rows = round(src.rows * sy);//把一个小数四舍五入 height
	int dst_cols = round(src.cols * sx); //width

	dst = cv::Mat(dst_rows, dst_cols, src.type());
	for (int i = 0; i < dst.rows; i++)
	{
		double index_i = i  / sy ;
		//防止越界
		if (index_i < 0) index_i = 0;
		if (index_i >= src.rows - 1) index_i = src.rows - 1;

		int srcrows = round(index_i);

		for (int j = 0; j < dst.cols; j++)
		{
			double index_j = j / sx ;
			//防止越界
			if (index_j < 0) index_j = 0;
			if (index_j >= src.cols - 1) index_j = src.cols - 1;

			int srccols = round(index_j);

			if (src.channels() == 1)
			{
				//灰度图像
				dst.at<uchar>(i, j) = src.at<uchar>(srcrows, srccols);
			}
			else
			{
				//彩色图像
				dst.at<cv::Vec3b>(i, j)[0] = src.at<cv::Vec3b>(srcrows, srccols)[0];
				dst.at<cv::Vec3b>(i, j)[1] = src.at<cv::Vec3b>(srcrows, srccols)[1];
				dst.at<cv::Vec3b>(i, j)[2] = src.at<cv::Vec3b>(srcrows, srccols)[2];
			}
		}
	}

}

int main()
{
	const char* imageName = "C:\\Users\\Public\\Pictures\\Sample Pictures\\flower.jpg";
	Mat srcImage = imread(imageName);
	if (srcImage.empty())
	{
		fprintf(stderr, "Can not load image %s\n", srcImage);
		return -1;
	}
	int iSrcWidth = 1024, iSrcHeight = 768;
	int iDstWidth = 4000, iDstHeight = 3000;
	Mat dstImage;
	double sx = static_cast<double>(1.0 / (1.0*iSrcWidth / iDstWidth));
	double sy = static_cast<double>(1.0 / (1.0*iSrcHeight / iDstHeight));
	Linera(srcImage, dstImage, sx, sy);
	imwrite("D:\\123.jpg", dstImage);
	system("pause");
	return 0;
}

示例图像及结果展示

示例图像
请添加图片描述
结果图像
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值