直方图反向投影
直方图反向投影可以用来做图像分割,或者在图像中找寻我们感兴趣的部分。简单来说,它会输出与输入图像(待搜索)同样大小的图像,其中的每一个像素值代表了输入图像上对应点属于目标对象的概率。用更简单的话来解释,输出图像中像素值越高(越白)的点就越可能代表我们要搜索的目标 (在输入图像所在的位置)。
opencv中使用函数 cv2.calcBackProject()直接实现反向投影,同样再使用目标的直方图做反向投影之前我们应该先对其做归一化处理。返回的结果是一个概率图像,我们再使用一个圆盘形卷积核对其做卷操作,最后使用阈值进行二值化。
函数原型:cv2.calcBackProjection(images, channels, hist, ranges, scale, dst)
参数说明:
(1)images:输入图像
(2)channels:用于计算反向投影的通道列表,通道数必须与直方图维度相匹配
(3)hist:输入的直方图,直方图的bin可以是密集(dense)或稀疏(sparse)
(4)ranges:直方图中每个维度bin的取值范围
(5)scale:可选输出反向投影的比例因子
(6)dst:目标图像
代码奉上:
# 直方图反向投影
# HSV与RGB色彩空间
# 反向投影
import cv2
import numpy as np
from matplotlib import pyplot as plt
#import matplotlib.pyplot as plt
def histo2d_demo(image): #2d直方图的制作与显示
hsv =cv2.cvtColor(image,cv2.COLOR_BGR2HSV) #BGR转HSV
hist=cv2.calcHist([image], [0,1], None, [180,256], [0, 180, 0, 256]) #图像直方图获取
# cv2.imshow("image_hist",hist)
plt.imshow(hist, interpolation='nearest') #直方图的显示
plt.title("2d")
plt.show()
def back_projection_demo(): #直方图反向投影的生成
sample=cv2.imread("lena_1.jpg")
target=cv2.imread("lena.jpg")
roi_hsv=cv2.cvtColor(sample,cv2.COLOR_BGR2HSV) #感兴趣区域转HSV
target_hsv=cv2.cvtColor(target, cv2.COLOR_BGR2HSV) #目标图像转HSV
#show image
cv2.imshow("sample",sample)
cv2.imshow("target",target)
roiHist=cv2.calcHist([roi_hsv], [0,1], None, [30, 40], [0,180, 0,256])#绘制感兴趣区域的直方图
cv2.normalize(roiHist,roiHist,0,255,cv2.NORM_MINMAX) #进行图片的归一化
dst=cv2.calcBackProject(target,[0,1],roiHist,[0,180, 0,256],1)
cv2.imshow("back_projection_demo",dst)
print("---------")
# src=cv2.imread("dwaii.png")
# cv2.imshow("source_image",src)
# histo2d_demo(src)
back_projection_demo()
cv2.waitKey(0)
cv2.destroyAllWindows()