python+OpenCV反投影图像的实现示例详解

2025-05-07 15:50

本文主要是介绍python+OpenCV反投影图像的实现示例详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《python+OpenCV反投影图像的实现示例详解》:本文主要介绍python+OpenCV反投影图像的实现示例详解,本文通过实例代码图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧...

一、前言

如果对直方图或者直方图均衡化的概念比较模糊的话,建议先了解直方图的基本原理及概念:

python+OpenCv笔记(十二):直方图(灰度直方图、掩膜的应用、直方图均衡化、自适应直方图均衡化)

二、什么是反投影图像

我们先不谈反投影图像抽象的概念,可以先用示例做一个简单且清晰的了解:

    1.    

例如,现在有一张手掌的图片,我们对其进行直方图绘制(假设bins设置为4),如图:

python+OpenCV反投影图像的实现示例详解

python+OpenCV反投影图像的实现示例详解

这是之前做过的一个示例,而且很容易理解,直方图中清晰地展示了如果将灰度0~255划分为4个区间(bins),那么这张手掌灰度图按照这4个区间划分都有多少个像素点,这就是图像到直方图的一个过程。

反投影图像恰恰是这一步的逆过程,即通过直方图又生成了一张图像,但生成的图像只有4种颜色(即直方图有多少个bins,生成的反投影图像就有多少种颜色),比如说原图中某一块区域的灰度值都在0到20php这个区间内,如果bins=4,那么反投影图像中那一块区域的颜色是同一种颜色。

并且,一个bins(区间)内像素越多,在反投影图js像中呈现出的颜色就越亮,反之越暗。

现在,我们设置bins=12,在代码中运行的结果如下:

归一化后的直方图:

python+OpenCV反投影图像的实现示例详解

 反投影图像:

python+OpenCV反投影图像的实现示例详解

 由上面可知,反投影图像由12种灰度值组成,且落在同一个区间内的像素值越多,那么反投影后原区域就会越亮,比如整个手掌部分由于灰度值接近,且像素很多,那么反投影后手掌部分就会变得很亮,像素点很少的bins反投影后甚至会呈现黑色。

(注:由于示例原因,直方图中很多bins的像素点数为0,所以反投影后的图像看起来不像是由12种灰度值组成,其实是因为那些区间并不存在像素点)

    2.    

但是,反投影图像更常见的用途是查找特征,在meanshift算法中会用到。

比如说我们现在有模板图像以及生成的模板图像的直方图(见上),我们需要在原图像中用上面的结果来检测特征,先看一下结果:

在原图像中反投影后:

python+OpenCV反投影图像的实现示例详解

 可以看到,一个手掌已经被清晰地展现了出来。

使用统计学的语言, 新图像中储存的数值代表了测试图像中该像素属于皮肤区域的 概率 。比如以上图为例, 亮起的区域是皮肤区域的概率更大(事实确实如此),而更暗的区域则表示更低的概率(注意手掌内部和边缘的阴影影响了检测的精度)。

这其中涉及backproject算法,具体算法以及流程可以阅读后文。

 总结:

原图像————直方图————反投影图像

三、反投影图像的概念

现在,我们可以理解一下反投影图像的抽象概念:

  • 反向投影是一种记录给定图像中的像素点如何适应直方图模型像素分布的方式。
  • 简单的讲, 所谓反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的该特征(即查找特征)。

四、反向投影的工作原理

一、利用反向投影backproject查找特征的大致流程:

  • 输入模板图像
  • 得到模板图像的直方图
  • 输入源图像,依据源图像的每个像素的值,在模板图像的直方图中找到对应的值,然后将直方图的值赋给新的图像

二、具体细化的流程

直方图反向投影流程

假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
1.从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像
2.生成临时图像的直方图
3.用临时图像的直方图和模板图像的直方图对比,对比结果记为c
4.直方图对比结果c,就是结果图像(0,0)处的像素值
5.切割输入图像从(0,1)至(10,11)的临时图像,对比直方图,并记录到结果图像
6.重复1~5步直到输入图像的右下角,就形成了直方图的反向投影。

三、计算过程示例

(1)模板灰度图像的矩阵如下:

python+OpenCV反投影图像的实现示例详解

(2)模板灰度图像的直方图为:

        bin指定的区间为:[0,3), [4,7), [8,11), [12,16)

        Histogram = 4  4  6  2

(3)反向投影图为的矩阵为:

python+OpenCV反投影图像的实现示例详解

        例如位置(0,0)上的像素值为0,对应的bin为[0,3), 所以反向直方图在该位置上的值为这个bin的值4。

