【python opencv】直方图反投影
这是由Michael J. Swain和Dana H. Ballard在他们的论文《通过颜色直方图索引》中提出的。
用简单的话说是什么意思?它用于图像分割或在图像中查找感兴趣的对象。简而言之,它创建的图像大小与输入图像相同(但只有一个通道),其中每个像素对应于该像素属于我们物体的概率。用更简单的话来说,与其余部分相比,输出图像将在可能有对象的区域具有更多的白色值。好吧,这是一个直观的解释。(我无法使其更简单)。直方图反投影与camshift算法等配合使用。
我们该怎么做呢?我们创建一个图像的直方图,其中包含我们感兴趣的对象(在我们的示例中是背景等)。对象应尽可能填充图像以获得更好的效果。而且颜色直方图比灰度直方图更可取,因为对象的颜色对比灰度强度是定义对象的好方法。然后,我们将该直方图“反投影”到需要找到对象的测试图像上,换句话说,我们计算出属于背景的每个像素的概率并将其显示出来。在适当的阈值下产生的输出使我们仅获得背景。
Numpy中的算法
- 首先,我们需要计算我们要查找的对象(使其为“ M”)和要搜索的图像(使其为“ I”)的颜色直方图。
#roi是我们需要找到的对象或对象区域
roi = cv.imread('梅西_roi.png')
cv2_imshow(roi)
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)
#目标是我们搜索的图像
target = cv.imread('梅西.jpg')
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)
# 使用calcHist查找直方图。也可以使用np.histogram2d完成
M = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
I = cv.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 = cv.split(hsvt)
R=M/I
B = R[h.ravel(),s.ravel()]
B = np.minimum(B,1)
B = B.reshape(hsvt.shape[:2])
- 现在对圆盘应用卷积,B = D ast B,其中D是圆盘内核。
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5))
cv.filter2D(B,-1,disc,B)
B = np.uint8(B)
cv.normalize(B,B,0,255,cv.NORM_MINMAX)
- 现在最大强度的位置给了我们物体的位置。如果我们期望图像中有一个区域,则对合适的值进行阈值处理将获得不错的结果
ret,thresh = cv.threshold(B,50,255,0)
原始图像:
roi图像:
处理之后:
OpenCV的反投影
OpenCV提供了一个内建的函数cv.calcBackProject()。它的参数几乎与cv.calchist()函数相同。它的一个参数是直方图,也就是物体的直方图,我们必须找到它。另外,在传递给backproject函数之前,应该对对象直方图进行归一化。它返回概率图像。然后我们用圆盘内核对图像进行卷积并应用阈值。下面是我的代码和结果:
import numpy as np
import cv2 as cv
from google.colab.patches import cv2_imshow
roi = cv.imread('梅西_roi.png')
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)
target = cv.imread('梅西.jpg')
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)
# 计算对象的直方图
roihist = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
# 直方图归一化并利用反传算法
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)
# 应用阈值作与操作
ret,thresh = cv.threshold(dst,50,255,0)
thresh = cv.merge((thresh,thresh,thresh))
res = cv.bitwise_and(target,thresh)
res = np.vstack((target,thresh,res))
cv2_imshow(res)
结果:
附加资源
- "Indexing via color histograms", Swain, Michael J. , Third international conference on computer vision,1990.
参考:
http://woshicver.com/FifthSection/4_10_4_%E7%9B%B4%E6%96%B9%E5%9B%BE-4%EF%BC%9A%E7%9B%B4%E6%96%B9%E5%9B%BE%E5%8F%8D%E6%8A%95%E5%BD%B1/
- 【专知-关关的刷题日记19】Leetcode 118. Pascal's Triangle
- 每周学点大数据 | No.3算法设计与分析理论
- HDU 1874 畅通工程续【Floyd算法实现】
- 接口测试 | 21 基于flask弄个restful API服务出来
- 数论部分第二节:埃拉托斯特尼筛法 埃拉托斯特尼筛法
- [接口测试 -基础篇] 20 用flask写一个简单server用于接口测试
- 接口测试 | urllib篇 19 urllib基本示例
- 接口测试 | urllib篇 18 urllib介绍
- 【专知-Deeplearning4j深度学习教程01】分布式Java开源深度学习框架DL4j安装使用: 图文+代码
- .Net Core Runtime安装说明
- 【专知-Deeplearning4j深度学习教程02】用ND4J自己动手实现RBM: 图文+代码
- 【专知-Deeplearning4j深度学习教程03】使用多层神经网络分类MNIST数据集:图文+代码
- TypeScript 1.6发布:完全支持React/JSX
- 【专知-Java Deeplearning4j深度学习教程04】使用CNN进行文本分类:图文+代码
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法