OpenCV中的图像处理3.10(九)二维直方图与反投影

news/2024/7/21 4:56:16 标签: opencv, 图像处理, python, 计算机视觉, 人工智能

目录

    • 3.10.3 直方图--3:二维直方图
      • 目标
      • 绪论
      • OpenCV中的二维直方图
      • Numpy中的2D直方图
      • 绘制二维直方图
    • 3.10.4 直方图 - 4:直方图反投影
      • 目标
      • 理论
      • Numpy中的算法
      • OpenCV中的反投影
      • 其他资源

翻译及二次校对:cvtutorials.com

编辑者:廿瓶鲸(和鲸社区Siby团队成员)

3.10.3 直方图–3:二维直方图

目标

在本章中,我们将学习如何寻找和绘制二维直方图。它对后面的章节会有帮助。

绪论

在第一篇文章中,我们计算并绘制了一维直方图。它之所以被称为一维,是因为我们只考虑了一个特征,即像素的灰度灰度值。但在二维直方图中,你要考虑两个特征。通常情况下,它被用于寻找颜色直方图,其中两个特征是每个像素的色调和饱和度值。

已经有一个python样本(samples/python/color_histogram.py)用于寻找颜色直方图。我们将尝试理解如何创建这样的颜色直方图,这对理解直方图反投影等进一步的主题很有用。

OpenCV中的二维直方图

它非常简单,使用同一个函数cv.calcHist()来计算。对于颜色直方图,我们需要将图像从BGR转换为HSV。(记住,对于一维直方图,我们从BGR转换为灰度)。) 对于二维直方图,其参数将被修改如下。

  • channels = [0,1] 因为我们需要同时处理H和S平面。
  • bins = [180,256] 180用于H平面,256用于S平面。
  • range = [0,180,0,256] 色调值在0到180之间,饱和度在0到256之间。

现在看看下面的代码:

python">import numpy as np
import cv2 as cv
img = cv.imread('home.jpg')
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])

Numpy中的2D直方图

Numpy还提供了一个专门的函数:np.histogram2d()。(记住,对于一维直方图,我们使用np.histogram())。

python">import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('home.jpg')
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])

第一个参数是H面,第二个是S面,第三个是bin数,第四个是范围。

现在我们可以检查如何绘制这个颜色直方图。

绘制二维直方图

方法-1:使用cv.imshow()

我们得到的结果是一个大小为180x256的二维数组。所以我们可以像平时那样,用cv.imshow()函数来显示它们。这将是一个灰度图像,除非你知道不同颜色的色相值,否则它不会让人知道有哪些颜色。

方法-2:使用Matplotlib

我们可以使用matplotlib.pyplot.imshow()函数来绘制带有不同颜色图谱的2D直方图。这可以让我们更好地了解不同的像素密度。但是,这也不能让我们在第一眼就知道是什么颜色,除非你知道不同颜色的色相值。但我还是喜欢这种方法。它既简单又好。

注意:在使用这个函数时,请记住,为了得到更好的结果,插值标志应该是最近的。

看一下代码:

python">import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('home.jpg')
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
hist = cv.calcHist( [hsv], [0, 1], None, [180, 256], [0, 180, 0, 256] )
plt.imshow(hist,interpolation = 'nearest')
plt.show()

下面是输入的图像和它的颜色直方图图谱。X轴显示S值,Y轴显示色调。

Image Name

在直方图中,你可以看到H=100和S=200附近的一些高值。它与天空的蓝色相对应。同样地,在H=25和S=100附近可以看到另一个峰值。它对应的是宫殿的黄色。你可以用任何图像编辑工具如GIMP来验证它。

方法3:OpenCV的样本风格

在OpenCV-Python2样本(samples/python/color_histogram.py)中,有一个颜色直方图的示例代码。如果你运行该代码,你可以看到直方图也显示了相应的颜色。或者简单地说,它输出了一个彩色编码的直方图。它的效果非常好(尽管你需要额外增加一堆行)。

