OpenCV-Python(22):直方图反向投影

news2024/11/25 7:54:36

引言

        直方图反向投影是一种基于图像颜色分布的图像处理技术,它通过计算图像中不同区域的颜色直方图,并将其与目标区域的直方图进行比较,从而实现目标的识别和分割。本文将介绍直方图反向投影的原理和应用,并探讨其在计算机视觉任务中的重要性。

原理

        直方图反向投影的原理是基于颜色分布的统计学特征。首先,选择感兴趣的目标区域,计算该区域的颜色直方图,得到不同颜色的像素数量。然后,对整个图像计算颜色直方图。接下来,归一化目标区域的直方图和整个图像的直方图,使它们具有相同的尺度。最后,对于每个像素,计算它在归一化目标区域直方图中的概率,并将其映射到图像中,形成反向投影图像。

步骤及应用

直方图反向投影是一种图像处理技术,用于根据图像的颜色分布来识别感兴趣的目标区域。它基于图像的直方图和目标区域的直方图之间的相似性来进行识别。

具体步骤如下:
1.创建目标区域的直方图:首先选择感兴趣的目标区域,然后计算该区域的颜色直方图。颜色直方图是对图像中每个像素的颜色进行统计,得到不同颜色的像素数量。

2.计算整个图像的直方图:对整个图像计算颜色直方图。

3.归一化直方图:将目标区域的直方图和整个图像的直方图进行归一化,使它们具有相同的尺度。

4.计算反向投影图像:对于每个像素,计算它在归一化目标区域直方图中的概率。这可以通过将像素的颜色值映射到直方图的bin来实现。

5.根据反向投影图像进行目标识别:根据反向投影图像的结果,可以使用阈值或其他分割算法来分割出目标区域。

        直方图反向投影在计算机视觉任务中具有广泛的应用。它可以用于图像分割,通过识别目标区域的颜色分布,将目标从背景中分割出来。此外,直方图反向投影还可以用于目标检测和跟踪。通过比较图像中不同区域的颜色分布,可以实现目标的快速检测和准确跟踪。

优势

与传统的基于边缘或纹理的图像处理技术相比,直方图反向投影具有以下优势:

  • 不受光照变化的影响:由于直方图反向投影是基于颜色分布的统计特征,因此它相对于光照变化具有较强的鲁棒性。
  • 简单而高效:直方图反向投影的实现相对简单,计算速度较快,适用于实时应用。
  • 适用性广泛:直方图反向投影可以应用于不同类型的图像,包括自然图像、医学图像和遥感图像等。

Numpy算法实现

        首先,我们需要先创建两幅颜色直方图,待搜索目标图像的直方图'M',输入图像的直方图'I'。

import cv2
import numpy as np
from matplotlib import pyplot as plt
#roi is the object or region of object we need to find
roi = cv2.imread('rose_red.png')
hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)
#target is the image we search in
target = cv2.imread('rose.png')
hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)
# Find the histograms using calcHist. Can be done with np.histogram2d also
M = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
I = cv2.calcHist([hsvt],[0, 1], None, [180, 256], [0, 180, 0, 256] )

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

现在使用一个圆盘算子做卷积B = D × B,其中D 为卷积核。 

disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
B=cv2.filter2D(B,-1,disc)
B = np.uint8(B)
cv2.normalize(B,B,0,255,cv2.NORM_MINMAX)

 现在找出图像中灰度值最大的地方就是我们要查找的目标的位置了。如果我们要找的是一个区域,我们就可以使用一个阈值对图像进行二值化,这样就可以得到一个很好的结果了。

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

OpenCV算法实现 

        OpenCV中使用cv2.calcBackProject()函数用于直方图反向投影实现。它的语法如下:

backProj = cv2.calcBackProject(images, channels, hist, ranges, scale)

参数说明:

  • images:输入图像,可以是单张图像或图像列表。
  • channels:指定用于计算直方图的通道列表。通道的索引从0开始。
  • hist:目标区域的归一化直方图。
  • ranges:每个通道的取值范围。
  • scale:反向投影结果的缩放因子。

返回值:

  • backProj:直方图反向投影结果。

