前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >opencv(4.5.3)-python(二十六)--直方图反投影

opencv(4.5.3)-python(二十六)--直方图反投影

作者头像
用户9875047
发布2023-02-26 15:14:14
2970
发布2023-02-26 15:14:14
举报
文章被收录于专栏:机器视觉全栈er

翻译及二次校对:cvtutorials.com

目标

在本章中,我们将学习直方图反投影的知识。

理论

它是由Michael J. Swain和Dana H. Ballard在他们的论文中提出的,通过颜色直方图进行索引。

简单地说,它到底是什么?它用于图像分割或寻找图像中感兴趣的对象。简单地说,它创建了一个与我们的输入图像相同大小(但为单通道)的图像,其中每个像素对应于该像素属于我们的对象的概率。用更简单的话说,输出的图像与其余部分相比,我们感兴趣的对象会有更多的白色。好吧,这就是一个直观的解释。直方图反投影是与camshift算法等一起使用的。

我们怎么做呢?我们创建一个包含我们感兴趣的对象(在我们的例子中,地面、离开的球员和其他东西)的图像的直方图。为了获得更好的效果,物体应该尽可能地填满图像。彩色直方图比灰度直方图更受欢迎,因为物体的颜色比其灰度更能定义物体。然后,我们在需要寻找物体的测试图像上 "反推 "这个直方图,即换句话说,我们计算每个像素属于地面的概率并显示出来。适当的阈值处理后的输出结果单独给了我们地面的信息。

Numpy中的算法

  1. 1. 首先,我们需要计算我们需要寻找的对象(让它成为 "M")和我们要搜索的图像(让它成为 "I")的颜色直方图。
代码语言:javascript
复制
import numpy as np
import cv2 as cvfrom matplotlib import pyplot as plt
#roi is the object or region of object we need to find
roi = cv.imread('rose_red.png')
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)
#target is the image we search in
target = cv.imread('rose.png')
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)
# Find the histograms using calcHist. Can be done with np.histogram2d also
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] )
  1. 1. 找到比率R=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) B = R[h.ravel(),s.ravel()] B = np.minimum(B,1) B = B.reshape(hsvt.shape[:2])
  2. 2. 现在应用一个圆盘的卷积,B=D∗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)
  3. 3. 现在,最大灰度的位置给了我们物体的位置。如果我们要在图像中寻找一个区域,对一个合适的值进行阈值处理会得到一个很好的结果。ret,thresh = cv.threshold(B,50,255,0)

OpenCV中的反投影

OpenCV提供了一个内置的函数cv.calcBackproject()。它的参数与cv.calcHist()函数几乎相同。它的一个参数是直方图,这是对象的直方图,我们必须找到它。另外,在传递给backproject函数之前,对象的直方图应该被归一化。它返回的是概率图像。然后我们用圆盘核对图像进行卷积,并应用阈值。下面是我的代码和输出。

代码语言:javascript
复制
import numpy as np
import cv2 as cv
roi = cv.imread('rose_red.png')
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)
target = cv.imread('rose.png')
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)
# calculating object histogram
roihist = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
# normalize histogram and apply backprojection
cv.normalize(roihist,roihist,0,255,cv.NORM_MINMAX)
dst = cv.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)
# Now convolute with circular disc
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)
thresh = cv.merge((thresh,thresh,thresh))
res = cv.bitwise_and(target,thresh)
res = np.vstack((target,thresh,res))
cv.imwrite('res.jpg',res)

下面是我处理的一个例子。我把蓝色矩形内的区域作为样本对象,我想提取整个地面。

其他资源

  • • "Indexing via color histograms", Swain, Michael J. , Third international conference on computer vision,1990.
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器视觉全栈er 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档