五、反向投影需注意的细节

  • 反投影图像能够在图像内定位感兴趣的对象python,同时反投影图像总是单通道图像,其中每一个像素的值都是从直方图中其对应的bin获取的。
  • 生成的反投影图像实际上是一张概率图。
  • 输入的原图像需要转换为HSV颜色空间,然后方可计算直方图,同时由于一般的直方图的bin很容易溢出0到255,所以在计算反投影之前,需要对直方图的结果进行标准化,将所有值缩放到从最小值0到最大值255的范围内,用到的是cv2.normalize()函数。
  • 再重复一次,必须在calBackProject函数之前调用该函数。
  • 为什么使用HSV颜色空间?
  • 例如,对于一张还有红玫瑰的图像,在RGB图像中,我们不能只根据一个阈值滤除红色通道,因为它可能太亮或太暗。但它仍然可能是红色的不同阴影。另外,可能想要考虑与红色javascript极其相似的颜色,以确保尽可能精确的得到玫瑰。在这种情况下,以及在需要处理颜色的类似情况下,最好是用色调、饱和度、值(三者简称HSV)颜色空间,其中颜色保存在单个通道(hue 或 h 通道)中。
  • 在HSV颜色空间中,色调单独负责每一个像素的颜色,饱和度和值通道可以用来得到相同颜色的更亮(使用饱和度通道)和更暗(使用值通道)的变化。
  • 另外与RGB不同,色调是0~360之间的值,这是因为色调被建模为一个圆,因此只要其值溢出,颜色就会回到起点。
  • 但是在open CV中,色调通常除以2以满足8位(除非我们使用16或更多位)的像素数据,所以颜色的值在0~180之间变化。

六、代码编写

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
# 输入模板图像与原图像
src = cv.imread("Epython:\\hand.jpg")
img = src.copy()
src2 = cv.imread("E:\\hand2.jpg")
img2 = src2.copy()
# 计算直方图
# 转换色彩空间
hsv_roi = cv.cvtColor(img, cv.COLOR_BGR2HSV)
# 计算直方图
roi_hist = cv.calcHist([hsv_roi], [0], None, [13], [0, 180])
# 归一化
cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)
# 原图像转换色彩空间
hsv_roi2 = cv.cvtColor(img2, cv.COLOR_BGR2HSV)
# 反投影
dst = cv.calcBackProject([hsv_roi2], [0], roi_hist, [0, 255], 1)
# 显示图像
plt.figure(figsize=(10, 6), dpi=100)
plt.plot(roi_hist)
plt.grid()
plt.show()
cv.imshow("backProject", dst)
cv.waitKey(0)

模板图像与原图像:

python+OpenCV反投影图像的实现示例详解

 模板图像的直方图:

python+OpenCV反投影图像的实现示例详解

在原图像中检测的特征:

python+OpenCV反投影图像的实现示例详解

到此这篇关于python+OpenCV反投影图像的文章就介绍到这了,更多相关python OpenCV反投影内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于python+OpenCV反投影图像的实现示例详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154506

相关文章

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

MySQL中REPLACE函数与语句举例详解

《MySQL中REPLACE函数与语句举例详解》在MySQL中REPLACE函数是一个用于处理字符串的强大工具,它的主要功能是替换字符串中的某些子字符串,:本文主要介绍MySQL中REPLACE函... 目录一、REPLACE()函数语法:参数说明:功能说明:示例:二、REPLACE INTO语句语法:参数

redis数据结构之String详解

《redis数据结构之String详解》Redis以String为基础类型,因C字符串效率低、非二进制安全等问题,采用SDS动态字符串实现高效存储,通过RedisObject封装,支持多种编码方式(如... 目录一、为什么Redis选String作为基础类型?二、SDS底层数据结构三、RedisObject

Python脚本轻松实现检测麦克风功能

《Python脚本轻松实现检测麦克风功能》在进行音频处理或开发需要使用麦克风的应用程序时,确保麦克风功能正常是非常重要的,本文将介绍一个简单的Python脚本,能够帮助我们检测本地麦克风的功能,需要的... 目录轻松检测麦克风功能脚本介绍一、python环境准备二、代码解析三、使用方法四、知识扩展轻松检测麦

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.

Java实现本地缓存的四种方法实现与对比

《Java实现本地缓存的四种方法实现与对比》本地缓存的优点就是速度非常快,没有网络消耗,本地缓存比如caffine,guavacache这些都是比较常用的,下面我们来看看这四种缓存的具体实现吧... 目录1、HashMap2、Guava Cache3、Caffeine4、Encache本地缓存比如 caff

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制

MySQL设置密码复杂度策略的完整步骤(附代码示例)

《MySQL设置密码复杂度策略的完整步骤(附代码示例)》MySQL密码策略还可能包括密码复杂度的检查,如是否要求密码包含大写字母、小写字母、数字和特殊字符等,:本文主要介绍MySQL设置密码复杂度... 目录前言1. 使用 validate_password 插件1.1 启用 validate_passwo

Java高效实现Word转PDF的完整指南

《Java高效实现Word转PDF的完整指南》这篇文章主要为大家详细介绍了如何用Spire.DocforJava库实现Word到PDF文档的快速转换,并解析其转换选项的灵活配置技巧,希望对大家有所帮助... 目录方法一:三步实现核心功能方法二:高级选项配置性能优化建议方法补充ASPose 实现方案Libre

springboot整合mqtt的步骤示例详解

《springboot整合mqtt的步骤示例详解》MQTT(MessageQueuingTelemetryTransport)是一种轻量级的消息传输协议,适用于物联网设备之间的通信,本文介绍Sprin... 目录1、引入依赖包2、yml配置3、创建配置4、自定义注解6、使用示例使用场景:mqtt可用于消息发