Opencv第十四章 进阶篇之图像直方图

图像直方图的绘制

图像直方图的绘制是用来统计图像中不同像素值出现的数量,下面向大家展示一下相关的代码:

img = cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg',0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist.shape

首先读入目标图像,0表示对图像进行灰度处理,转化为灰度图像输出。

[img]是将目标图像传入函数,

[0]表示的是图像的channel,用中括号括,如果是灰度图就是[0],如果是彩色图就是[0],[1],[2],根据传入的对应的BGR来定。

None对应的是不加掩膜图像,如果不加掩膜图像则为None,如果加掩膜图像则替换为mask。

[256]表示的是Bin的数目

[0,256]表示的是像素值范围

最后我们来输出一下直方图的参数

 256表示一共用256个bin,1表示每个bin的宽度为1

plt.hist(img.ravel(),256);
plt.show()

 接着用plt输出直方图

我们这样就得到了相应的直方图。

接下来我们来输入彩色图进行一下直方图的输出。

#一定要输入彩色图
img = cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg')
color = ('b','g','r')

for i,col in enumerate(color):
    histr = cv2.calcHist([img],[i],None,[256],[0,256])
    plt.plot(histr,color = col)
    plt.xlim([0,256])

for函数是对三个通道进行遍历

i 是颜色通道的索引,按照b,g,r的顺序索引相应的颜色通道

 下面我们来查看一下plt的输出结果:

直方图绘制完成后,发现有的区域像素较为聚集,为了解决此问题,我们需要对直方图进行一系列的处理。

直方图的均衡化处理

#直方图的均衡化:
img = cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg',0)
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256);
plt.show()

以上便是对图像直方图进行均衡化处理的公式,直接套公式即可。

下面我们来看一下输出的图像

我们发现图像直方图变得分布不在过于聚集,达到了直方图均衡化的效果。

均衡化以后,图像会丢失部分细节:

向大家展示一下效果图:

 

自适应均衡化

#均衡化的缺点:会丢失一些细节
#解决方法:可以把图分为不同的小块,分别进行均衡化处理

解决方法的代码如下:

clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
res_clahe = clahe.apply((img))
res= np.hstack((img,equ,res_clahe))
cv_show(res,'res')

 自适应均衡化的公式给定如上,不需要对其原理进行进一步的了解

 自适应化得到的结果与原图和和均衡化的对比图展示如下:

 我们不难发现,自适应均衡化不仅提高了图片的亮度,而且还较大程度的保留了原有的数据细节。

mask掩膜图像

上文已经有提到掩膜图像,下面向大家介绍一下什么是掩膜图像。

所谓掩膜图像,就是设立一个矩阵,在选定部分为一,未选定部分为零,然后用该矩阵乘以原有图像的矩阵,得到的结果未框选的部分变为0,即变为黑色。图像仅保留被框选的部分。

下面向大家展示一下相关的代码:

#创建mask
#第一步是固定格式。2是选取的颜色通道
mask=np.zeros(img.shape[:2],np.uint8)
#设定该范围内的图像为白色,故使范围内等于255
mask[0:900,100:2000] = 255
def cv_show(mask,name):
    cv2.imshow(name,mask)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    #cv_show(mask,'mask')
img=cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg',0)

masked_img = cv2.bitwise_and(img,img,mask = mask)#与操作,将两个矩阵相乘
hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(221),plt.imshow(img,'gray')
plt.subplot(222),plt.imshow(mask,'gray')
plt.subplot(223),plt.imshow(masked_img,'gray')
plt.subplot(224),plt.plot(hist_full),plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()

效果图展示如下:

我们不难发现,所框选的区域越大,得到的直方图就越接近于原图的直方图。

关于直方图的介绍就这么多,下一张向大家介绍傅里叶变换。 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值