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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值