python OpenCV学习笔记直方图反向投影的实现


Posted in Python onFebruary 07, 2018

本文介绍了python OpenCV学习笔记直方图反向投影的实现,分享给大家,具体如下:

官方文档 ? https://docs.opencv.org/3.4.0/dc/df6/tutorial_py_histogram_backprojection.html

它用于图像分割或寻找图像中感兴趣的对象。简单地说,它创建一个与我们的输入图像相同大小(但单通道)的图像,其中每个像素对应于属于我们对象的像素的概率。输出图像将使我们感兴趣的对象比其余部分更白。

该怎么做呢?我们创建一个图像的直方图,其中包含我们感兴趣的对象。为了得到更好的结果,对象应该尽可能地填充图像。而颜色直方图比灰度直方图更受青睐,因为对象的颜色比灰度强度更能定义对象。然后,我们在我们的测试图像上“反向投射”这个直方图,我们需要找到这个对象,换句话说,我们计算每个像素的概率,并显示它。在适当的阈值上产生的输出结果使我们得到了一个单独的结果。

Numpy中的算法

1、首先,我们需要计算我们需要找到的对象的颜色直方图(让它为'M')和我们将要搜索的图像(让它为'I')。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

# roi是我们需要找到的对象或区域
roi = cv.imread('rose_red.png')
hsv = cv.cvtColor(roi, cv.COLOR_BGR2HSV)

# target是我们搜索的图像
target = cv.imread('rose.png')
hsvt = cv.cvtColor(target, cv.COLOR_BGR2HSV)

# 用calcHist来找直方图,也可以用np.histogram2d
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是(x,y)坐标像素的色调,s是饱和度。之后,B(x,y)=min[B(x,y),1]

h, s, v = cv.split(hsvt)
B = R[h.ravel(), s.ravel()]
B = np.munimum(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)

# 计算对象的直方图
roihist = cv.calcHist([hsv], [0,1], None, [180,256], [0,180,0,256])

# 标准化直方图,并应用投影
cv.normalize(roihist, roihist, 0, 255, cv.NORM_MINMAX)
dst = cv.calcBackProject([hsvt], [0,1], roihist, [0,180,0,256], 1)

# 与磁盘内核进行卷积
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5,5))
cv.filter2D(dst, -1, disc, dst)

# 阈值、二进制按位和操作
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)

下面是一个例子。使用蓝色矩形中的区域作为示例对象,提取想提取全部内容。

python OpenCV学习笔记直方图反向投影的实现

关于这两种技术的原理可以参考我上面贴的链接,下面是示例的代码:

0x01. 绘制直方图

import cv2.cv as cv
 
def drawGraph(ar,im, size): #Draw the histogram on the image
  minV, maxV, minloc, maxloc = cv.MinMaxLoc(ar) #Get the min and max value
  hpt = 0.9 * histsize
  for i in range(size):
    intensity = ar[i] * hpt / maxV #Calculate the intensity to make enter in the image
    cv.Line(im, (i,size), (i,int(size-intensity)),cv.Scalar(255,255,255)) #Draw the line
    i += 1
 
#---- Gray image
orig = cv.LoadImage("img/lena.jpg", cv.CV_8U)
 
histsize = 256 #Because we are working on grayscale pictures which values within 0-255
 
hist = cv.CreateHist([histsize], cv.CV_HIST_ARRAY, [[0,histsize]], 1)
 
cv.CalcHist([orig], hist) #Calculate histogram for the given grayscale picture
 
histImg = cv.CreateMat(histsize, histsize, cv.CV_8U) #Image that will contain the graph of the repartition of values
drawGraph(hist.bins, histImg, histsize)
 
cv.ShowImage("Original Image", orig)
cv.ShowImage("Original Histogram", histImg)
#---------------------
 
#---- Equalized image
imEq = cv.CloneImage(orig)
cv.EqualizeHist(imEq, imEq) #Equlize the original image
 
histEq = cv.CreateHist([histsize], cv.CV_HIST_ARRAY, [[0,histsize]], 1)
cv.CalcHist([imEq], histEq) #Calculate histogram for the given grayscale picture
eqImg = cv.CreateMat(histsize, histsize, cv.CV_8U) #Image that will contain the graph of the repartition of values
drawGraph(histEq.bins, eqImg, histsize)
 
cv.ShowImage("Image Equalized", imEq)
cv.ShowImage("Equalized HIstogram", eqImg)
#--------------------------------
 
cv.WaitKey(0)

0x02. 反向投影

import cv2.cv as cv
 
im = cv.LoadImage("img/lena.jpg", cv.CV_8U)
 
