直方图匹配原理与python、matlab实现
直方图匹配本质上是让两幅图像的累积直方图尽量相似,累积直方图相似了,直方图也就相似了。
把原图像img的直方图匹配到参考图像ref的直方图,包括以下几个步骤:
1. 求出原图像img的累积直方图img_accu;
2. 求出参考图像ref的累积直方图ref_accu;
3. 灰度级g在img_accu中对应的值记为img_accu_g,找出ref_accu中与ref_accu_g最接近的值,记为ref_accu_G,记该值对应的灰度级为G;
4. 根据g和G的对应关系,得到img经过匹配之后的直方图。
为了说明该过程,我们举一个简单的例子,并把计算过程列在表格中。该例子中图像只有10个灰度级,总共3289个像素,如下图所示。

(a) 原图像img的直方图 (b) 参考图像ref的直方图

(c) 原图像img的累积直方图 (d) 参考图像ref的累积直方图
| 灰度级 | ref直方图 | ref累积直方图 | img直方图 |
img累积直方图 | 匹配之后的灰度级 |
匹配之后的img累积直方图 |
匹配之后的img直方图 |
| 1 | 0 | 0 | 927 | 927(匹配第三列第七行的1137) | 7 | 0 | 0 |
| 2 | 0 | 0 | 690 | 1617(匹配第三列第八行的1672) | 8 | 0 | 0 |
| 3 | 20 | 20 | 535 | 2152(匹配第三列第九行的2362) | 9 | 0 | 0 |
| 4 | 112 | 132 | 450 | 2602(匹配第三列第九行的2362) | 9 | 0 | 0 |
| 5 | 221 | 353 | 334 | 2936(匹配第三列第十行的3289) | 10 | 0 | 0 |
| 6 | 334 | 687 | 221 | 3157(匹配第三列第十行的3289) | 10 | 0 | 0 |
| 7 | 450 | 1137 | 112 | 3269(匹配第三列第十行的3289) | 10 | 927 | 927 |
| 8 | 535 | 1672 | 20 | 3289(匹配第三列第十行的3289) | 10 | 1617 | 690 |
| 9 | 690 | 2362 | 0 | 3289(匹配第三列第十行的3289) | 10 | 2152 | 985 |
| 10 | 927 | 3289 | 0 | 3289(匹配第三列第十行的3289) | 10 | 3289 | 687 |
img在匹配之后的效果如下:

(a) img的经过匹配之后的累积直方图 (b) img的经过匹配之后的直方图
1. OpenCV-Python实现直方图匹配
代码如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt img = cv2.imread('C:\\Users\\admin\\Desktop\\original_img3\\testimg\\lena_300_500.jpg')
ref = cv2.imread('C:\\Users\\admin\\Desktop\\original_img3\\testimg\\messi_300_500.jpg') out = np.zeros_like(img)
_, _, colorChannel = img.shape
for i in range(colorChannel):
print(i)
hist_img, _ = np.histogram(img[:, :, i], 256) # get the histogram
hist_ref, _ = np.histogram(ref[:, :, i], 256)
cdf_img = np.cumsum(hist_img) # get the accumulative histogram
cdf_ref = np.cumsum(hist_ref) for j in range(256):
tmp = abs(cdf_img[j] - cdf_ref)
tmp = tmp.tolist()
idx = tmp.index(min(tmp)) # find the smallest number in tmp, get the index of this number
out[:, :, i][img[:, :, i] == j] = idx cv2.imwrite('C:\\Users\\admin\\Desktop\\lena.jpg', out)
print('Done')
效果如下:

