C++实现OPENCV resize函数 最邻近插值 记录踩坑过程

事情是这样的,因硬性需求,要求不使用resize函数接口,用C++实现这个函数类型,并且要求传入图片是32float型,网上找了一堆代码,通常都是8UC3的图片可以正常resize,32FC3的就会出错,最后翻阅OPENCV官方代码,完成了转换,记录一下以免以后忘记,直接上代码。

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;


void resize_floatmap(const cv::Mat &src, cv::Mat &dst, cv::Size size){
    dst.create(size, src.type());
	Size ssize = src.size();
	Size dsize = dst.size();

	double fx = (double)dsize.width / ssize.width;
	double fy = (double)dsize.height / ssize.height;

	AutoBuffer<int> _x_ofs(dsize.width);
	int* x_ofs = _x_ofs;
	int pix_size = (int)src.elemSize();
	int pix_size4 = (int)(pix_size / sizeof(int));
	double ifx = 1. / fx, ify = 1. / fy;

    for(int x = 0; x < dsize.width; x++){
		int sx = cvFloor(x*ifx);
 		x_ofs[x] = std::min(sx, ssize.width - 1)*pix_size;
    }

    Range range(0, dsize.height);
	int x, y;

	for (y = range.start; y < range.end; y++) {
		uchar* D = dst.data + dst.step*y;
		int sy = std::min(cvFloor(y*ify), ssize.height - 1);
		const uchar* S = src.ptr(sy);

		switch (pix_size) {
		case 1:
			for (x = 0; x <= dsize.width - 2; x += 2) {
				uchar t0 = S[x_ofs[x]];
				uchar t1 = S[x_ofs[x + 1]];
				D[x] = t0;
				D[x + 1] = t1;
			}

			for (; x < dsize.width; x++) {
				D[x] = S[x_ofs[x]];
			}
			break;
		case 2:
			for (x = 0; x < dsize.width; x++) {
				*(ushort*)(D + x * 2) = *(ushort*)(S + x_ofs[x]);
			}
			break;
		case 3:
			for (x = 0; x < dsize.width; x++, D += 3) {
				const uchar* _tS = S + x_ofs[x];
				D[0] = _tS[0]; D[1] = _tS[1]; D[2] = _tS[2];
			}
			break;
		case 4:
			for (x = 0; x < dsize.width; x++) {
				*(int*)(D + x * 4) = *(int*)(S + x_ofs[x]);
			}
			break;
		case 6:
			for (x = 0; x < dsize.width; x++, D += 6) {
				const ushort* _tS = (const ushort*)(S + x_ofs[x]);
				ushort* _tD = (ushort*)D;
				_tD[0] = _tS[0]; _tD[1] = _tS[1]; _tD[2] = _tS[2];
			}
			break;
		case 8:
			for (x = 0; x < dsize.width; x++, D += 8) {
				const int* _tS = (const int*)(S + x_ofs[x]);
				int* _tD = (int*)D;
				_tD[0] = _tS[0]; _tD[1] = _tS[1];
			}
			break;
		case 12:
			for (x = 0; x < dsize.width; x++, D += 12) {
				const int* _tS = (const int*)(S + x_ofs[x]);
				int* _tD = (int*)D;
				_tD[0] = _tS[0]; _tD[1] = _tS[1]; _tD[2] = _tS[2];
			}
			break;
		default:
			for (x = 0; x < dsize.width; x++, D += pix_size) {
				const int* _tS = (const int*)(S + x_ofs[x]);
				int* _tD = (int*)D;
				for (int k = 0; k < pix_size4; k++)
					_tD[k] = _tS[k];
			}
		}
	}
}


int main(int argc, char *argv[])
{
    Mat src = imread("image.JPG");
    if (src.empty()) 
    {
    cout << "读取图片失败..." << endl;
    return -1;
    } 
    Mat dst, dst2, dst3, dst4, dst5, sub1;
    src.convertTo(dst, CV_32FC3, 1/255.0);
    resize(src, dst2, Size(1280, 640), 0, 0, cv::INTER_NEAREST);
    resize(dst, dst3, Size(1280, 640), 0, 0, cv::INTER_NEAREST);
    std::cout<<"shape: "<<dst3.cols<<dst3.rows<<std::endl;
    resize_floatmap(src, dst4, Size(1280, 640));
    resize_floatmap(dst, dst5, Size(1280, 640));

    //subtract(dst4, dst5, sub1);
    imshow("src", src);
    imshow("dst", dst3);
    imshow("dst2", dst2);
    imshow("dst4", dst4);
    imshow("dst5", dst5);
    //imshow("sub1", sub1);
    waitKey(0);
    return 0;
}

至此,改一下图片输入就行了,有兴趣可以翻阅OPENCV官方库,https://github.com/fengbingchun/OpenCV_Test/blob/master/src/fbc_cv/include/resize.hpp
opencv/modules/imgproc/src/resize.cpp at 4.x · opencv/opencv (github.com)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,使用OpenCVresize函数可以实现图像的缩放和放大操作。该函数的原型如下: ```cpp void cv::resize(InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR ); ``` 其中,各参数的含义如下: - `src`:源图像,可以是Mat类型的对象,也可以是其它形式的图像数据。 - `dst`:目标图像,用于存储resize操作后的图像数据,也可以是Mat类型的对象,也可以是其它形式的图像数据。 - `dsize`:目标图像的大小,可以指定为Size类型的对象或者cv::Size()函数。当指定了dsize参数时,fx和fy参数会被忽略。 - `fx`:水平方向的缩放比例,当dsize参数没有指定时才会生效。 - `fy`:垂直方向的缩放比例,当dsize参数没有指定时才会生效。 - `interpolation`:插值方法,可以指定为INTER_NEAREST、INTER_LINEAR、INTER_CUBIC、INTER_AREA、INTER_LANCZOS4等常量之一。 下面是一个简单的示例代码,展示了如何使用resize函数对图像进行缩放操作: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 读取原始图像 Mat src = imread("lena.jpg"); if (src.empty()) { cout << "can not load image!" << endl; return -1; } // 缩放图像 Mat dst; resize(src, dst, Size(src.cols / 2, src.rows / 2), 0, 0, INTER_LINEAR); // 显示原始图像和缩放后的图像 namedWindow("src", WINDOW_NORMAL); namedWindow("dst", WINDOW_NORMAL); imshow("src", src); imshow("dst", dst); waitKey(0); return 0; } ``` 在这个示例代码中,我们首先读取了一张名为lena.jpg的图像,然后调用resize函数对图像进行了缩放操作,将图像的大小缩小为原始图像的一半。最后,我们使用imshow函数将原始图像和缩放后的图像在窗口中显示出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值