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


Posted in Python onJune 05, 2021

最新版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、最近邻:公式,

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

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)计算得出,公式,

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

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<short>(coeffsY[2] * 2048);
		cbufY[3] = cv::saturate_cast<short>(coeffsY[3] * 2048);
 
		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 < 1) {
				fx = 0, sx = 1;
			}
			if (sx >= matSrc.cols - 3) {
				fx = 0, sx = matSrc.cols - 3;
			}
 
			float coeffsX[4];
			coeffsX[0] = ((A*(fx + 1) - 5*A)*(fx + 1) + 8*A)*(fx + 1) - 4*A;
			coeffsX[1] = ((A + 2)*fx - (A + 3))*fx*fx + 1;
			coeffsX[2] = ((A + 2)*(1 - fx) - (A + 3))*(1 - fx)*(1 - fx) + 1;
			coeffsX[3] = 1.f - coeffsX[0] - coeffsX[1] - coeffsX[2];
 
			short cbufX[4];
			cbufX[0] = cv::saturate_cast<short>(coeffsX[0] * 2048);
			cbufX[1] = cv::saturate_cast<short>(coeffsX[1] * 2048);
			cbufX[2] = cv::saturate_cast<short>(coeffsX[2] * 2048);
			cbufX[3] = cv::saturate_cast<short>(coeffsX[3] * 2048);
 
			for (int k = 0; k < matSrc.channels(); ++k)
			{
				matDst1.at<cv::Vec3b>(j, i)[k] = abs((matSrc.at<cv::Vec3b>(sy-1, sx-1)[k] * cbufX[0] * cbufY[0] + matSrc.at<cv::Vec3b>(sy, sx-1)[k] * cbufX[0] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy+1, sx-1)[k] * cbufX[0] * cbufY[2] + matSrc.at<cv::Vec3b>(sy+2, sx-1)[k] * cbufX[0] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy-1, sx)[k] * cbufX[1] * cbufY[0] + matSrc.at<cv::Vec3b>(sy, sx)[k] * cbufX[1] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy+1, sx)[k] * cbufX[1] * cbufY[2] + matSrc.at<cv::Vec3b>(sy+2, sx)[k] * cbufX[1] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy-1, sx+1)[k] * cbufX[2] * cbufY[0] + matSrc.at<cv::Vec3b>(sy, sx+1)[k] * cbufX[2] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy+1, sx+1)[k] * cbufX[2] * cbufY[2] + matSrc.at<cv::Vec3b>(sy+2, sx+1)[k] * cbufX[2] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy-1, sx+2)[k] * cbufX[3] * cbufY[0] + matSrc.at<cv::Vec3b>(sy, sx+2)[k] * cbufX[3] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy+1, sx+2)[k] * cbufX[3] * cbufY[2] + matSrc.at<cv::Vec3b>(sy+2, sx+2)[k] * cbufX[3] * cbufY[3] ) >> 22);
			}
		}
	}
	cv::imwrite("cubic_1.jpg", matDst1);
 
	cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 2);
	cv::imwrite("cubic_2.jpg", matDst2);

4、基于像素区域关系:共分三种情况,图像放大时类似于双线性插值,图像缩小(x轴、y轴同时缩小)又分两种情况,此情况下可以避免波纹出现。

#ifdef _MSC_VER
	cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 3);
	cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_2.jpg", matDst2);
#else
	cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 3);
	cv::imwrite("area_2.jpg", matDst2);