在那段代码中,作者用HSV创建了一个颜色图。然后将其转换为BGR。得到的直方图图像与这个颜色图相乘。他还使用了一些预处理步骤来去除孤立的小像素,从而得到了一个好的直方图。

我把它留给读者,让他们去运行这段代码,分析它,思考它。下面是该代码对上述相同图像的输出。

Image Name

你可以在直方图中清楚地看到哪些颜色是存在的,蓝色是存在的,黄色是存在的,还有一些由于棋盘造成的白色是存在的。

3.10.4 直方图 - 4:直方图反投影

目标

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

理论

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

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

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

Numpy中的算法

1.首先,我们需要计算我们需要寻找的对象(让它成为 “M”)和我们要搜索的图像(让它成为 “I”)的颜色直方图。

python">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] )

2.找到比率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]。

python">h,s,v = cv.split(hsvt)
B = R[h.ravel(),s.ravel()]
B = np.minimum(B,1)
B = B.reshape(hsvt.shape[:2])

3.现在应用一个圆盘的卷积,B=D∗B,其中D是圆盘的核。

python">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)

4.现在,最大灰度的位置给了我们物体的位置。如果我们要在图像中寻找一个区域,对一个合适的值进行阈值处理会得到一个很好的结果。

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

OpenCV中的反投影

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

python">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)

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

Image Name

其他资源

  • “Indexing via color histograms”, Swain, Michael J. , Third international conference on computer vision,1990.

http://www.niftyadmin.cn/n/357356.html

相关文章

MyBatis 框架

MyBatis 框架 MyBatis 简介搭建 MyBatis 开发环境核心配置文件详解mapper 映射文件(实现增删改查)MyBatis获取参数值的两种方式MyBatis的各种查询功能特殊SQL的执行自定义映射resultMapresultMap 字段和属性的映射多对一映射处理一对多映射处理 动态SQLM…

python绘制密度图

本期目录 1、绘图参数2、使用 matplotlib 库绘制密度图时常用的参数3、案例4、 运行结果python绘图往期系列文章目录 1、绘图参数 可以使用多种库来绘制密度图,其中最常用的是 seaborn 和 matplotlib。以下是使用 seaborn 库绘制密度图时常用的参数: i…

chatgpt赋能python:Python实现Word合并

Python实现Word合并 在日常工作和生活中,我们经常需要处理Word文档。有一种情况是需要将多个Word文档合并成一个,并且保留原有的格式和样式。这个时候,Python就派上用场了。 Word文档的结构 在了解怎样合并多个Word文档之前,我…

chatgpt赋能python:PythonWMI:掌握Windows管理工具的关键

Python WMI: 掌握Windows管理工具的关键 在Windows系统上,WMI (Windows Management Instrumentation)是一个无价的管理工具,允许用户监控和管理各种Windows组件,包括硬件、操作系统,和应用程序。在Python编程中,通过使…

SpringCloudAlibaba:继解决登录问题之后,Sentinel持久化没有效果问题

说实话好麻烦,每次使用关于Nacos的时候,bootstrap.yaml中都得配置username和password。 我后悔了。。。 哪位大哥有好办法啊!!! 因为之前开启登录鉴权,导致使用Nacos就得配username和password&#xff0c…

淘宝/天猫商品评论数据采集

淘宝商品评论API接口是指允许开发者通过API接口获取淘宝商品的评价信息的一种技术手段。通过使用这个接口,开发者可以快速获取淘宝商品的评价信息,以实现自己的商业用途。 淘宝商品评论API接口需要开发者提供相应的数据访问权限,包括授权和Ap…

代理模式 静态代理 JDK动态代理 Cglib动态代理

1.静态代理 总共只有两个类,代理类和被代理类。其中代理类是被代理类的增强和扩展 被代理的类C和代理类B都要实现同一个接口 代理类B中调用代理类C中相同的方法 interface D {public void function1(); }class C implements D {Overridepublic void function1(…

图像滤波概述

什么是图像滤波 1.图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。 2.消除图像中的噪声成分叫作图像的平滑化或滤波操…