cv2.calcBackProject()函数的原理是通过计算输入图像中每个像素点在归一化直方图中的概率,并将其映射到反向投影图像中。这样,反向投影图像中的每个像素点表示该像素点属于目标区域的概率。使用cv2.calcBackProject()函数时,通常需要先计算目标区域直方图,可以使用cv2.calcHist()函数来计算直方图。然后,通过对输入图像应用cv2.calcBackProject()函数,可以得到反向投影图像。反向投影图像可以用于目标检测、图像分割和跟踪等应用。

需要注意的是,cv2.calcBackProject()函数的输入图像和目标区域的直方图应该具有相同的色彩空间和维度。此外,通常还需要对反向投影图像进行阈值化或二值化处理,以便更好地分割目标区域。

        下面是我使用的一幅图像进行的示例展示。我使用图中蓝色矩形中的区域作为取样对象,再根据这个样本搜索图中所有的类似区域(草地)。

import cv2
import numpy as np
roi = cv2.imread('tar.jpg')
hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)
target = cv2.imread('roi.jpg')
hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)
# calculating object histogram
roihist = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )

cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)
disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
dst=cv2.filter2D(dst,-1,disc)
# threshold and binary AND
ret,thresh = cv2.threshold(dst,50,255,0)

thresh = cv2.merge((thresh,thresh,thresh))
# 按位操作
res = cv2.bitwise_and(target,thresh)
res = np.hstack((target,thresh,res))
cv2.imwrite('res.jpg',res)
# 显示图像
cv2.imshow('1',res)
cv2.waitKey(0)

结论

         直方图反向投影是一种基于颜色分布的图像处理技术,通过计算图像中不同区域的颜色直方图,并将其与目标区域的直方图进行比较,实现目标的识别和分割。它在图像分割、目标检测和跟踪等计算机视觉任务中具有广泛的应用。直方图反向投影相对于传统的图像处理技术具有许多优势,如不受光照变化的影响、简单高效以及适用性广泛。因此,直方图反向投影在计算机视觉领域具有重要的研究和应用价值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1350161.html

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

相关文章

服务器被入侵后如何查询连接IP以及防护措施

目前越来越多的服务器被入侵,以及攻击事件频频的发生,像数据被窃取,数据库被篡改,网站被强制跳转到恶意网站上,网站在百度的快照被劫持等等的攻击症状层出不穷,在这些问题中,如何有效、准确地追…

Java学习苦旅(十七)——栈和队列

本篇博客将详细讲解Java中的栈和队列。 文章目录 栈概念Java中Stack常用方法代码实现 队列概念队列常用方法对比QueueDeque 代码实现Queue 结尾 栈 概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一…

Codeium在IDEA里的3个坑

转载自Codeium在IDEA里的3个坑:无法log in,downloading language server和中文乱码_downloading codeium language server...-CSDN博客文章浏览阅读1.7w次,点赞26次,收藏47次。Codeium安装IDEA插件的3个常见坑_downloading codeiu…

基于ssm鲜花销售管理系统

🍅点赞收藏关注 → 私信领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅项目介绍 随着科学技术的飞速发展…

【Linux常用指令】用户管理

文章目录 Linux系统目录结构Linux用户和用户组用户管理概述用户账号和用户组用户概念用户组概念 Linux用户和组的关系 Linux用户管理添加用户 useradd选项修改用户 usermod用户账号口令管理passwd删除用户 userdel Linux用户组管理添加新组groupadd修改群组groupmod删除群组gro…

2024史上最全的 iOS 各种测试工具集锦!

引言: 随着移动互联网的兴起,APP 测试的越来越被重视!Android 系统因为自己的开源性,测试工具和测试方法比较广为流传,但是 iOS 系统的私密性,导致很多测试的执行都有点麻烦。 为了帮助大家更好的执行 iO…

Sectigo和Certum的区别

为了保护用户在互联网的隐私,网站使用SSL数字证书为http明文传输协议加上安全套接层,对网站传输数据加密。Sectigo和Certum是正规的CA认证机构,它们颁发的SSL证书经过市场认证,已经兼容大多数浏览器以及终端,今天就随S…

【MATLAB】【数字信号处理】线性卷积和抽样定理

已知有限长序列:xk1,2,1,1,0,-3, hk[1,-1,1] , 计算离散卷积和ykxk*h(k) 。 程序如下: function [t,x] My_conv(x1,x2,t1,t2,dt) %文件名与函数名对应 %自写的卷积函数 x conv(x1,x2)*dt; t0 t1(1) t2(1); L length(x1) length(x2)-2; t t0:dt…