#endif
 
	fprintf(stdout, "==== start area ====\n");
	double inv_scale_x = 1. / scale_x;
	double inv_scale_y = 1. / scale_y;
	int iscale_x = cv::saturate_cast<int>(scale_x);
	int iscale_y = cv::saturate_cast<int>(scale_y);
	bool is_area_fast = std::abs(scale_x - iscale_x) < DBL_EPSILON && std::abs(scale_y - iscale_y) < DBL_EPSILON;
 
	if (scale_x >= 1 && scale_y >= 1)  { // zoom out
		if (is_area_fast)  { // integer multiples
			for (int j = 0; j < matDst1.rows; ++j) {
				int sy = std::min(cvFloor(j * scale_y), matSrc.rows - 1);
 
				for (int i = 0; i < matDst1.cols; ++i) {
					int sx = std::min(cvFloor(i * scale_x), matSrc.cols -1);
 
					matDst1.at<cv::Vec3b>(j, i) = matSrc.at<cv::Vec3b>(sy, sx);
				}
			}
#ifdef _MSC_VER
			cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_1.jpg", matDst1);
#else
			cv::imwrite("area_1.jpg", matDst1);
#endif
			return 0;
		}
 
		for (int j = 0; j < matDst1.rows; ++j) {
			double fsy1 = j * scale_y;
			double fsy2 = fsy1 + scale_y;
			double cellHeight = cv::min(scale_y, matSrc.rows - fsy1);
 
			int sy1 = cvCeil(fsy1), sy2 = cvFloor(fsy2);
 
			sy2 = std::min(sy2, matSrc.rows - 2);
			sy1 = std::min(sy1, sy2);
 
			float cbufy[2];
			cbufy[0] = (float)((sy1 - fsy1) / cellHeight);
			cbufy[1] = (float)(std::min(std::min(fsy2 - sy2, 1.), cellHeight) / cellHeight);
 
			for (int i = 0; i < matDst1.cols; ++i) {
				double fsx1 = i * scale_x;
				double fsx2 = fsx1 + scale_x;
				double cellWidth = std::min(scale_x, matSrc.cols - fsx1);
 
				int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2);
 
				sx2 = std::min(sx2, matSrc.cols - 2);
				sx1 = std::min(sx1, sx2);
 
				float cbufx[2];
				cbufx[0] = (float)((sx1 - fsx1) / cellWidth);
				cbufx[1] = (float)(std::min(std::min(fsx2 - sx2, 1.), cellWidth) / cellWidth);
 
				for (int k = 0; k < matSrc.channels(); ++k) {
					matDst1.at<cv::Vec3b>(j, i)[k] = (uchar)(matSrc.at<cv::Vec3b>(sy1, sx1)[k] * cbufx[0] * cbufy[0] +
						matSrc.at<cv::Vec3b>(sy1 + 1, sx1)[k] * cbufx[0] * cbufy[1] +
						matSrc.at<cv::Vec3b>(sy1, sx1 + 1)[k] * cbufx[1] * cbufy[0] +
						matSrc.at<cv::Vec3b>(sy1 + 1, sx1 + 1)[k] * cbufx[1] * cbufy[1]);
				}
			}
		}
#ifdef _MSC_VER
		cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_1.jpg", matDst1);
#else
		cv::imwrite("area_1.jpg", matDst1);
#endif
 
		return 0;
	}
 
	//zoom in,it is emulated using some variant of bilinear interpolation
	for (int j = 0; j < matDst1.rows; ++j) {
		int  sy = cvFloor(j * scale_y);
		float fy = (float)((j + 1) - (sy + 1) * inv_scale_y);
		fy = fy <= 0 ? 0.f : fy - cvFloor(fy);
		sy = std::min(sy, matSrc.rows - 2);
 
		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) {
			int sx = cvFloor(i * scale_x);
			float fx = (float)((i + 1) - (sx + 1) * inv_scale_x);
			fx = fx < 0 ? 0.f : fx - cvFloor(fx);
 
			if (sx < 0) {
				fx = 0, sx = 0;
			}
 
			if (sx >= matSrc.cols - 1) {
				fx = 0, sx = matSrc.cols - 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) {
				matDst1.at<cv::Vec3b>(j, i)[k] = (matSrc.at<cv::Vec3b>(sy, sx)[k] * cbufx[0] * cbufy[0] +
					matSrc.at<cv::Vec3b>(sy + 1, sx)[k] * cbufx[0] * cbufy[1] +
					matSrc.at<cv::Vec3b>(sy, sx + 1)[k] * cbufx[1] * cbufy[0] +
					matSrc.at<cv::Vec3b>(sy + 1, sx + 1)[k] * cbufx[1] * cbufy[1]) >> 22;
			}
		}
	}
	fprintf(stdout, "==== end area ====\n");
 
#ifdef _MSC_VER
	cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_1.jpg", matDst1);
