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;
}

实验结果例如以下:

原图为

须要匹配的图是

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXJvbnlvdW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">。

终于输出的是图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXJvbnlvdW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">。

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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXJvbnlvdW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">;

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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXJvbnlvdW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

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

【图像处理】基于OpenCV底层实现的直方图匹配的更多相关文章

  1. 【图像处理】基于OpenCV底层实现的图片旋转

    image processing 系列 [图像处理]直方图匹配 [图像处理]高斯滤波.中值滤波.均值滤波 图片旋转,本质上是对旋转后的图片中每一个像素点计算在原图的位置.然后照搬过来就好. (多说一句 ...

  2. 【图像处理】基于OpenCV实现图像直方图的原理

    背景 图像的直方图是衡量图像像素分布的一种方式,可以通过分析像素分布,使用直方图均衡化对图像进行优化,让图像变的清晰. opencv官方对图像直方图的定义如下: 直方图是图像中像素强度分布的图形表达方 ...

  3. 基于Opencv和Mfc的图像处理增强库GOCVHelper(索引)

    GOCVHelper(GreenOpen Computer Version Helper )是我在这几年编写图像处理程序的过程中积累下来的函数库.主要是对Opencv的适当扩展和在实现Mfc程序时候的 ...

  4. OpenCV直方图(直方图、直方图均衡,直方图匹配,原理、实现)

    1 直方图 灰度级范围为 \([0,L-1]\) 的数字图像的直方图是离散函数 \(h(r_k) = n_k\) , 其中 \(r_k\) 是第\(k\)级灰度值,\(n_k\) 是图像中灰度为 \( ...

  5. 基于OpenCV的双目视觉匹配测距系统

    刚读研究生的时候,自己导师研究的方向是双目视觉,于是让自己研究OpenCV,折腾了几个月,算法上没啥突破,不过工程上还是折腾出了一个能用的小玩意,基于OpenCV实现了相机的标定.双目视觉图片的矫正. ...

  6. 基于 opencv 的图像处理入门教程

    前言 虽然计算机视觉领域目前基本是以深度学习算法为主,但实际上很多时候对图片的很多处理方法,并不需要采用深度学习的网络模型,采用目前成熟的图像处理库即可实现,比如 OpenCV 和 PIL ,对图片进 ...

  7. Python图像处理丨基于OpenCV和像素处理的图像灰度化处理

    摘要:本篇文章讲解图像灰度化处理的知识,结合OpenCV调用cv2.cvtColor()函数实现图像灰度操作,使用像素处理方法对图像进行灰度化处理. 本文分享自华为云社区<[Python图像处理 ...

  8. 图像处理基础(2):自适应中值滤波器(基于OpenCV实现)

    本文主要介绍了自适应的中值滤波器,并基于OpenCV实现了该滤波器,并且将自适应的中值滤波器和常规的中值滤波器对不同概率的椒盐噪声的过滤效果进行了对比.最后,对中值滤波器的优缺点了进行了总结. 空间滤 ...

  9. c#数字图像处理(七)直方图匹配

    直方图匹配,又称直方图规定化,即变换原图的直方图为规定的某种形式的直方图,从而使两幅图像具有类似的色调和反差.直方图匹配属于非线性点运算. 直方图规定化的原理:对两个直方图都做均衡化,变成相同的归一化 ...

随机推荐

  1. 20155215 2016-2017-2 《Java程序设计》第7周学习总结

    20155215 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 lambda语法:Lambda去重复,回忆DRY原则,Lambda表达式可读性更好 ...

  2. continue和break区别

    break 语句用于跳出循环. continue 用于跳过循环中的一个迭代. 一个迭代,就是一次循环,continue终止本次循环,继续下一次循环: break,循环终止不再循环.

  3. Anaconda+django写出第一个web app(六)

    今天学习如何写一个注册用户的界面. 上一节的导航栏中我们修改了导航栏右侧的文字为register并将路径设置为/register,内容如下: <li><a href="/r ...

  4. ZYNQ. LwIP.PHY.KSZ9031RNX

    新一块板子 米尔科技的 z-turn  使用的PHY芯片是Micrel的 KSZ9031RNX 而不是zedboard上的Marvell的. 直接使用lwip的echo server demo时会报错 ...

  5. Burp-Suit之Interder

    登陆页面:http://localhost/pentest/brute/login.php 设置代理,使用Burp截断: 发送到Intruder进行爆破,这里我先说明一下Intruder页面 Inte ...

  6. 学习mysql replication

  7. js字符串操作之substr与substring

    substr和substring两个都是截取字符串的. 两者有相同点,如果只是写一个参数,两者的作用都是一样的:就是截取字符串当前下标以后直到字符串最后的字符串片段. 例如: `var a=" ...

  8. java adapter(适配器)惯用方法

    如果现在有一个Iterable类,你想要添加一种或多种在foreach语句中使用这个类的方法,例如方向迭代,应该怎么做呢? 如果之间继承这个类,并且覆盖iterator()方法,你只能替换现有的方法, ...

  9. java 代理 agency

    java并没有对其提供直接的支持,这是继承和组合的中庸之道,因为我们将一个成员对象置于所要构造的类中(组合),但与此同时我们在新类中暴露了该成员的所有方法(就像继承),使用代理时可以拥有更多的控制力, ...

  10. Zookeeper的java客户端API使用方法(五)

    前面几篇博文,我们简单的介绍了一下zookeeper,如何安装zookeeper集群,以及如何使用命令行等.这篇博文我们重点来看下Zookeeper的java客户端API使用方式. 创建会话 客户端可 ...