提取ROS bag文件中LiDAR点云数据为pcd格式

这段代码是用于从ROS bag文件中提取LiDAR点云数据并保存为PCD格式的。 1. 命令行 rosrun pcl_ros bag_to_pcd 2022-04-21-21-02-29.bag /rslidar_points_32 lidar_points_80_lines 详细解释如下: 1. rosrun pcl_ros bag_to_pcd 这是运行一个ROS节点bag_to_pcd,它来自pcl_r…

使用selenium定位csdn主页的收藏夹文章(含完整Python代码)

目录 前提:准备好流程 第一步 导包 代码 第三方库的下载流程 第二步 设置谷歌浏览器及要打开的网页 第三步 定位元素 代码 元素定位方法 前提:准备好流程 第一步 导包 这里需要提前下载好第三方库:selenium,time。代码及…

python多线程同步:Event对象

1.python事件Event相关函数介绍 set() — 全局内置标志Flag,将标志Flag 设置为 True,通知在等待状态(wait)的线程恢复运行 isSet() — 获取标志Flag当前状态,返回True 或者 False wait() — 一旦调用,线程将会处于阻塞状态,直到…

【Leetcode 80】删除排序数组中的重复项 II ——双指针

80. 删除排序数组中的重复项 II 给你一个有序数组nums,请你原地删除重复出现的元素,使得出现次数超过两次的元素只出现两次,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在原地 修改输入数组并在使用 O(1) 额外空间…

VC++ ado 实现单表CURD

继续修改前文的资产管理源码; 新建一个数据库sds;把代码中的数据库连接改为连接此库; 新建下图一个表; 把之前的资产类别管理对话框改为下图所示;对话框ID也改为下图; 资产类别管理菜单和ID改为下图; 直接修改资产类别管理对话框类不太方便,新建一个对话框类,没有关联…

vue3基础知识一,安装及使用

一、安装vue3 需要安装node,然后在项目所在目录命令行执行以下代码。 npm create vuelatest 回车后需要配置以下内容。 二、安装所需的依赖包并运行 cd到项目目录,执行以下代码安装依赖包 npm i 运行项目 npm run dev 打开浏览器查看结果 ok&#…

携手罗振宇,泸州老窖用“眼前一亮”的方式开启全新700年

执笔 | 洪大大 编辑 | 萧 萧 又一段故事拉开帷幕,又一个品牌扣人心弦。 2023年12月31日跨年夜,由深圳卫视、得到APP联合出品的“时间的朋友”跨年演讲在深圳春茧体育馆正式开讲,现场,罗振宇用一段段睿智的话语与一个个鲜明的故…

系统架构设计面试指南(02)-MQ和文件存储

点击下方“JavaEdge”,选择“设为星标” 第一时间关注技术干货! 免责声明~ 任何文章不要过度深思! 万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案…

Go语言module,依赖管理方法

Go语言module,依赖管理方法 1.为什么需要依赖管理2.module管理配置流程打开go module配置一个国内的代理创建go.modGo Modules下的go get行为 3.GO env的其他配置GOSUMDBGONOPROXY/GONOSUMDB/GOPRIVATE 4.go.mod和go.sum概述5.Go Modules的语义化版本控制6.Go Modul…

Vue3-27-路由-路径参数的简单使用

什么是路径参数 在路由配置中,可以将【参数】放在【路由路径】中, 从而实现,同一个 路由,同一个组件,因路径参数不同,可以渲染出不同的内容。特点 : 1、当携带不同路径参数的路由相互跳转时&am…

Jupyter Notebook的10个常用扩展介绍

Jupyter Notebook(前身为IPython Notebook)是一种开源的交互式计算和数据可视化的工具,广泛用于数据科学、机器学习、科学研究和教育等领域。它提供了一个基于Web的界面,允许用户创建和共享文档,这些文档包含实时代码、…

关于解决引用第三方依赖突然失效的问题解决办法

目录 背景回顾解决办法结果 背景 出现该问题的背景是这样的。在项目中需要支持加载pdf文档的功能。所以采取了使用第三方PDF库的方法来实现加载pdf文档。集成完后,功能是正常的。后来过了一段时间,发现加载pdf的功能不能正常使用了,加载不出…