#else
	cv::imwrite("area_1.jpg", matDst1);
#endif

注:以上基于area进行图像缩小的代码有问题,具体实现代码可以参考https://github.com/fengbingchun/OpenCV_Test/blob/master/src/fbc_cv/include/resize.hpp,用法如下:

fbc::Mat3BGR src(matSrc.rows, matSrc.cols, matSrc.data);
fbc::Mat3BGR dst(matDst1.rows, matDst1.cols, matDst1.data);
fbc::resize(src, dst, 3);

5、兰索斯插值:由相邻的8*8像素计算得出,公式类似于双线性

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 - 5);
		sy = std::max(3, sy);
 
		const double s45 = 0.70710678118654752440084436210485;
		const double cs[][2] = {{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}};
		float coeffsY[8];
 
		if (fy < FLT_EPSILON) {
			for (int t = 0; t < 8; t++)
				coeffsY[t] = 0;
			coeffsY[3] = 1;
		} else {
			float sum = 0;
			double y0 = -(fy + 3) * CV_PI * 0.25, s0 = sin(y0), c0 = cos(y0);
 
			for (int t = 0; t < 8; ++t)
			{
				double dy = -(fy + 3 -t) * CV_PI * 0.25;
				coeffsY[t] = (float)((cs[t][0] * s0 + cs[t][1] * c0) / (dy * dy));
				sum += coeffsY[t];
			}
 
			sum = 1.f / sum;
			for (int t = 0; t < 8; ++t)
				coeffsY[t] *= sum;
		}
 
		short cbufY[8];
		cbufY[0] = cv::saturate_cast<short>(coeffsY[0] * 2048);
		cbufY[1] = cv::saturate_cast<short>(coeffsY[1] * 2048);
		cbufY[2] = cv::saturate_cast<short>(coeffsY[2] * 2048);
		cbufY[3] = cv::saturate_cast<short>(coeffsY[3] * 2048);
		cbufY[4] = cv::saturate_cast<short>(coeffsY[4] * 2048);
		cbufY[5] = cv::saturate_cast<short>(coeffsY[5] * 2048);
		cbufY[6] = cv::saturate_cast<short>(coeffsY[6] * 2048);
		cbufY[7] = cv::saturate_cast<short>(coeffsY[7] * 2048);
 
		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 < 3) {
				fx = 0, sx = 3;
			}
			if (sx >= matSrc.cols - 5) {
				fx = 0, sx = matSrc.cols - 5;
			}
 
			float coeffsX[8];
 
			if (fx < FLT_EPSILON) {
				for ( int t = 0; t < 8; t++ )
					coeffsX[t] = 0;
				coeffsX[3] = 1;
			} else {
				float sum = 0;
				double x0 = -(fx + 3) * CV_PI * 0.25, s0 = sin(x0), c0 = cos(x0);
 
				for (int t = 0; t < 8; ++t)
				{
					double dx = -(fx + 3 -t) * CV_PI * 0.25;
					coeffsX[t] = (float)((cs[t][0] * s0 + cs[t][1] * c0) / (dx * dx));
					sum += coeffsX[t];
				}
 
				sum = 1.f / sum;
				for (int t = 0; t < 8; ++t)
					coeffsX[t] *= sum;
			}
 
			short cbufX[8];
			cbufX[0] = cv::saturate_cast<short>(coeffsX[0] * 2048);
			cbufX[1] = cv::saturate_cast<short>(coeffsX[1] * 2048);
			cbufX[2] = cv::saturate_cast<short>(coeffsX[2] * 2048);
			cbufX[3] = cv::saturate_cast<short>(coeffsX[3] * 2048);
			cbufX[4] = cv::saturate_cast<short>(coeffsX[4] * 2048);
			cbufX[5] = cv::saturate_cast<short>(coeffsX[5] * 2048);
			cbufX[6] = cv::saturate_cast<short>(coeffsX[6] * 2048);
			cbufX[7] = cv::saturate_cast<short>(coeffsX[7] * 2048);
 
			for (int k = 0; k < matSrc.channels(); ++k)
			{
				matDst1.at<cv::Vec3b>(j, i)[k] = abs((matSrc.at<cv::Vec3b>(sy-3, sx-3)[k] * cbufX[0] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx-3)[k] * cbufX[0] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx-3)[k] * cbufX[0] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx-3)[k] * cbufX[0] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx-3)[k] * cbufX[0] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx-3)[k] * cbufX[0] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx-3)[k] * cbufX[0] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx-3)[k] * cbufX[0] * cbufY[7] +
 
					matSrc.at<cv::Vec3b>(sy-3, sx-2)[k] * cbufX[1] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx-2)[k] * cbufX[1] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx-2)[k] * cbufX[1] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx-2)[k] * cbufX[1] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx-2)[k] * cbufX[1] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx-2)[k] * cbufX[1] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx-2)[k] * cbufX[1] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx-2)[k] * cbufX[1] * cbufY[7] +
 
					matSrc.at<cv::Vec3b>(sy-3, sx-1)[k] * cbufX[2] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx-1)[k] * cbufX[2] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx-1)[k] * cbufX[2] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx-1)[k] * cbufX[2] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx-1)[k] * cbufX[2] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx-1)[k] * cbufX[2] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx-1)[k] * cbufX[2] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx-1)[k] * cbufX[2] * cbufY[7] +
 
					matSrc.at<cv::Vec3b>(sy-3, sx)[k] * cbufX[3] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx)[k] * cbufX[3] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx)[k] * cbufX[3] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx)[k] * cbufX[3] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx)[k] * cbufX[3] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx)[k] * cbufX[3] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx)[k] * cbufX[3] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx)[k] * cbufX[3] * cbufY[7] +
 
					matSrc.at<cv::Vec3b>(sy-3, sx+1)[k] * cbufX[4] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx+1)[k] * cbufX[4] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx+1)[k] * cbufX[4] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx+1)[k] * cbufX[4] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx+1)[k] * cbufX[4] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx+1)[k] * cbufX[4] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx+1)[k] * cbufX[4] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx+1)[k] * cbufX[4] * cbufY[7] +
 
					matSrc.at<cv::Vec3b>(sy-3, sx+2)[k] * cbufX[5] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx+2)[k] * cbufX[5] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx+2)[k] * cbufX[5] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx+2)[k] * cbufX[5] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx+2)[k] * cbufX[5] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx+2)[k] * cbufX[5] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx+2)[k] * cbufX[5] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx+2)[k] * cbufX[5] * cbufY[7] +
 
					matSrc.at<cv::Vec3b>(sy-3, sx+3)[k] * cbufX[6] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx+3)[k] * cbufX[6] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx+3)[k] * cbufX[6] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx+3)[k] * cbufX[6] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx+3)[k] * cbufX[6] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx+3)[k] * cbufX[6] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx+3)[k] * cbufX[6] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx+3)[k] * cbufX[6] * cbufY[7] +
 
					matSrc.at<cv::Vec3b>(sy-3, sx+4)[k] * cbufX[7] * cbufY[0] + matSrc.at<cv::Vec3b>(sy-2, sx+4)[k] * cbufX[7] * cbufY[1] +
					matSrc.at<cv::Vec3b>(sy-1, sx+4)[k] * cbufX[7] * cbufY[2] + matSrc.at<cv::Vec3b>(sy, sx+4)[k] * cbufX[7] * cbufY[3] +
					matSrc.at<cv::Vec3b>(sy+1, sx+4)[k] * cbufX[7] * cbufY[4] + matSrc.at<cv::Vec3b>(sy+2, sx+4)[k] * cbufX[7] * cbufY[5] +
					matSrc.at<cv::Vec3b>(sy+3, sx+4)[k] * cbufX[7] * cbufY[6] + matSrc.at<cv::Vec3b>(sy+4, sx+4)[k] * cbufX[7] * cbufY[7] ) >> 22);// 4194304
			}
		}
	}
	cv::imwrite("Lanczos_1.jpg", matDst1);
 
	cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 4);
	cv::imwrite("Lanczos_2.jpg", matDst2);