cv.SetImageROI(im, (1, 1,30,30))
 
histsize = 256 #Because we are working on grayscale pictures
hist = cv.CreateHist([histsize], cv.CV_HIST_ARRAY, [[0,histsize]], 1)
cv.CalcHist([im], hist)

cv.NormalizeHist(hist,1) # The factor rescale values by multiplying values by the factor
_,max_value,_,_ = cv.GetMinMaxHistValue(hist)
 
if max_value == 0:
  max_value = 1.0
cv.NormalizeHist(hist,256/max_value)
 
cv.ResetImageROI(im)
 
res = cv.CreateMat(im.height, im.width, cv.CV_8U)
cv.CalcBackProject([im], res, hist)
 
cv.Rectangle(im, (1,1), (30,30), (0,0,255), 2, cv.CV_FILLED)
cv.ShowImage("Original Image", im)
cv.ShowImage("BackProjected", res)
cv.WaitKey(0)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3遍历目录树实现方法
May 22 Python
20个常用Python运维库和模块
Feb 12 Python
Python paramiko模块的使用示例
Apr 11 Python
python程序封装为win32服务的方法
Mar 07 Python
Python OS模块实例详解
Apr 15 Python
python3.5安装python3-tk详解
Apr 26 Python
python命令 -u参数用法解析
Oct 24 Python
python实现输入的数据在地图上生成热力图效果
Dec 06 Python
解决python 找不到module的问题
Feb 12 Python
零基础小白多久能学会python
Jun 22 Python
Python 测试框架unittest和pytest的优劣
Sep 26 Python
Python创建SQL数据库流程逐步讲解
Sep 23 Python
Python实现上下班抢个顺风单脚本
Feb 07 #Python
Python SqlAlchemy动态添加数据表字段实例解析
Feb 07 #Python
Python实现抢购IPhone手机
Feb 07 #Python
浅谈python可视化包Bokeh
Feb 07 #Python
详解tensorflow训练自己的数据集实现CNN图像分类
Feb 07 #Python
全面分析Python的优点和缺点
Feb 07 #Python
Tensorflow环境搭建的方法步骤
Feb 07 #Python
You might like
将博客园(cnblogs.com)数据导入到wordpress的代码
2013/01/06 PHP
php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法
2013/08/10 PHP
Smarty中调用FCKeditor的方法
2014/10/27 PHP
老生常谈ThinkPHP中的行为扩展和插件(推荐)
2017/05/05 PHP
在网站上应该用的30个jQuery插件整理
2011/11/03 Javascript
nodejs入门详解(多篇文章结合)
2012/03/07 NodeJs
js模拟点击事件实现代码
2012/11/06 Javascript
Javascript Boolean、Nnumber、String 强制类型转换的区别详细介绍
2012/12/13 Javascript
点击标签切换和自动切换DIV选项卡
2014/08/10 Javascript
js实现点击切换TAB标签实例
2015/08/21 Javascript
深入浅析JavaScript中数据共享和数据传递
2016/04/25 Javascript
JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别
2016/08/26 Javascript
移动前端图片压缩上传的实例
2017/12/06 Javascript
JS删除数组里的某个元素方法
2018/02/03 Javascript
axios发送post请求springMVC接收不到参数的解决方法
2018/03/05 Javascript
nuxt框架中路由鉴权之Koa和Session的用法
2018/05/09 Javascript
Javascript删除数组里的某个元素
2019/02/28 Javascript
Electron-vue开发的客户端支付收款工具的实现
2019/05/24 Javascript
vue 指令和过滤器的基本使用(品牌管理案例)
2019/11/04 Javascript
vue中destroyed方法的使用说明
2020/07/21 Javascript
Element-UI 使用el-row 分栏布局的教程
2020/10/26 Javascript
python网络编程学习笔记(五):socket的一些补充
2014/06/09 Python
python中的多重继承实例讲解
2014/09/28 Python
Python类的多重继承问题深入分析
2014/11/09 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解
2020/02/18 Python
什么是Smarty变量操作符?如何使用Smarty变量操作符
2014/07/18 面试题
你在项目中用到了xml技术的哪些方面?如何实现的?
2014/01/26 面试题
资产经营总监岗位职责
2013/12/04 职场文书
某集团股份有限公司委托书样本
2014/09/24 职场文书
国庆横幅标语
2014/10/08 职场文书
瘦西湖导游词
2015/02/03 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书
python 下载文件的几种方式分享
2021/04/07 Python
如何有效防止sql注入的方法
2021/05/25 SQL Server
CSS filter 有什么神奇用途
2021/05/25 HTML / CSS