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

2023-11-06

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

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


	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];
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV中resize函数五种插值算法的实现过程 的相关文章

随机推荐

  • iOS 应用获取最上层全屏 Window 的正确方法

    有时候 我们需要将View添加到最上层的Window上 比如 弹出框 Loading等 经常有同学直接通过 UIApplication sharedApplication windows lastObject 来获取 这种方法是非常不严谨的
  • leetcode----JavaScript 详情题解(4)

    目录 2722 根据 ID 合并两个数组 2723 添加两个 Promise 对象 2724 排序方式 2725 间隔取消 2726 使用方法链的计算器 2727 判断对象是否为空 2624 蜗牛排序 2694 事件发射器 2722 根据
  • 集成支付宝报错订单信息有错误,建议联系实家。 错误码: TOTAL FEE EXCEED

    问题 集成支付宝报错 订单信息有错误 建议联系实家 错误码 TOTAL FEE EXCEED 详细问题 笔者按照支付宝沙箱支付快速集成版进行操作 操作完成访问所集成的支付宝 页面如下 发起请求核心代码 response sendRedire
  • ubuntu(20.04)-shell脚本(4)-vmstat-iostat-expr-netstat-arp-Tracert-Route-NBTStat

    vmstat 好iostat 两个命令都适用于所有主要的类unix系统 linux的软件包 都在sysstat软件包中 1 vmstat iostat 基本语法 每列的意义 常用的 Free 空闲的内存空间 si 每秒从磁盘中交换进内存的数
  • 项目问题总结

    1 android studio 导入开源项目源码时要注意与自己包的冲突 比如 你有一个com xxxx的包 而需要导入的是com xx yy 你就不能把整个包复制过来 否则会报can t resolve symbil 因为它根据com会到
  • 虚幻4常见问题

    问题1 问题描述 UE4找不到游戏模块 UE4 the game module fps could not be found 解决方案 重新编译一遍C 项目 通过C 项目启动UE4生成游戏模块 为了防止生成失效可以启动uproject文件再
  • 数组是分配在栈中的

    关于JAVA堆 下面说法错误的是 正确答案 C 你的答案 B 错误 所有类的实例和数组都是在堆上分配内存的 堆内存由存活和死亡的对象 空闲碎片区组成 数组是分配在栈中的 对象所占的堆内存是由自动内存管理系统回收 JVM 关于堆和栈 Java
  • Java 数据转换/进制转换 工具类

    public class ByteUtil 十六进制转为十进制 public static String getHexToTen String hex return String valueOf Integer parseInt hex 1
  • Contact Form 7 获取用户IP和留言url,发布时间

    提交询盘时间 date time 客户访问IP a href remote ip a 点击打开可看到ip所属国家 客户访问产品 url 客户访问日期 date 客户访问者有没有facebook a href your email a
  • XXE(外部实体注入)

    写在前面 这个系列开始写写XXE相关的东西 这里是第一部分 相关资料及使用靶场如下 XML学习 靶场链接 XXE是以XML为基础进行的一种攻击 所以你需要先学习XML 为了更方便你检索题目且由于是国外网站 会带有一定外语及翻译 最后 如果你
  • 监听pda扫描_android系统PDA扫描枪,扫描完成后自带回车,为什么回车监听第一次不起作用,手动提交一次后才能正常提交...

    如题 第一次扫描后 在条码后出现的是回车 而不是绑定的提交按钮的提交功能 手动软键盘提交后 再回到扫描页 再次扫描 就会自动执行提交功能 下面附上源码 privateImageButton 如题 第一次扫描后 在条码后出现的是回车 而不是绑
  • openGL 调用glewInit()失败

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 glew官网 二 glew库初始化调用失败 1 引入库 2 glew调用失败原因 着色器 运行结果 前言 OpenGL Extension Wrangler Libra
  • 垂类模型大有前景,但AGI却给自己“挖了个坑”

    巨量模型是个 坑 但垂直模型不是 数科星球原创 作者丨苑晶 编辑丨大兔 2023年4月 GPT 5的相关消息引起了一阵轰动 彼时 人们对巨量大模型既有期待 也有恐惧 更有甚者 认为人类历史或许将因此而画上终止符 但很快 从业者便发现 巨量大
  • ZYNQ学习之路(三):自定义IP实现PL处理PS写入BRAM的数据

    目录 一 实验简介 二 vivado部分处理 三 SDK编程 四 实验测试 五 总结 一 实验简介 ZYNQ系列嵌入式FPGA可以使PS将数据写入PL部分BRAM PL可以将数据读取后再重新写入BRAM PS将数据读出后再传走 这样可以使P
  • 数据结构--一个数组实现两个栈

    用一个数组实现两个栈 通常我们会想到以下几种方案 1 奇偶栈 即就是将数组的偶数位置看作一个栈的存储空间 将奇数位置看作另一个栈的存储空间 2 从中间分别向两边展开 即就是将数组的中间位置看作是两个栈的栈底 压栈时栈顶指针分别向两边移动 当
  • C++ 加锁的原则

    规则1 多线程 进程并行访问共享资源时 一定要加锁保护 说明 共享资源包括全局变量 静态变量 共享内存 文件等 建议封装像智能指针一样的对象对锁进行管理 比如我们就封装了一个auto lock 在构造时申请 锁 析构中释放锁 保证不会忘记
  • docker容器日志管理

    docker容器日志导致主机磁盘空间满了 docker logs f container name 噼里啪啦一大堆 很占用空间 需要的日志可进行备份 不用的日志可以清理掉了 设置一个容器服务的日志大小上限 上述方法 日志文件迟早又会涨回来
  • Python——数据分析,原来女孩子喜欢这些礼物

    每次情人节我都会问女朋友 你喜欢啥 你想要啥 但是每次女朋友每次都说 你自己想 伸手要来的没有惊喜 这搞的我还没到情人节就开始失眠了 总是担心送的礼物她会不喜欢 相信有很多朋友跟我一样苦恼吧 今天特意爬取了某东的数据 来分析下大家情人节都送
  • Python可视化--双Y轴图

    双Y轴图 1 双Y轴图简介 双Y轴图顾名思义就是在一个图里有两个Y轴 这种图形主要用来展示两个因变量和一个自变量的关系并且两个因变量的数值单位还不同 如我们想要展示不同月份公司销业绩以及成本的变化情况这时就可以用双Y轴图来展示 因变量销量和
  • OpenCV中resize函数五种插值算法的实现过程

    最新版OpenCV2 4 7中 cv resize函数有五种插值算法 最近邻 双线性 双三次 基于像素区域关系 兰索斯插值 下面用for循环代替cv resize函数来说明其详细的插值实现过程 其中部分代码摘自于cv resize函数中的源