以上代码的实现结果与cv::resize函数相同,但是执行效率非常低,只是为了详细说明插值过程。OpenCV中默认采用C++ Concurrency进行优化加速,你也可以采用TBB、OpenMP等进行优化加速。

GitHubhttps://github.com/fengbingchun/OpenCV_Test/blob/master/demo/OpenCV_Test/test_opencv_funset.cpp

到此这篇关于OpenCV中resize函数插值算法的实现过程(五种)的文章就介绍到这了,更多相关OpenCV resize插值内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python进程类subprocess的一些操作方法例子
Nov 22 Python
python实现n个数中选出m个数的方法
Nov 13 Python
python远程连接MySQL数据库
Apr 19 Python
搭建python django虚拟环境完整步骤详解
Jul 08 Python
Python 保持登录状态进行接口测试的方法示例
Aug 06 Python
python tkinter图形界面代码统计工具(更新)
Sep 18 Python
Python如何使用函数做字典的值
Nov 30 Python
python 实现二维列表转置
Dec 02 Python
python 在threading中如何处理主进程和子线程的关系
Apr 25 Python
Python使用jpype模块调用jar包过程解析
Jul 29 Python
Python对excel的基本操作方法
Feb 18 Python
Python可视化学习之seaborn绘制矩阵图详解
Feb 24 Python
OpenCV全景图像拼接的实现示例
opencv 分类白天与夜景视频的方法
python如何利用traceback获取详细的异常信息
Jun 05 #Python
Python异常类型以及处理方法汇总
Jun 05 #Python
Python OpenCV 彩色与灰度图像的转换实现
Python深度学习之实现卷积神经网络
python opencv通过4坐标剪裁图片
Jun 05 #Python
You might like
第三节--定义一个类
2006/11/16 PHP
PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法
2014/05/04 PHP
PHP 使用memcached简单示例分享
2015/03/05 PHP
php实现粘贴截图并完成上传功能
2015/05/17 PHP
php curl操作API接口类完整示例
2019/05/21 PHP
让人期待的2011年度最佳 jQuery 插件分享
2012/03/16 Javascript
node.js解决获取图片真实文件类型的问题
2014/12/20 Javascript
jQuery控制div实现随滚动条滚动效果
2016/06/07 Javascript
jQuery简单实现中间浮窗效果
2016/09/04 Javascript
关于在vue-cli中使用微信自动登录和分享的实例
2017/06/22 Javascript
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
基于Bootstrap table组件实现多层表头的实例代码
2017/09/07 Javascript
基于js 各种排序方法和sort方法的区别(详解)
2018/01/03 Javascript
axios的拦截请求与响应方法
2018/08/11 Javascript
小程序hover-class点击态效果实现
2019/02/26 Javascript
Webpack4 使用Babel处理ES6语法的方法示例
2019/03/07 Javascript
vue项目前端错误收集之sentry教程详解
2019/05/27 Javascript
[00:32]2018DOTA2亚洲邀请赛VGJ.T出场
2018/04/03 DOTA
[02:29]大剑、皮鞭、女装,这届DOTA2勇士令状里都有
2020/07/17 DOTA
Python中的字典与成员运算符初步探究
2015/10/13 Python
python编写简单爬虫资料汇总
2016/03/22 Python
Django的信号机制详解
2017/05/05 Python
使用pyecharts在jupyter notebook上绘图
2020/04/23 Python
Python图片转换成矩阵,矩阵数据转换成图片的实例
2018/07/02 Python
对python中Librosa的mfcc步骤详解
2019/01/09 Python
Python实现名片管理系统
2020/02/14 Python
Python 序列化和反序列化库 MarshMallow 的用法实例代码
2020/02/25 Python
python使用for...else跳出双层嵌套循环的方法实例
2020/05/17 Python
matplotlib.pyplot.plot()参数使用详解
2020/07/28 Python
html5适合移动应用开发的12大特性
2014/03/19 HTML / CSS
美国在线奢侈品寄售商店:Luxury Garage Sale
2018/08/19 全球购物
linux面试题参考答案(10)
2016/10/26 面试题
自我评价200字分享
2013/12/17 职场文书
护士长竞聘演讲稿
2014/04/30 职场文书
故宫的导游词
2015/01/31 职场文书
优秀范文:读《红岩》有感3篇
2019/10/14 职场文书