坐看云起时|

一枚码农

园龄:7年6个月粉丝:5关注:1

opencv-python 4.10.4. 反投影直方图

理论

它由Michael J. Swain,Dana H. Ballard在他们的论文“Indexing via color histograms”中提出。

用简单的话来说,它到底是什么?它用于图像分割或查找图像中感兴趣的对象。简单地说,它创建了与输入图像大小相同(但是是单一通道)的图像,其中每个像素对应于该像素属于对象的概率。在更简单的世界中,输出的图像将使我们感兴趣的对象与其余部分相比有更多的白色。这是一个直观的解释。(我说得再简单不过了)。直方图反投影与camshift算法等相结合。我们怎么做呢?我们创建一个an的直方图

我们怎么做呢?我们创建一个图像的直方图,其中包含我们感兴趣的对象(在我们的例子中是地面、离开玩家和其他东西)。对象应该尽可能地填充图像,以获得更好的结果。与灰度直方图相比,颜色直方图更受欢迎,因为与灰度强度相比,对象的颜色是一种更好的定义对象的方法。然后我们将这个直方图“向后投射”到我们需要找到目标的测试图像上,换句话说,我们计算出属于地面的每个像素的概率并显示出来。在适当的阈值上得到的输出只给我们提供了基础

以下算法运用我们将使用下边两张图片,我们将在被搜索的图像cow 上查找对象 cow_roi。
image

Numpy中的算法

首先,我们需要计算需要找到的对象(设为“M”)和要搜索的图像(设为“I”)的颜色直方图。

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('cow_roi.png')
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)

#target is the image we search in
target = cv.imread('cow.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] )

求出比率 $$ 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)
B = R[h.ravel(),s.ravel()]
B = np.minimum(B,1)
B = B.reshape(hsvt.shape[: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)

现在最大强度的位置为我们提供了物体的位置。 如果我们期望图像中有一个区域,那么对适当值进行阈值处理会得到很好的结果。

ret,thresh = cv.threshold(B,50,255,0)

OpenCV中的反投影

OpenCV提供了一个内置函数cv.calcBackProject()。 它的参数与cv.calcHist()函数几乎相同。 它的一个参数是直方图,它是对象的直方图,我们必须找到它。 此外,在传递给backproject函数之前,应该对象直方图进行规范化。 它返回概率图像。 然后我们将图像与光盘卷积核卷积并应用阈值。 以下是我的代码和输出:
cv.calcBackProject(images,channels,hist,ranges,scale[,dst])->dst

  • images:输入图像,是一个图像集合,可以是包含多通道彩色图像的list或tuple,也可以是多个灰度图组成的list或者tuple;list或tuple形式的输入
  • channels:根据images确定,指明要用images里的哪个通道号,根据images的形式确定;list或tuple形式的输入;
  • hist:输入直方图;
  • ranges:图像元素取值的范围;包含2个元素的list或tuple;
  • scale:缩放比例;
  • dst:目标图像,单通道,和images[0]同样的尺寸和depth ;

其中入参images、channels、ranges参数用法同calcHist()。
入参hist是特征图像(roi)的的直方图,使用它在源图像中查找该特征。

import cv2 as cv
from matplotlib import pyplot as plt

cow = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\cow.jpg')
cow_roi = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\cow_roi.jpg')

hsv_cow = cv.cvtColor(cow, cv.COLOR_BGR2HSV)
hsv_cow_roi = cv.cvtColor(cow_roi, cv.COLOR_BGR2HSV)

# 计算特征图像直方图
hist_roi = cv.calcHist([hsv_cow_roi], [0, 1], None, [180, 256], [0, 180, 0, 256])
cv.normalize(hist_roi, hist_roi, 0, 255, cv.NORM_MINMAX)
# 计算反投影
img_back = cv.calcBackProject([hsv_cow], [0, 1], hist_roi, [0, 180, 0, 256], 2)

# 二值化和叠加
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
img_dest = cv.filter2D(img_back, -1, disc)
ret, thresh = cv.threshold(img_dest, 30, 255, 0)
thresh = cv.merge((thresh, thresh, thresh))
img_merge = cv.bitwise_and(cow, thresh)

# 绘图
fig, ax = plt.subplots(1, 4)
ax[0].set_title('cow')
ax[0].imshow(cv.cvtColor(cow, cv.COLOR_BGR2RGB))
ax[1].set_title('cow_roi')
ax[1].imshow(cv.cvtColor(cow_roi, cv.COLOR_BGR2RGB))
ax[2].set_title('img_back')
ax[2].imshow(img_back, 'gray')
ax[3].set_title('img_merge')
ax[3].imshow(cv.cvtColor(img_merge, cv.COLOR_BGR2RGB))
plt.show()

image

本文作者:一枚码农

本文链接:https://www.cnblogs.com/yimeimanong/p/17285485.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   一枚码农  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
 
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Sold Out Hawk
  2. 2 光辉岁月 Beyond
Sold Out - Hawk
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : Jon Steingard

作曲 : Jon Steingard

I ain't like no one you met before

I'm running for the front

When they're all running for the door

And I won't sit down won't back out

You can't ever shut me up

Cause I'm on a mission

And I won't quit now

In a world full of followers

I'll be a leader

In a world full of doubters

I'll be a believer

I'm stepping out without a hesitation

Because the battle's already been won

I'm sold out

I'm no longer living

Just for myself

Running after Jesus

With my whole heart

And now I'm ready to show

I am sold out

I'm sold out

With every single

Step that I take now

With every drop of blood

Left in my veins

I'm gonna be making it count

I am sold out

This ain't just some temporary phase

You can't face this kind of grace

And leave the way you came

This is permanent with intent

And there won't be no stopping it now

I'm on a mission and it's heaven sent

In a world full of followers

I'll be a leader

In a world full of doubters

I'll be a believer

I'm stepping out without a hesitation

Cause my soul is like a stadium

I'm sold out

I'm no longer living

Just for myself

Running after Jesus

With my whole heart

And now I'm ready to shout

I am sold out

I'm sold out

With every single

Step that I take now

With every drop of blood

Left in my veins

I'm gonna be making it count

I am sold out

No trials coming against me

Could put a dent in my passion

They're just an opportunity

To put my faith into action

In a world full of followers

I'll be a leader

In a world full of doubters

I'll be a believer

I'm stepping out without a hesitation

I ain't got nothing left to be afraid of

I'm sold out

I'm no longer living

Just for myself

Running after Jesus

With my whole heart

And now I'm ready to show

I am sold out

I'm sold out

With every single

Step that I take now

With every drop of blood

Left in my veins

I'm gonna be making it count

I am sold out