- 1. 学习如何在你的电脑上配置OpenCV-Python环境!
- 1.1 开始了解OpenCV-Python
- 1.2 在 Windows 下安装 OpenCV-Python
- 1.3 在 Fedora 环境下安装 OpenCV-Python
- 1.4 在 Debian(Ubuntu)中配置 OpenCV-Python
- 1.5 在Docker中安装OpenCV-Python
- 1.6 在树莓派配置OpenCV-Python
- 2. OpenCV中的GUI功能
- 2.1 开始使用图像
- 2.2 开始使用视频
- 2.3 OpenCV 中的绘图函数
- 2.4 以鼠标为画笔
- 2.5 用滑块控制条做调色板
- 3. OpenCV中的GUI功能
- 3.1 图片基本操作
- 3.2 图像算术操作
- 3.3 性能评估与改进技巧
- 4. OpenCV中的图像处理
- 4.1 更换颜色空间
- 4.2 对图像进行几何变换
- 4.3 图像二值化处理
- 4.4 平滑图像
- 4.5 形态学转换
- 4.6 图像梯度
- 4.7 Canny边缘检测
- 4.8 图像金字塔
- 4.9.1 直方图:查找,绘制,分析
- 4.9.2 直方图均衡化
- 4.9.3 二维直方图
- 4.9.4 直方图反投影
- 4.10 OpenCV中的图像变换
- 4.10.1 傅立叶变换
- 4.11 模板匹配
- 4.12 霍夫直线变换
- 4.13 霍夫圆变换
- 4.14 基于分水岭算法的图像分割
- 4.14 使用 GrabCut 算法交互式前景提取
- 5. 特征检测和描述符
- 5.1 理解特征
- 5.2 Harris 角点检测
- 5.3 Shi-Tomasi 角点检测 & 适合用来跟踪的特征
- 5.4 介绍SIFT(尺度不变特征转换)
- 5.5 介绍SURF(加速稳健特征)
- 5.6 角点检测的FAST算法
- 5.7 BRIEF特征点描述算法
- 5.8 ORB 特征描述符(Oriented FAST and Rotated BRIEF)
- 5.9 特征匹配
- 5.10 特征匹配和使用单应性匹配来搜索物体
- 6. 视频分析
- 6.1 Meanshift和Camshift
- 6.2 光流
- 6.3 背景分割
- 7. 相机校准和3D重建
- 7.1 相机校准
- 7.2 姿势估计
- 7.3 极线几何
- 7.4 来自立体图像的深度图
- 8. 机器学习
- 8.1 K-最近邻算法
- 8.1.1 了解k-最近邻算法
- 8.1.2 使用kNN进行手写字符的OCR
- 8.2 支持向量机(SVM)
- 8.2.1 理解SVM
- 8.2.2 使用SVM的手写数据的OCR
- 8.3 K-Means聚类
- 8.3.1 理解 K-Means 聚类
- 8.3.2 OpenCV中的K-Means聚类
- 9. 计算摄影学
- 9.1 图像去噪
- 9.2 图像修复
- 9.3 高动态范围(HDR)
- 10. 目标检测
- 10.1 使用 Haar Cascades 的面部识别
- 11. OpenCV-Python 绑定
- 11.1 OpenCV-Python绑定如何工作?
4.9.4 直方图反投影
目标
在本章中,我们将学习直方图反投影。
理论
它由 Michael J. Swain,Dana H. Ballard 在他们的论文《Indexing via color histograms》中提出。
用简单的话来说它是什么?
它用于图像分割或查找图像中感兴趣的对象。简而言之,它会创建与我们的输入图像相同大小(但为单个通道)的图像,其中每个像素对应于该像素属于我们对象的概率。用更简单的话说,在输出的图像中,与其余的部分相比,我们感兴趣的对象更白。这是一个直观的解释。 (我不能使它更简单了)。直方图反投影常常与camshift算法等一起使用。
我们该怎么做呢 ?
我们创建一个包含我们感兴趣的对象(在我们的例子中,这个对象是地面,而不是运动员或其他东西)的图像直方图。对象应尽可能填充图像以获得更好的效果。颜色直方图比灰度直方图更受欢迎,因为对象的颜色是定义对象的一种比其灰度强度更好的方法。然后我们在测试图像上“反投影”这个直方图,在那里我们需要找到对象,换句话说,我们计算每个像素属于地面的概率并显示出来。在适当的阈值下产生的输出将会为我们挑出地面。
用 Numpy 实现的算法
首先,我们需要计算我们需要找到的对象(称它是 M)和我们要搜索的图像(称它为 I)的颜色直方图。
import cv2
import numpy as np
from matplotlib import pyplot as plt
# roi是我们要寻找的对象或要寻找对象的区域
roi = cv2.imread('rose_red.png')
hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)
# target是我们要在其中寻找对象的图片
target = cv2.imread('rose.png')
hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)
# 使用calcHist计算出直方图。也可以使用np.histogram2d
M = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
I = cv2.calcHist([hsvt],[0, 1], None, [180, 256], [0, 180, 0, 256] )
找到比率 $R = \frac {M} {I}$。然后,反向投影 R,即使用 R 作为调色板,并以每个像素作为其相应的目标概率来创建新的图像。即 $B(x,y)=R[h(x,y),s(x,y)]$,其中 h 是色相,s 是 (x,y) 处像素的饱和度。之后,应用条件 $B(x,y)= min [B(x,y),1]$。
h,s,v = cv2.split(hsvt)
B = R[h.ravel(),s.ravel()]
B = np.minimum(B,1)
B = B.reshape(hsvt.shape[:2])
现在应用圆形卷积,$B = D \ast B$,其中 D 是卷积核。
disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
cv2.filter2D(B,-1,disc,B)
B = np.uint8(B)
cv2.normalize(B,B,0,255,cv2.NORM_MINMAX)
现在最大亮度的位置给出了我们物体的位置。如果我们想要的图像中的一个区域,以合适的值进行二值化将会给出了很好的结果。
ret,thresh = cv2.threshold(B,50,255,0)
就是这样。
OpenCV 中的反投影
OpenCV 提供了一个内置函数 cv2.calcBackProject()
。它的参数几乎和 cv2.calcHist()
函数相同。其中一个参数是直方图,它是要寻找对象的直方图,我们必须自己找到它。另外,在传递给反投影函数之前,对象直方图应该被归一化。它返回概率图像。然后,我们用圆形内核卷积图像并二值化。下面是我的代码和输出:
import cv2
import numpy as np
roi = cv2.imread('rose_red.png')
hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)
target = cv2.imread('rose.png')
hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)
# 计算对象的直方图
roihist = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
# 直方图均衡化,并应用backprojection
cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)
# 使用圆形内核卷积
disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
cv2.filter2D(dst,-1,disc,dst)
# 二值化,按位与
ret,thresh = cv2.threshold(dst,50,255,0)
thresh = cv2.merge((thresh,thresh,thresh))
res = cv2.bitwise_and(target,thresh)
res = np.vstack((target,thresh,res))
cv2.imwrite('res.jpg',res)
更多资源
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论