当前位置: 首页 > news >正文

【图像处理】基于OpenCV底层实现的直方图匹配

image processing 系列:

  1. 【图像处理】图片旋转
  2. 【图像处理】高斯滤波、中值滤波、均值滤波

直方图匹配算法。又称直方图规定化。简单说。就是依据某函数、或者另外一张图片的引导,使得原图改变。

感觉解释的最好的是:http://www.360doc.com/content/13/1106/16/10724725_327179043.shtml

完整代码:github (里面同一时候包括OSTU / 大津算法、直方图均衡化等算法,还包括两种測试图片)。

由于我个人兴趣爱好(放P就是老师逼的。

。。)。不同意使用 OpenCV 封装好的直方图函数。

依据实例解说,了解了直方图匹配算法底层的操作(多说一句,这个样例能够是我见过最好的直方图匹配算法解说,也是非常难见的此算法的样例,必读)。

注:实例解说中 0->3 的意义是,原图中灰度级为 0 的像素点所有转化为原图中的 3 灰度级。


上代码(当中,srcImg 是原图。dstImg 是须要匹配的图,flag 标记两者是 RGB  图还是灰度图):

cv::Mat ycMatchHist(cv::Mat srcImg, cv::Mat dstImg, int flag)
{
	// ****** 假设是 RGB 图片则转为灰度图片操作 ******
	Mat out(srcImg);
	if (flag == YC_RGB)
	{
		cvtColor(srcImg, out, CV_BGR2GRAY);
	}
	else if (flag == YC_GRAY)
	{
	}
	int grayLevel[colvl];
	for(int i=0; i<colvl; i++)	grayLevel[i] = i;

	int grayArr[colvl];
	int srcRow = srcImg.rows;
	int srcCol = srcImg.cols;
	int dstRow = dstImg.rows;
	int dstCol = dstImg.cols;
	float srcCdfArr[colvl]  = {0.f};
	float dstCdfArr[colvl]  = {0.f};
	float tmp;

	// *** 求解源图片的累积直方图(概率)分布 *** 
	memset(grayArr, 0, sizeof(grayArr));
	for(size_t nrow = 0; nrow < srcRow; nrow++)  
       for(size_t ncol = 0; ncol < srcCol; ncol++)
	   {
		   int tag = srcImg.at<uchar>(nrow, ncol);
		   grayArr[tag]++;
	   }

	tmp = 0;
	for(int i=0; i<colvl; i++)
	{
		tmp += grayArr[i];
		srcCdfArr[i] = tmp / (srcRow * srcCol);
		// std::cout<<srcCdfArr[i]<<std::endl;
	}

	// *** 求解目标图片的累积直方图(概率)分布 *** 
	memset(grayArr, 0, sizeof(grayArr));
	for(size_t nrow = 0; nrow < dstRow; nrow++)  
       for(size_t ncol = 0; ncol < dstCol; ncol++)
	   {
		   int tag = dstImg.at<uchar>(nrow, ncol);
		   grayArr[tag]++;
	   }

	tmp = 0;
	for(int i=0; i<colvl; i++)
	{
		tmp += grayArr[i];
		dstCdfArr[i] = tmp / (dstRow * dstCol);
	}

	// *** 直方图匹配算法 ***
	int histMap[colvl];
	int minTag;
	for(int i=0; i<colvl; i++)
	{
		float minMap = 10.f;
		for(int j=0; j<colvl; j++)
		{
			if (minMap > abs(srcCdfArr[i] - dstCdfArr[j]))
			{
				minMap = abs(srcCdfArr[i] - dstCdfArr[j]);
				minTag = j;
			}
		}
		histMap[i] = minTag;
	}

	for(size_t nrow = 0; nrow < out.rows; nrow++)  
       for(size_t ncol = 0; ncol < out.cols; ncol++)
	   {
		   int tag = out.at<uchar>(nrow, ncol);
		   out.at<uchar>(nrow, ncol) = histMap[tag];
	   }

	return out;
}

实验结果例如以下:

原图为

须要匹配的图是

终于输出的是图

匹配图片的灰度累积直方图为:

终于输出的灰度累积直方图为:

两者非常接近了,证明匹配算法是可行的(当然假设我说错了,欢迎打脸。共同进步哈哈~)




本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5409488.html,如需转载请自行联系原作者 

相关文章:

  • javascript判断IPV6格式
  • 【sql】部门最高工资 Department Highest Salary
  • 用shell批量修改类似的文件名
  • 【★】交换层网关协议大总结!
  • 使用vRealize Operations for Horizon,做高效的虚拟桌面系统管理员
  • Tomcat6+JDK6如何加固,解决Logjam attack,
  • Word2007“由于文件许可权错误,Word无法完成保存操作”问题的解决方法
  • Centos压缩解压
  • Linux执行命令常见的英语语句
  • asn1编码格式的解析过程
  • top2
  • 远程连接服务器工具:sshpass
  • U盘安装Debian 6 amd64版本
  • Zabbix调优的几个原则
  • HytrixCommand实践总结
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 03Go 类型总结
  • Android系统模拟器绘制实现概述
  • angular2 简述
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • java多线程
  • Java方法详解
  • Laravel5.4 Queues队列学习
  • nginx 负载服务器优化
  • Node 版本管理
  • NSTimer学习笔记
  • React系列之 Redux 架构模式
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • 程序员最讨厌的9句话,你可有补充?
  • 从0实现一个tiny react(三)生命周期
  • 从零开始的无人驾驶 1
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 设计模式(12)迭代器模式(讲解+应用)
  • 学习JavaScript数据结构与算法 — 树
  • 移动端 h5开发相关内容总结(三)
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 终端用户监控:真实用户监控还是模拟监控?
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • FaaS 的简单实践
  • k8s使用glusterfs实现动态持久化存储
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • #、%和$符号在OGNL表达式中经常出现
  • (C++)八皇后问题
  • (C语言)二分查找 超详细
  • (LeetCode C++)盛最多水的容器
  • (搬运以学习)flask 上下文的实现
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (一)kafka实战——kafka源码编译启动
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • *** 2003
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .NET Core 中插件式开发实现
  • .NET 设计模式初探