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

news2024/7/30 8:25:00

目录

    • 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之间。

现在看看下面的代码:

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())。

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直方图。这可以让我们更好地了解不同的像素密度。但是,这也不能让我们在第一眼就知道是什么颜色,除非你知道不同颜色的色相值。但我还是喜欢这种方法。它既简单又好。

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

看一下代码:

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”)的颜色直方图。

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]。

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是圆盘的核。

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

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

OpenCV中的反投影

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

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.coloradmin.cn/o/565901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端新员工入职,需要为你的新电脑安装一些环境,开发工具

目录 一.先安装个谷歌浏览器,稳定版。 二.安装公司日常交流软件 三.安装个VSCode 四.安装nvm 五.vue-cli的安装和配置 六.安装git 配置git账号 拉取线上仓库到本地 一些常用git命令 七.其他工具 网络抓包工具:whistle 反向代理工具&#xff1…

雪花算法记录

引子 伴随着业务的日渐庞大,单库单表的数据库可能无法支持业务的读写,需要对数据库进行分库分表。 原来数据库中,通常使用自增id的方式生成主键。分库分表之后,如果仍然采用原来的方式,在多个表之间主键会发生重复。 …

斑梨电子树莓派Zero 2W显示屏7寸DIY电容触摸屏RJ45 USB HUB接口 兼容Banana pi Zero

spotpear.cn/index/product/detail/id/1320.html detail.tmall.com/item.htm?id719583990252&spma211lz.success.0.0.63982b90oweBSa 【产品简介】 为了让你的Zero正常工作,你需要很多模块,如一个显示器,一个USB HUB,一个…

Java StringBuilder类

3 StringBuilder可变字符串类 StringBuilder是一个可变的字符串类,内容可以改变3.1 StringBuilder构造方法 范例public class Demo {public static void main(String[] args) {//创建空白可

chatgpt赋能python:Pythonspidev简介

Python spidev简介 Python spidev是一个可以与SPI设备进行通信的Python库。SPI是一种简单的通信协议,通常用于与单片机或其他嵌入式设备进行通信。Python spidev库可以使用SPI协议读写数据,然后与其他设备交换数据。 开发环境和使用方法 开发环境 Py…

如何把视频中的声音提取出来转化成文字?

在观看电影、综艺节目等视频内容时,我们可以使用视频转文字的方法来帮助我们更好地了解对话内容,从而提高观影体验。那么,如何把视频声音转成文字?视频声音转成文字的软件有哪些呢?我给你介绍几个非常好用的视频声音转…

PCL学习之点云重建

1:点云模型重建 离散点云 • 数据量大 • 渲染显示大 • 模型操作计算不方便 网格模型 • 数据量小 • 渲染方便 • 模型操作计算方便 重建步骤 2:凸包算法 凸包 • 平面凸包:平面的一个子集S被称为是“ 凸”的,当且仅当对于任…

【Netty】ChannelPipeline源码分析(五)

文章目录 前言一、ChannelPipeline 接口1.1 创建 ChannelPipeline1.2 ChannelPipeline 事件传输机制1.2.1 处理出站事件1.2.2 处理入站事件 二、ChannelPipeline 中的 ChannelHandler三、ChannelHandlerContext 接口3.1 ChannelHandlerContext 与其他组件的关系3.2 跳过某些 Ch…

tcp拥塞控制

序列号: 在TCP连接中传送的字节流中的每一个字节都按顺序编号。该字段表明发送数据的第一个字节的序号 确认号:希望收到对方下一个报文的第一个字节的序号 窗口:用于通知发送端,接收端可以接收的空间大小 TCP的流量控制是使用滑动窗口机制&…

C4d Octane渲染器内存满、卡顿、崩溃、缓慢、updating解决办法

最近碰到Octane渲染动画序列,总是会渲染一段时间后卡在某一张图片上,图片查看器左下角一直显示updating。 偶然发现在C4D界面点击octane工具栏的设置,它又会开始渲染,但渲染一些序列帧后又会卡在一张图上显示updating 点击octane工…

MyBatis-Plus01_简介、入门案例、BaseMapper与IService中的CRUD以及常用的注解

目录 ①. MyBatis-plus简介 ②. MyBatis-plus入门案例 ③. BaseMapper中的CRUD ④. 通用Service的CRUD ⑤. MyBatis-plus中常用注解TableName: ⑥. 常用注解TableId ⑦. 雪花算法 ⑧常用注解TableField ⑨. 常用注解TableLogic——逻辑删除专用注解 ①. M…

chatgpt赋能python:PythonUDS:让你的汽车掌握更多技能

Python UDS:让你的汽车掌握更多技能 UDS(Unified Diagnostic Services)是一种汽车电子控制单元(ECU)通信协议,用于车辆的诊断和测试。Python UDS是用Python编程语言实现的UDS客户端和服务器实现&#xff0…

【stable diffusion保姆级教程,左手ChatGPT之剑,右手stablediffusion之矛】

一、前言 哈喽,大家好,我是Tian-Feng,前面写过两篇文章,但是细节没认真写,除了介绍一些参数意思,和推荐模型插件,有一定基础的小伙伴应该是挺有用的,但如果是小白,可能还…

完全二叉树——堆的概念及实现

前言 堆(heap):是堆内存的简称,堆是动态分配内存,内存大小不固定,也不会自动释放,堆——数据结构是一种无序的树状结构,同时它还满足key-value键值对的存储方式。 1. 堆的概念及结构 如果有一个关键码的…

BFC与IFC

概念 块级元素在BFC布局(块级格式化上下文) 行内级元素在IFC布局(行内级格式化上下文) BFC 形成BFC的情况 BFC规则 在BFC中box在垂直方向排列在同一个BFC中,相邻box垂直方向外边距塌陷在BFC中box左边缘紧贴包含块的…

Python数据结构与算法篇(十五)-- 二叉树的遍历:深度优先搜索与广度优先搜索

本篇开始总结二叉树的常用解题技巧,二叉树的顺序遍历和层序遍历刚好对应深度优先搜索和广度优先搜索。 1 顺序遍历 题目列表 144. 前序遍历145. 二叉树的后序遍历 94. 二叉树的中序遍历 144. 二叉树的前序遍历 给你二叉树的根节点 root ,返回它…

程序员开发之“留一手“

很多乙方公司为了顺利获得项目的尾款,或者有些项目的封装整合的逻辑比较多,通常会把项目的业务逻辑代码及架构进行打包成线上NuGet包。 一、 NuGet包 其实就是线上的.dll文件 ,在本地编译后上传是NuGet 1、首先注册NuGet 2、记住API Key …

chatgpt赋能python:Python*a:提高代码效率的利器

Python *a:提高代码效率的利器 Python是一种高层次、通用性编程语言。Python的简洁语法和宽松语义,让它成为了软件开发、数据分析、科学计算等领域的首选语言之一。Python也因其易学、易读、易部署的特点而被全球越来越多的开发者所喜爱。在这篇文章中&…

Redis事务及网络处理

一 Redis事务 redis开启事务后,会把接下来的所有命令缓存到一个单独的队列中,在提交事务时,使这些命令不可被分割的一起执行完成。 如果使用了watch命令监视某一个key,如果在开启事务之后,提交事务之前,有…

超级牛散也踩雷!这A股宣布大消息

公司被债权人申请重整一事被法院正式立案7个多月后,5月24日,*ST搜特收到了法院的终结预重整程序通知书和不予受理重整申请裁定书。 消息曝出后,*ST搜特股吧则瞬间炸锅,投资者纷纷留言“完了”、“没盼头了”、“最后的希望终究还…