写点什么

图像直方图反向投影,Python OpenCV 取经之旅第 28 天

发布于: 2021 年 07 月 09 日

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。


基础知识铺垫


通过直方图的反向投影,可以在图像 A 中查找特定的图像 B,一般情况下图像 A 比较大,图像 B 比较小或者图像 B 只有 1 个像素。


可以查找到最匹配的区域图像或者像素点。


翻译的理论一些就是,定位模板图像在输入图像中的位置。


在翻译成白话,就是计算图像为某一特征的直方图模型,然后使用模型去寻找图像中存在的该特征。


如果深究下去,图像的反向投影涉及的数学知识点也非常多,不过,取经之旅初期,咱们不深究这些内容。

cv2.calcBackProject 函数

在 Python OpenCV 中提供了一个用于实现反向投影的函数 <kbd>cv2.calcBackProject</kbd> 。


下面我们具体学习一下该函数如何使用。

函数原型说明

dst = cv2.calcBackProject(images, channels, hist, ranges, scale[, dst])
复制代码


参数说明如下:


  • <kbd>images</kbd> :输入图像,注意加 []

  • <kbd>channels</kbd>:通道,通道数必须与直方图维度相匹配,

  • <kbd>hist</kbd>:图象的直方图;

  • <kbd>ranges</kbd>:直方图的变化范围;

  • <kbd>scale</kbd>:输出反投影的可选比例因子。


案例 Demo 如下:


import cv2 as cvfrom matplotlib import pyplot as plt
def back_projection_demo(): # 读取图片 test = cv.imread("test1.jpg") target = cv.imread("target.jpeg") # 转换为 HSV 格式 roi_hsv = cv.cvtColor(test, cv.COLOR_BGR2HSV) target_hsv = cv.cvtColor(target, cv.COLOR_BGR2HSV)
cv.imshow("sample", test) cv.imshow("target", target)
# 计算直方图 roiHist = cv.calcHist([roi_hsv], [0, 1], None, [64, 64], [0, 180, 0, 256]) # 获取直方图的反向投影 dst = cv.calcBackProject([target_hsv], [0, 1], roiHist, [0, 180, 0, 256], 1) cv.imshow("back_projection_demo", dst)
back_projection_demo()cv.waitKey(0)
cv.destroyAllWindows()
复制代码


先看一下运行效果。



不过这个效果实在不是很理想,为了获取到更精确的值,我增加了一个滑动条。


修改代码成如下这个样子。


import cv2 as cvfrom matplotlib import pyplot as plt
winName = 'getTrackbarPos'# 新建窗口cv.namedWindow(winName, cv.WINDOW_NORMAL)
def nothing(): pass
cv.createTrackbar('hue', winName, 60, 180, nothing)cv.createTrackbar('sat', winName, 60, 256, nothing)
def back_projection_demo(): # 读取图片 test = cv.imread("test1.jpg") # 转换为 HSV 格式 roi_hsv = cv.cvtColor(test, cv.COLOR_BGR2HSV)
target = cv.imread("target.jpeg") target_hsv = cv.cvtColor(target, cv.COLOR_BGR2HSV)
cv.imshow("sample", test) cv.imshow("target", target) while(1): # 从滑动条读取数据 hue = cv.getTrackbarPos('hue', winName) sat = cv.getTrackbarPos('sat', winName)
# 计算直方图 roiHist = cv.calcHist([roi_hsv], [0, 1], None, [ hue, sat], [0, 180, 0, 256])
# 获取直方图的反向投影 dst = cv.calcBackProject([target_hsv], [0, 1], roiHist, [0, 180, 0, 256], 1) cv.imshow(winName, dst) if cv.waitKey(1) == ord('q'): break
back_projection_demo()cv.destroyAllWindows()
复制代码



反复调整之后,发现直方图反向投影,除了给橡皮擦增加一个函数认知外,并没有产生过多的思考,可能学习的还不够深入,总之把这个函数收入脑中,日后再次出现的时候,我们拿出来在品味一下。


补充一下官方说明地址:点击查阅

橡皮擦的小节

希望今天的 1 个小时,你有所收获,我们下篇博客见~


发布于: 2021 年 07 月 09 日阅读数: 6
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
图像直方图反向投影,Python OpenCV 取经之旅第 28 天