OpenCV-Python教程(10、直方图均衡化)
相比C++而言,Python适合做原型。本系列的文章介绍如何在Python中用OpenCV图形库,以及与C++调用相应OpenCV函数的不同之处。这篇文章介绍在Python中使用OpenCV和NumPy对直方图进行均衡化处理。
提示:
- 转载请详细注明原作者及出处,谢谢!
- 本文不介详细的理论知识,读者可从其他资料中获取相应的背景知识。笔者推荐清华大学出版社的《图像处理与计算机视觉算法及应用(第2版) 》,对于本节的内容,建议直接参考维基百科直方图均衡化,只需看下页面最后的两幅图就能懂了。
本文内容:
- 使用查找表拉伸直方图
- 使用OpenCV和NumPy的函数以不同的方式进行直方图均衡化
在某些情况下,一副图像中大部分像素的强度都集中在某一区域,而质量较高的图像中,像素的强度应该均衡的分布。为此,可将表示像素强度的直方图进行拉伸,将其平坦化。如下:
图来自维基百科
实验数据
本节的实验数据来自维基百科,原图如下:
其直方图为:
使用查找表来拉伸直方图
在图像处理中,直方图均衡化一般用来均衡图像的强度,或增加图像的对比度。在介绍使用直方图均衡化来拉伸图像的直方图之前,先介绍使用查询表的方法。
观察上图中原始图像的直方图,很容易发现大部分强度值范围都没有用到。因此先检测图像非0的最低(imin)强度值和最高(imax)强度值。将最低值imin设为0,最高值imax设为255。中间的按255.0*(i-imin)/(imax-imin)+0.5)的形式设置。
实现的任务主要集中在查询表的创建中,代码如下:
minBinNo, maxBinNo = 0, 255 #计算从左起第一个不为0的直方图位置
for binNo, binValue in enumerate(hist):
if binValue != 0:
minBinNo = binNo
break
#计算从右起第一个不为0的直方图位置
for binNo, binValue in enumerate(reversed(hist)):
if binValue != 0:
maxBinNo = 255-binNo
break
print minBinNo, maxBinNo #生成查找表,方法来自参考文献1第四章第2节
for i,v in enumerate(lut):
print i
if i < minBinNo:
lut[i] = 0
elif i > maxBinNo:
lut[i] = 255
else:
lut[i] = int(255.0*(i-minBinNo)/(maxBinNo-minBinNo)+0.5)
查询表创建完成后,就直接调用相应的OpenCV函数即可,这里调用的是cv2.LUT函数:
#计算
result = cv2.LUT(image, lut)
cv2.LUT函数只有两个参数,分别为输入图像和查找表,其返回处理的结果,完整代码如下:
#coding=utf-8
import cv2
import numpy as np image = cv2.imread("D:/test/unequ.jpg", 0)
lut = np.zeros(256, dtype = image.dtype )#创建空的查找表
hist= cv2.calcHist([image], #计算图像的直方图
[0], #使用的通道
None, #没有使用mask
[256], #it is a 1D histogram
[0.0,255.0]) minBinNo, maxBinNo = 0, 255 #计算从左起第一个不为0的直方图柱的位置
for binNo, binValue in enumerate(hist):
if binValue != 0:
minBinNo = binNo
break
#计算从右起第一个不为0的直方图柱的位置
for binNo, binValue in enumerate(reversed(hist)):
if binValue != 0:
maxBinNo = 255-binNo
break
print minBinNo, maxBinNo #生成查找表,方法来自参考文献1第四章第2节
for i,v in enumerate(lut):
print i
if i < minBinNo:
lut[i] = 0
elif i > maxBinNo:
lut[i] = 255
else:
lut[i] = int(255.0*(i-minBinNo)/(maxBinNo-minBinNo)+0.5) #计算
result = cv2.LUT(image, lut)
cv2.imshow("Result", result)
cv2.imwrite("LutImage.jpg", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
直方图结果如下,可以看到原来占的区域很小的直方图尖峰被移动了:
处理结果为:
关于直方图的绘制,请参考这篇文章。
直方图均衡化
介绍
有时图像的视觉上的缺陷并不在强度值集中在很窄的范围内。而是某些强度值的使用频率很大。比如第一幅图中,灰度图中间值的占了很大的比例。
在完美均衡的直方图中,每个柱的值都应该相等。即50%的像素值应该小于128,25%的像素值应该小于64。总结出的经验可定义为:在标准的直方图中p%的像素拥有的强度值一定小于或等于255×p%。将该规律用于均衡直方图中:强度i的灰度值应该在对应的像素强度值低于i的百分比的强度中。因此,所需的查询表可以由下面的式子建立:
lut[i] = int(255.0 *p[i]) #p[i]是是强度值小于或等于i的像素的数目。
p[i]即直方图累积值,这是包含小于给点强度值的像素的直方图,以代替包含指定强度值像素的数目。比如第一幅图像的累计直方图如下图中的蓝线:
而完美均衡的直方图,其累积直方图应为一条斜线,如上图中均衡化之后的红线。
更专业一点,这种累积直方图应称为累积分布(cumulative distribition)。在NumPy中有一个专门的函数来计算。这在NumPy实现直方图均衡化一节中介绍。
通过上面的介绍,应该可以明白,直方图均衡化就是对图像使用一种特殊的查询表。在第三个例子中可以看到使用查询表来获得直方图均衡化的效果。通常来说,直方图均衡化大大增加了图像的表象。但根据图像可视内容的不同,不同图像的直方图均衡化产生的效果不尽相同。
直方图均衡化之OpenCV函数实现
用OpenCV实现直方图均衡化很简单,只需调用一个函数即可:
img = cv2.imread('图像路径',0)
equ = cv2.equalizeHist(img)
cv2.imshow('equ',equ)
这样图像就均衡化了。可以通过 直方图的计算与显示这篇文章中介绍的方法将结果绘制出来。
直方图均衡化之NumPy函数实现
通过前面的介绍,可以明白直方图均衡化就是用一种特殊的查找表来实现的。所以这里用NumPy函数,以查找表的方式手动实现图像直方图的均衡化:
#coding=utf-8
import cv2
import numpy as np image = cv2.imread("D:/test/unequ.jpg", 0) lut = np.zeros(256, dtype = image.dtype )#创建空的查找表 hist,bins = np.histogram(image.flatten(),256,[0,256])
cdf = hist.cumsum() #计算累积直方图
cdf_m = np.ma.masked_equal(cdf,0) #除去直方图中的0值
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())#等同于前面介绍的lut[i] = int(255.0 *p[i])公式
cdf = np.ma.filled(cdf_m,0).astype('uint8') #将掩模处理掉的元素补为0 #计算
result2 = cdf[image]
result = cv2.LUT(image, cdf) cv2.imshow("OpenCVLUT", result)
cv2.imshow("NumPyLUT", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
最终结果
验证
比较查找表和OpenCV直方图均衡化生成的直方图:
可以看出,总体上来看是吻合的,但OpenCV中函数的实现
可能还有一些细微的差别(有空去翻下源码,不过今天就先到这里了)。
参考资料:
1、《Opencv2 Computer Vision Application Programming Cookbook》
2、《OpenCV References Manule》
3、http://opencvpython.blogspot.com/2013/03/histograms-2-histogram-equalization.html
如果觉得本文写的还可以的话,请轻点“顶”,您的支持是我写下去的动力之一。未完待续。。。如有错误请指正,本人会虚心接受并改正!谢谢!
OpenCV-Python教程(10、直方图均衡化)的更多相关文章
- OpenCV Python教程(3、直方图的计算与显示)
转载请详细注明原作者及出处,谢谢! 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途什么的就直接略过去了. ...
- Python实现图像直方图均衡化算法
title: "Python实现图像直方图均衡化算法" date: 2018-06-12T17:10:48+08:00 tags: [""] categorie ...
- opencv python:图像直方图 histogram
直接用matplotlib画出直方图 def plot_demo(image): plt.hist(image.ravel(), 256, [0, 256]) # image.ravel()将图像展开 ...
- OpenCV Python教程(1、图像的载入、显示和保存)
原文地址:http://blog.csdn.net/sunny2038/article/details/9057415 转载请详细注明原作者及出处,谢谢! 本文是OpenCV 2 Computer ...
- OpenCV计算机视觉学习(9)——图像直方图 & 直方图均衡化
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...
- OpenCV-跟我一起学数字图像处理之直方图均衡化
从这篇博文开始,小生正式从一个毫不相干专业转投数字图像处理.废话不多说了,talk is cheap. show me the code. 直方图均衡化目的 由于一些图像灰度的分布过于集中,这样会导致 ...
- 灰度图的直方图均衡化(Histogram Equalization)原理与 Python 实现
原理 直方图均衡化是一种通过使用图像直方图,调整对比度的图像处理方法:通过对图像的强度(intensity)进行某种非线性变换,使得变换后的图像直方图为近似均匀分布,从而,达到提高图像对比度和增强图片 ...
- opencv —— equalizeHist 直方图均衡化实现对比度增强
直方图均匀化简介 从这张未经处理的灰度图可以看出,其灰度集中在非常小的一个范围内.这就导致了图片的强弱对比不强烈. 直方图均衡化的目的,就是把原始的直方图变换为在整个灰度范围(0~255)内均匀分布的 ...
- python实现直方图均衡化,理想高通滤波与高斯低通滤波
写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验二,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验二. 由于时间紧张,代码没有进行任何优化, ...
随机推荐
- OpenJudge Trans
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include ...
- No module named MYSQLdb 问题解决
问题描述: 报错:ImportError: No module named MySQLdb 对于不同的系统和程序有如下的解决方法: easy_install mysql-python (mix os) ...
- java打印菱形的简单方法
代码: public class Diamond { /** * 测试main方法 */ public static void main(String[] args) { printDiamond(1 ...
- Java有用经验总结--Swing篇
Java有用经验总结--Swing篇 前言 本文前言部分为我的一些感想,假设你仅仅对本文介绍的Java有用技巧感兴趣,能够跳过前言直接看正文的内容. 本文的写作动机来源于近期接给人家帮忙写的一个小程序 ...
- CATransform3D参数的意义
经常忘记CATransform3D各参数的意思,记下来好好理解下 struct CATransform3D { CGFloat m11(x缩放),m12(y切变),m13(旋转),m14(); C ...
- ubuntu WiFi: operation not possible due to RF-kill《转载》
Some people have been experiencing WiFi problems with Ubuntu 10.10 since an update that happend just ...
- diffuse linux 文件比对工具
linux下比较好用的可视化文件比对工具
- HEVC测试序列(百度云网盘分享)
巧妇难为无米之炊,身为一个码农怎能碗里没有米呢?想必很多朋友都碰到下载测试序列的困惑,为了减少麻烦,现提供HEVC所有测试序列的下载,上传到百度云网盘上,方便大家下载.主要的测试序列如下: Test ...
- struts1:Struts配置文件初解
struts-config.xml是Struts的核心文件.该文件可配置各种组件,包括,FormBeans,Actions,ActionMappings,全局转发GlobalForwards,数据源D ...
- T - stl 的mapⅡ
Description Ignatius is so lucky that he met a Martian yesterday. But he didn't know the language th ...