Python与机器视觉(x) 颜色直方图
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用
cv2包是著名的视觉库OpenCV的Python实现
颜色直方图一般用于统计图片不同通道像素强度的分布,并可以基于此来实现对比度提升、以及简单的目标识别、跟踪以及分割等任务。在openCV中集成了函数cv2.calcHist()
来实现直方图的计算。
函数定义如下:
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) → hist
其中images
可为单张或多张图像的array
channels
为要计算的通道数
mask
为图像掩膜
histSize
为直方图的柱子数量,即将数据分布在多少个区间上计数
range
为直方图取值范围
hist
为返回值,不用填
accumulate
多张图的时候是否叠加
所以一般调用的时候只需要填上面四个参数,掩膜为None,范围0.0-255.0,数量255个:
hist = cv2.calcHist(img, [0], None,[256], [0.0,255.0])
1. 看一个例子
import cv2
import numpy as np
import matplotlib.pyplot as plt#读入灰度图像并显示(imread用0参数)
img = cv2.imread('img.jpeg',0)
cv2.imshow('img',img)
cv2.waitKey()
cv2.destroyAllWindows()
img from pexels.com
接下来计算其像素亮度分布的直方图,在0~255范围内分为255级来计算
hist_255 = cv2.calcHist([img],[0], None, [256], [0.0,255.0]) #灰度图只有一个通道,通道0
#注意,img一定要加[],使其变成三维,否则则会使用第一维进行计算,即不加中括号会计算img[0,:]的直方分布print('histrogram shape is',hist_255.shape)
plt.plot(hist_255,'gray')
plt.title('Histrogram of gray image')
plt.show()
Output: ‘histrogram shape is’, (256L, 1L)
可以看到这幅灰度图,其亮度集中在250附近,这是由于有大片的天空呈现白色,而暗区的峰值则来源于较暗的山体。
2.看第二个例子
我们读入彩色图,并将rgb通道的颜色直方图分别画出来:
img = cv2.imread('img.jpeg')cv2.imshow('img',img)
cv2.waitKey()
cv2.destroyAllWindows()
我们对三个通道分别遍历求直方图,注意opencv中的颜色是按照b,g,r顺序的。
color = ['blue','springgreen','red'] #稍微调整显示颜色,提高可视化效果
for i in [0,1,2]:hist = cv2.calcHist([img],[0], None, [256], [0.0,255.0]) #彩色图有三个通道,通道b:0,g:1,r:2plt.plot(hist, color[i])plt.title('Histrogram of Color image')
plt.show()
可以看到在低亮度区域红色比较多,对应了图中上体的反光和云彩的颜色。
可以改变区间分割的数量来得到更为平滑或者稠密的分布曲线:
color = ['blue','springgreen','red'] #稍微调整显示颜色,提高可视化效果
for i in [0,1,2]:hist = cv2.calcHist([img],[i], None, [64], [0.0,256.0]) #用64端区间来统计0~256的灰度分布plt.plot(hist, color[i])plt.title('Histrogram of Color image')
plt.show()
为了直观的查看每个通道的质量,我们画出各个通道的图像来与直方图对比:
#画出各个通道查看,opencv中为bgr顺序
img_b = img.copy();img_b[:,:,2] = 0;img_b[:,:,1] = 0
img_g = img.copy();img_g[:,:,2] = 0;img_g[:,:,0] = 0
img_r = img.copy();img_r[:,:,0] = 0;img_r[:,:,1] = 0#转为rgb显示
plt.figure(figsize=(10,30))
plt.subplot(1,3,1)
plt.imshow(cv2.cvtColor(img_r,cv2.COLOR_BGR2RGB)) #r
plt.title('red')
plt.subplot(1,3,2)
plt.imshow(cv2.cvtColor(img_g,cv2.COLOR_BGR2RGB)) #g
plt.title('green')
plt.subplot(1,3,3)
plt.imshow(cv2.cvtColor(img_b,cv2.COLOR_BGR2RGB)) #b
plt.title('blue')
plt.show()
可以与上图的直方图相比较。
3.直方图均衡
有的时候我们需要调整图像的对比度,让整幅图在各个取值区间的像素数变得更加均衡,就需要利用上面计算出的直方图进行直方图均衡。OpenCV中主要利用cv2.equalizeHist()
来实现。
import cv2
import numpy as np
import matplotlib.pyplot as pltimg2= cv2.imread('img2.jpeg')
# img from:https://www.pexels.com/photo/white-yacht-on-body-of-water-under-bridge-1529625/
cv2.imshow('img',img2)
cv2.waitKey()
cv2.destroyAllWindows()
可以看到这幅图的暗部和亮部分对比度不够好,每一部分像素分布过于集中了,在直方图中更为明显:
equal_hist_255 = cv2.calcHist([img2],[0], None, [256], [0.0,256.0]) #灰度图只有一个通道,通道0
print('histrogram shape is',hist_255.shape)
plt.plot(hist_255,'gray')
plt.title('Histrogram of gray image')
plt.show()
下面我们进行直方图均衡化,然后查看对比度修正的结果:
img_equal = cv2.equalizeHist(img2)
hist_255_equal = cv2.calcHist([img_equal],[0], None, [256], [0.0,256.0]) #灰度图只有一个通道,通道0
print('histrogram shape is',hist_255.shape)plt.figure(figsize=(20,20))
plt.subplot(2,2,1)
plt.imshow(img2,'gray')
plt.title('source')
plt.subplot(2,2,2)
plt.imshow(img_equal,'gray')
plt.title('histrogram equilized')
plt.subplot(2,2,3)
plt.plot(hist_255,'gray')
plt.title('Histrogram of gray image')
plt.subplot(2,2,4)
plt.plot(hist_255_equal,'gray')
plt.title('Histrogram of equalized image')
plt.show()
可以看到修正后的直方图分布更均匀,对比度也比原来好了很多,更能看清暗处的部分了。
让我们再来看看彩色图:
img2_color = cv2.imread('img2.jpeg') #读入彩色图img2_color_equl = img2_color.copy()
#需要按通道分别均衡化
img2_color_equl[:,:,0] = cv2.equalizeHist(img2_color[:,:,0])
img2_color_equl[:,:,1] = cv2.equalizeHist(img2_color[:,:,1])
img2_color_equl[:,:,2] = cv2.equalizeHist(img2_color[:,:,2])plt.figure(figsize=(20,10))
plt.subplot(2,2,1)
plt.imshow(cv2.cvtColor(img2_color,cv2.COLOR_BGR2RGB))
plt.title('source')
plt.subplot(2,2,2)
plt.imshow(cv2.cvtColor(img2_color_equl,cv2.COLOR_BGR2RGB))
plt.title('Histrogram of equalized image')plt.subplot(2,2,3)
for i in [0,1,2]:hist = cv2.calcHist([img2_color],[i], None, [255], [0.0,256.0]) #彩色图三通道plt.plot(hist, color[i])plt.title('Histrogram of Color image')
plt.subplot(2,2,4)
for i in [0,1,2]:hist = cv2.calcHist([img2_color_equl],[i], None, [255], [0.0,256.0]) #彩色图plt.plot(hist, color[i])plt.title('Histrogram of equalized Color image')
plt.show()
对比度有很大改观,但是颜色产生了一定的失真。
上面一种均衡化是针对全局进行调节,但可以看到某些地方发生了失真。这时候就需要利用自适应直方图均衡。opencv中提供了限制对比度自适应直方图均衡(Contrast Limited Adaptive Histogram Equalization,CLAHE),其函数为cv2.createCLAHE(clipLimit=2,tileGridSize=(10,10))
。它将图像中的区域分块来进行处理,其中包含两个参数,clipLimit
为限制阈值,tileGridSize
为区域的大小。
img3_color = cv2.imread('img.jpg') #读入彩色图img3_color_equl = img3_color.copy()
#创建均化方法
clahe = cv2.createCLAHE(clipLimit=2,tileGridSize=(20,20))
#按通道分别局部均衡化
img3_color_equl[:,:,0] = clahe.apply(img3_color[:,:,0])
img3_color_equl[:,:,1] = clahe.apply(img3_color[:,:,1])
img3_color_equl[:,:,2] = clahe.apply(img3_color[:,:,2])plt.figure(figsize=(20,10))
plt.subplot(2,2,1)
plt.imshow(cv2.cvtColor(img3_color,cv2.COLOR_BGR2RGB))
plt.title('source')
plt.subplot(2,2,2)
plt.imshow(cv2.cvtColor(img3_color_equl,cv2.COLOR_BGR2RGB))
plt.title('Histrogram of Adaptive equalized image')
plt.subplot(2,2,3)
for i in [0,1,2]:hist = cv2.calcHist([img3_color],[i], None, [255], [0.0,256.0]) #灰度图只有一个通道,通道0plt.plot(hist, color[i])plt.title('Histrogram of Color image')
plt.subplot(2,2,4)
for i in [0,1,2]:hist = cv2.calcHist([img3_color_equl],[i], None, [255], [0.0,256.0]) #灰度图只有一个通道,通道0plt.plot(hist, color[i])plt.title('Histrogram of Adaptive equalized Color image')
plt.show()
可以看到直方图比前述方法的变得更为缓和,更为均匀的分布在了各个灰度值上。
pic from pexels.com
ref:
Doc:https://docs.opencv.org/2.4/modules/imgproc/doc/histograms.html?highlight=hist
Tutorial:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/table_of_content_imgproc/table_of_content_imgproc.html
blog1
blog2
createCLahe
Clahe
Clahe algorithm
Python与机器视觉(x) 颜色直方图相关推荐
- python画不同颜色的直方图_Python与机器视觉(x) 颜色直方图
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用 cv2包是著名的视觉库OpenCV的Python实现 颜色直方图一般用于统计图片不同通道像素强度的分布,并可以基于此来实现对比度提升. ...
- Python+opencv 机器视觉 - 基于霍夫圈变换算法检测图像中的圆形实例演示
Python+opencv 机器视觉 - 基于霍夫圈变换算法检测图像中的圆形实例演示 第一章:霍夫变换检测圆 ① 实例演示1 ② 实例演示2 ③ 霍夫变换函数解析 第二章:Python + openc ...
- Python与机器视觉(x)下雨啦,图片模拟雨天效果
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用 cv2包是著名的视觉库OpenCV的Python实现 在opencv中,可以利用随机噪声.滤波器等方法为图像叠加仿真的雨滴的运动轨迹, ...
- Python与机器视觉(x)图像差分-图像相减
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用 cv2包是著名的视觉库OpenCV的Python实现 在求峰值信噪比PSNR时,我们需要求取目标图像和实际图像之间的误差. err = ...
- Python与机器视觉(x)图像修复
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用 cv2包是著名的视觉库OpenCV的Python实现 图像修复 很多时候遇到受损的图片我们需要利用机器视觉的手段对其进行修复,open ...
- Python与机器视觉(三)图像保存
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用 cv2包是著名的视觉库OpenCV的Python实现 在对图片进行一定的操作后,我们需要将图像保存在对应的位置,cv2提供了imwri ...
- Python与机器视觉(二)读入图片并显示
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用 cv2包是著名的视觉库OpenCV的Python实现 1.读入图像并显示 import cv2 #导入opencv包img = cv2 ...
- Python与机器视觉(一)安装与环境
本系列博客主要分享Python在机器视觉/计算机视觉下的编程应用 cv2包是著名的视觉库OpenCV的Python实现 1.安装 在安装过python环境后,可以使用apt-get工具或者pip工具来 ...
- python适合机器视觉_Python机器视觉编程常用数据结构与示例
本文总结了使用Python进行机器视觉(图像处理)编程时常用的数据结构,主要包括以下内容: 数据结构 序列操作:索引(indexing).分片(slicing).加(adding).乘(multipy ...
最新文章
- mac 配置 php,mac如何配置php环境
- laravel实现读写分离
- 给初学编程的人的干货
- C语言在建筑专业的应用,新工科背景下基于OBE的《C语言程序设计》课程建设
- WCF(五) 深入理解绑定
- C#中yield return用法
- 【LeetCode笔记】146. LRU缓存机制(Java、双向链表、哈希表)
- Linux内核(5) - 内核学习的相关资源
- 《统计学习方法》代码全解析——第十一部分条件随机场
- 苹果和谷歌在印度下架数十款中国应用;贾跃亭宣布破产重组完成;Tails 4.8 发布| 极客头条...
- Enterprise Library 1.0
- Maven搭建SpringMVC+Hibernate项目详解
- 【渝粤教育】电大中专电商运营实操 (14)作业 题库
- 利用 Python 读写文本内容
- 给软件添加鼠标右键快捷方式
- 113.输入10个国家的名字,按由小到大排序
- java获取视频第一帧工具类
- 3D打印成型成型原理有哪些?性价比高的教学3D打印机如何选购?
- 电路元器件3——TVS:
- 在thinkphp框架中如何对多表进行操作(thinkphp多表查询方法)
热门文章
- python opencv 实现从一个文件夹中读取图片做切割处理后放入另一个文件夹
- jQuery-动画与特效
- Ubuntu系统显卡驱动、CUDA、CUDNN安装(二CUDA和CUDNN)
- 跨域 · 后台设置:头部header(服务器端添加属性、属性值,浏览器端获取属性及其值) - 数据篇
- matlab相位连续显示,matlab设计复合信号不同频率的初相位
- sip 时序图_简单几步让你看懂单片机时序图
- XyPlayer 智能解析 X4 影视解析源码
- Atlantis Lite蓝色精品后台管理系统模板
- golang的一款cms内容管理系统
- Android8有深度休眠吗,IMX8MQ android休眠功耗过大