OpenCV学习20-直方图反向投影

'''
直方图反向投影是由 Michael J. Swain 和 Dana H. Ballard 在他们的
文章“Indexing via color histograms”中提出。
那它到底是什么呢?它可以用来做图像分割,或者在图像中找寻我们感兴
趣的部分。简单来说,它会输出与输入图像(待搜索)同样大小的图像,其中
的每一个像素值代表了输入图像上对应点属于目标对象的概率。用更简单的话
来解释,输出图像中像素值越高(越白)的点就越可能代表我们要搜索的目标
(在输入图像所在的位置)。这是一个直观的解释。直方图投影经常与 camshift
算法等一起使用。
我们应该怎样来实现这个算法呢?首先我们要为一张包含我们要查找目标
的图像创建直方图(在我们的示例中,我们要查找的是草地,其他的都不要)。
我们要查找的对象要尽量占满这张图像(换句话说,这张图像上最好是有且仅
有我们要查找的对象)。最好使用颜色直方图,因为一个物体的颜色要比它的灰
度能更好的被用来进行图像分割与对象识别。接着我们再把这个颜色直方图投
影到输入图像中寻找我们的目标,也就是找到输入图像中的每一个像素点的像
素值在直方图中对应的概率,这样我们就得到一个概率图像,最后设置适当的
阈值对概率图像进行二值化,就这么简单。
'''

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
import matplotlib

#设置中文字体
matplotlib.rcParams['font.family'] = 'SimHei'

#在messi.jpg图片中取一小块绿色区域,生成green.jpg文件
roi = cv.imread('green.jpg')
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)

#在目标图中寻找绿色
target = cv.imread('messi.jpg')
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)

'''
使用函数 cv2.calcHist() 来计算直方图既简单又方便。如果要绘制颜色
直方图的话,我们首先需要将图像的颜色空间从 BGR 转换到 HSV。(记住,
计算一维直方图,要从 BGR 转换到 HSV)。计算 2D 直方图,函数的参数要
做如下修改:
• channels=[0 ,1] 因为我们需要同时处理 H 和 S 两个通道。
• bins=[180 ,256]H 通道为 180,S 通道为 256。
• range=[0 ,180 ,0 ,256]H 的取值范围在 0 到 180,S的取值范围在0到256。
首先,我们要创建两幅颜色直方图,目标图像的直方图('M'),(待搜索)
输入图像的直方图('I')。
'''
roihist = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )

# 归一化:原始图像,结果图像,映射到结果图像中的最小值,最大值,归一化类型
#cv2.NORM_MINMAX 对数组的所有值进行转化,使它们线性映射到最小值和最大值之间
# 归一化之后的直方图便于显示,归一化之后就成了 0 到 255 之间的数了。
cv.normalize(roihist,roihist,0,255,cv.NORM_MINMAX)
dst = cv.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)

# 此处卷积可以把分散的点连在一起
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5))
cv.filter2D(dst,-1,disc,dst)

# threshold and binary AND
ret,thresh = cv.threshold(dst,50,255,0)
# 别忘了是三通道图像,因此这里使用 merge 变成 3 通道
thresh = cv.merge((thresh,thresh,thresh))
# 按位操作
res = cv.bitwise_and(target,thresh)

plt.subplot(131), plt.imshow(target)
plt.title(u'原图'), plt.xticks([]), plt.yticks([])
plt.subplot(132), plt.imshow(thresh)
plt.title(u'二值化'), plt.xticks([]), plt.yticks([])
plt.subplot(133), plt.imshow(res)
plt.title(u'直方图反向投影'), plt.xticks([]), plt.yticks([])

plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值