python opencv 直方图均衡_OpenCV-Python教程(10、直方图均衡化)
相比C++而言,Python适合做原型。本系列的文章介绍如何在Python中用OpenCV图形库,以及与C++调用相应OpenCV函数的不同之处。这篇文章介绍在Python中使用OpenCV和NumPy对直方图进行均衡化处理。
提示:
转载请详细注明原作者及出处,谢谢!
本文不介详细的理论知识,读者可从其他资料中获取相应的背景知识。笔者推荐清华大学出版社的《 》,对于本节的内容,建议直接参考 维基百科直方图均衡化 ,只需看下页面最后的两幅图就能懂了。
本文内容:
使用查找表拉伸直方图
使用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 = binNobreak#计算从右起第一个不为0的直方图位置for binNo, binValue in enumerate(reversed(hist)): if binValue != 0:maxBinNo = 255-binNobreakprint minBinNo, maxBinNo#生成查找表,方法来自参考文献1第四章第2节for i,v in enumerate(lut):print iif i < minBinNo:lut[i] = 0elif i > maxBinNo:lut[i] = 255else:lut[i] = int(255.0*(i-minBinNo)/(maxBinNo-minBinNo)+0.5)
查询表创建完成后,就直接调用相应的OpenCV函数即可,这里调用的是cv2.LUT函数:#计算result = cv2.LUT(image, lut)
cv2.LUT函数只有两个参数,分别为输入图像和查找表,其返回处理的结果,完整代码如下:
#coding=utf-8import cv2import numpy as npimage = 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 = binNobreak#计算从右起第一个不为0的直方图柱的位置for binNo, binValue in enumerate(reversed(hist)): if binValue != 0:maxBinNo = 255-binNobreakprint minBinNo, maxBinNo#生成查找表,方法来自参考文献1第四章第2节for i,v in enumerate(lut):print iif i < minBinNo:lut[i] = 0elif i > maxBinNo:lut[i] = 255else: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-8import cv2import numpy as npimage = 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》
如果觉得本文写的还可以的话,请轻点“顶”,您的支持是我写下去的动力之一。未完待续。。。如有错误请指正,本人会虚心接受并改正!谢谢!欢迎加入我爱机器学习QQ14群:336582044
微信扫一扫,关注我爱机器学习公众号
python opencv 直方图均衡_OpenCV-Python教程(10、直方图均衡化)相关推荐
- Python+OpenCV:图像对比度受限自适应直方图均衡化(CLAHE, Contrast Limited Adaptive Histogram Equalization)
Python+OpenCV:图像对比度受限自适应直方图均衡化(CLAHE, Contrast Limited Adaptive Histogram Equalization) ############ ...
- Python OpenCV学习笔记之:图像直方图均衡化
# -*- coding: utf-8 -*- """ 图像直方图均衡化 """ import cv2 import numpy as np ...
- vs python opencv配置_OPENCV入门教程二:opencv+VS2015开发环境配置
在该cpp文件中输入一下代码 #include #include #include #include #include using namespace cv; using namespace std; ...
- python opencv 摄像头_opencv python中摄像头参数的设置
我正在使用Windows7 64位操作系统以及Python3和OpenCV.我的电脑连接到以下型号的两个罗技网络摄像头: 1)罗技高清网络摄像头C615 2) 罗技QuickCam Pro 9000 ...
- python opencv保存图片_OpenCV Python 保存图片
By 凌顺 2019年9月12日 本示例使用的OpenCV版本是:4.1.1 运行Python的编辑器:Jupyter notebook 示例目的 通过无损和有损的方式进行图片保存. 实现代码 1,加 ...
- Python+Opencv图像处理新手入门教程(二):颜色空间转换,图像大小调整,灰度直方图
一步一步来吧 上一节:Python+Opencv图像处理新手入门教程(一):介绍,安装与起步 1.什么是图像 对于计算机而言,图像的本质是一个由像素点构成的矩阵. 例如我们用肉眼很容易分辨一辆汽车的后 ...
- Python+Opencv图像处理新手入门教程(三):阈值与二值化
一步一步来吧 上一节: Python+Opencv图像处理新手入门教程(二):颜色空间转换,图像大小调整,灰度直方图 1.Intro 今天这节我们主要研究利用阈值处理图像.例如对于输入图像: 如何做一 ...
- python做直方图-python OpenCV学习笔记实现二维直方图
本文介绍了python OpenCV学习笔记实现二维直方图,分享给大家,具体如下: 官方文档 – https://docs.opencv.org/3.4.0/dd/d0d/tutorial_py_2d ...
- Python+Opencv图像处理新手入门教程(四):视频内容的读取与导出
一步一步来吧 上一节: Python+Opencv图像处理新手入门教程(三):阈值与二值化 1.Intro 今天这节我们主要看怎么利用opencv读取并处理视频中的内容. 2.VideoCapture ...
- 【OpenCV 例程200篇】46. 直方图均衡化
[OpenCV 例程200篇]46. 直方图均衡化 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 图像直方图是反映图 ...
最新文章
- Access外键 级联更新、删除
- 【scala初学】scala 控制 for while match if
- 枣庄三中高考2021成绩查询,2021枣庄中考成绩查询系统入口
- Linux怎么更新镜像,利用 Zsync 更新已有的 Ubuntu ISO 镜像
- java word转html 乱码 poi,java word转html poi
- 20个正则表达式必知(前端开发)
- 监听程序当前无法识别连接符中请求的服务_[Servlet] 18 监听器
- 理论应用实例水杯_PLC应用,3个PID控制实例讲解,想不会都难!
- Android快速批量打渠道包(AndroidManifestModifier)
- 商品包含资源和劳动两部分内容
- python随机出题_什么软件可以自制题库随机出题?怎么操作
- linux下kegg注释软件,KEGG pathway注释过程
- 什么是云服务和云服务端开发?
- 基于CH340G的STC单片机一键下载电路
- 洛谷P2178 [NOI2015]品酒大会 后缀数组+单调栈
- 对话系统调查:近期进展与新前沿
- Python心形图-采用turtle模块画心形
- 5个值得关注的L1公链
- EMI-EMC设计注意事项
- 已搭建独立博客,请移步下面网址
热门文章
- 阿里云IoT投入智物智造战略 三年赋能10亿设备改造10万家数字工厂
- FreeNAS 简介
- Settings Preference 的理解
- Unix/Linux下的Curses库开发指南——第一章 Curses库开发简介
- java中的持有引用
- python地产成本_Python3抓取 深圳房地产均价数据,通过真实数据为购置不动产做决策分析(二)...
- web项目打war包方法 两步解决(极其简单方便)
- 渗透测试-越权漏洞之垂直越权和水平越权
- 区块链入门者的五本必读书籍
- LNK1181:无法打开输入文件“release/.obj“