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中的getBytes()方法使用详解

《Java中的getBytes()方法使用详解》:本文主要介绍Java中getBytes()方法使用的相关资料,getBytes()方法有多个重载形式,可以根据需要指定字符集来进行转换,文中通过代... 目录前言一、常见重载形式二、示例代码三、getBytes(Charset charset)和getByt

Python多重继承慎用的地方

《Python多重继承慎用的地方》多重继承也可能导致一些问题,本文主要介绍了Python多重继承慎用的地方,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录前言多重继承要慎用Mixin模式最后前言在python中,多重继承是一种强大的功能,它允许一个

Spring框架中@Lazy延迟加载原理和使用详解

《Spring框架中@Lazy延迟加载原理和使用详解》:本文主要介绍Spring框架中@Lazy延迟加载原理和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、@Lazy延迟加载原理1.延迟加载原理1.1 @Lazy三种配置方法1.2 @Component

Django之定时任务django-crontab的实现

《Django之定时任务django-crontab的实现》Django可以使用第三方库如django-crontab来实现定时任务的调度,本文主要介绍了Django之定时任务django-cront... 目录crontab安装django-crontab注册应用定时时间格式定时时间示例设置定时任务@符号

Python中edge-tts实现便捷语音合成

《Python中edge-tts实现便捷语音合成》edge-tts是一个功能强大的Python库,支持多种语言和声音选项,本文主要介绍了Python中edge-tts实现便捷语音合成,具有一定的参考价... 目录安装与环境设置文本转语音查找音色更改语音参数生成音频与字幕总结edge-tts 是一个功能强大的

Java实现按字节长度截取字符串

《Java实现按字节长度截取字符串》在Java中,由于字符串可能包含多字节字符,直接按字节长度截取可能会导致乱码或截取不准确的问题,下面我们就来看看几种按字节长度截取字符串的方法吧... 目录方法一:使用String的getBytes方法方法二:指定字符编码处理方法三:更精确的字符编码处理使用示例注意事项方

使用Python和PaddleOCR实现图文识别的代码和步骤

《使用Python和PaddleOCR实现图文识别的代码和步骤》在当今数字化时代,图文识别技术的应用越来越广泛,如文档数字化、信息提取等,PaddleOCR是百度开源的一款强大的OCR工具包,它集成了... 目录一、引言二、环境准备2.1 安装 python2.2 安装 PaddlePaddle2.3 安装

Python+PyQt5开发一个Windows电脑启动项管理神器

《Python+PyQt5开发一个Windows电脑启动项管理神器》:本文主要介绍如何使用PyQt5开发一款颜值与功能并存的Windows启动项管理工具,不仅能查看/删除现有启动项,还能智能添加新... 目录开篇:为什么我们需要启动项管理工具功能全景图核心技术解析1. Windows注册表操作2. 启动文件

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

Python datetime 模块概述及应用场景

《Pythondatetime模块概述及应用场景》Python的datetime模块是标准库中用于处理日期和时间的核心模块,本文给大家介绍Pythondatetime模块概述及应用场景,感兴趣的朋... 目录一、python datetime 模块概述二、datetime 模块核心类解析三、日期时间格式化与