2. matlab实现直方图匹配
程序如下:
clear;
% matching img's histogram to ref's histogram.
path = 'C:\\Users\\admin\\Desktop\\original_img3\\yijia0923_9\\';
ref = imread([path, '18.jpg']);
img = imread([path, '21.jpg']); [H, W, colorChannel] = size(ref);
out = zeros(H, W, colorChannel);
for k = 1:colorChannel
disp(k);
hist_ref = imhist(ref(:, :, k)); % ref的直方图
cumHist_ref = []; %ref的累积直方图
for i=1:256
cumHist_ref = [cumHist_ref sum(hist_ref(1:i))];
end img1 = img(:, :, k);
hist_img = imhist(img1); %img的直方图
cumHist_img = []; %img的累积直方图
for i=1:256
cumHist_img = [cumHist_img sum(hist_img(1:i))];
end for i=1:256
tmp{i} = cumHist_ref - cumHist_img(i);
tmp{i} = abs(tmp{i}); % 找到两个累积直方图距离最近的点
[a, index(i)] = min(tmp{i}); % a是tmp{i}中最小的值,index是该值对应的下标
end imgn = zeros(H,W);
for i = 1:H
for j = 1:W
imgn(i,j) = index(img1(i,j)+1)-1; % 由原图的灰度通过索引映射到新的灰度
end
end
out(:, :, k) = imgn;
end out=uint8(out);
% imwrite(out, [path, 'new3.jpg']);
figure; imshow(out); title('out')
disp('Done');
直方图匹配原理与python、matlab实现的更多相关文章
- OpenCV直方图(直方图、直方图均衡,直方图匹配,原理、实现)
1 直方图 灰度级范围为 \([0,L-1]\) 的数字图像的直方图是离散函数 \(h(r_k) = n_k\) , 其中 \(r_k\) 是第\(k\)级灰度值,\(n_k\) 是图像中灰度为 \( ...
- 【zz】matlab 直方图匹配
原文地址:http://www.cnblogs.com/tiandsp/archive/2012/12/19/2825418.html 直方图匹配或叫做直方图规定化都可以,是把原图像的直方图按照给定的 ...
- 灰度图像--图像增强 直方图匹配(规定化)Histogram Specification
学习DIP第39天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不 ...
- c#数字图像处理(七)直方图匹配
直方图匹配,又称直方图规定化,即变换原图的直方图为规定的某种形式的直方图,从而使两幅图像具有类似的色调和反差.直方图匹配属于非线性点运算. 直方图规定化的原理:对两个直方图都做均衡化,变成相同的归一化 ...
- NFA引擎匹配原理
1 为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动听的乐曲,但他/她或 ...
- paip.编程语言方法重载实现的原理及python,php,js中实现方法重载
paip.编程语言方法重载实现的原理及python,php,js中实现方法重载 有些语言,在方法的重载上,形式上不支持函数重载,但可以通过模拟实现.. 主要原理:根据参数个数进行重载,或者使用默认值 ...
- CSS选择器以及优先级与匹配原理
最常用的五类CSS选择器 准确而简洁的运用CSS选择器会达到非常好的效果.我们不必通篇给每一个元素定义类(class)或ID,通过合适的组织,可以用最简单的方法实现同样的效果.在实际工作中,最常用的选 ...
- CSS选择器、优先级与匹配原理(转)
CSS选择器.优先级与匹配原理 导航 为了分析Bootstrap源码,所以的先把CSS选择器相关的东东给巩固好 废话就不多说了 CSS 2.1 selectors, Part 1 计算指定选择器的优先 ...
- css匹配原理与优化
一. 匹配原理 浏览器CSS匹配不是从左到右进行查找,而是从右到左进行查找.比如之前说的 DIV#divBox p span.red{color:red;},浏览器的查找顺序如下:先查找 html 中 ...
随机推荐
- poj1734 Sightseeing trip[最小环]
一个最小环裸题.最小环的两种求法dijkstra和Floyd直接参见这里我就是从这里学的,不想写了. 注意这里最重要的一个点是利用了Floyd的dp过程中路径上点不超过$k$这一性质,来枚举环上最大编 ...
- js特效 15个小demo
js特效和15个小demo 代码如下:images文件夹未上传 1.图片切换: <!DOCTYPE html> <html> <head> <title> ...
- logback.xml 配置详解(转)
<?xml version="1.0" encoding="UTF-8"> <configuration> <!-- 设置控制台日 ...
- 错误/异常:org.hibernate.InvalidMappingException: Could not parse mapping document from resource com/shore/model/Husband.hbm.xml 的解决方法
1.错误/异常视图 错误/异常描述:无效的映射异常,无法从xxxxx资源中解析映射文档 2.解决方法 出现这个异常,一般情况下是包名写错了.改回来即可. 看报错/异常的第一行,最后面,会提示你 ...
- MessagePack Jackson 数据大小
我们在使用 MessagePack 对 List 对象数据进行序列化的时候,发现序列化以后的二进制数组数据偏大的情况. 请注意,不是所有的 List 对象都会出现这种情况,这个根据你 List 对象中 ...
- 微信小程序搭建mpvue+vant+flyio
导语 上一篇文章微信小程序搭建mpvue+vant已经介绍了如何搭起mpvue项目及引入vant,本篇文章继续在它的基础上,引入flyio,并做一些封装,目的是为了在小程序发起请求. 这时读者会有些疑 ...
- yum update 更新失败
1.yum安装东西的时候,老是报:There are unfinished transactions remaining. You might consider running yum-complet ...
- Jmeter设置成中文
首次启动Jmeter为中文 选择后即变为中文
- 8.4 JavaScript(一)
参考链接:http://how2j.cn/k/javascript/javascript-javascript-tutorial/519.html 一.JavaScript是什么 JavaScript ...
- Nginx事件管理之事件处理流程
1. 概述 事件处理要解决的两个问题: "惊群" 问题,即多个 worker 子进程监听相同端口时,在 accept 建立新连接时会有争抢,引发不必要的上下文切换, 增加系统开销. ...