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 相关文章推荐
Python入门教程之if语句的用法
May 14 Python
Python中分支语句与循环语句实例详解
Sep 13 Python
python读取几个G的csv文件方法
Jan 07 Python
在Python中获取操作系统的进程信息
Aug 27 Python
执行Django数据迁移时报 1091错误及解决方法
Oct 14 Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
Mar 18 Python
PyQt使用QPropertyAnimation开发简单动画
Apr 02 Python
pandas数据拼接的实现示例
Apr 16 Python
Python基础教程(一)——Windows搭建开发Python开发环境
Jul 20 Python
Python通过zookeeper实现分布式服务代码解析
Jul 22 Python
Python爬虫自动化获取华图和粉笔网站的错题(推荐)
Jan 08 Python
Python中Cookies导出某站用户数据的方法
May 17 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
DOTA2 玩家自创拉野攻略 特色英雄快速成长篇
2020/04/20 DOTA
php使用Session和文件统计在线人数
2015/07/04 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
2015/08/08 PHP
PHP实现简易blog的制作
2016/10/24 PHP
Jquery EasyUI中弹出确认对话框以及加载效果示例代码
2014/02/13 Javascript
javascript获取隐藏元素(display:none)的高度和宽度的方法
2014/06/06 Javascript
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
jquery实现的缩略图预览滑块实例
2015/06/25 Javascript
JS实现消息来时让网页标题闪动效果的方法
2016/04/20 Javascript
JS模拟的Map类实现方法
2016/06/17 Javascript
Bootstrap CSS使用方法
2016/12/23 Javascript
TypeScript入门-基本数据类型
2017/03/28 Javascript
JavaScript实现form表单的多文件上传
2020/03/27 Javascript
Node实战之不同环境下配置文件使用教程
2018/01/02 Javascript
JS实现的缓冲运动效果示例
2018/04/30 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
Vue触发式全局组件构建的方法
2018/11/28 Javascript
vue计算属性get和set用法示例
2019/02/08 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
微信小程序实现渐入渐出动画效果
2019/06/13 Javascript
使用vue实现多规格选择实例(SKU)
2019/08/23 Javascript
node.js中path路径模块的使用方法实例分析
2020/02/13 Javascript
Python基于DES算法加密解密实例
2015/06/03 Python
python数组复制拷贝的实现方法
2015/06/09 Python
python实现自动重启本程序的方法
2015/07/09 Python
Python中的数据对象持久化存储模块pickle的使用示例
2016/03/03 Python
Python中查看文件名和文件路径
2017/03/31 Python
详谈Numpy中数组重塑、合并与拆分方法
2018/04/17 Python
Django 请求Request的具体使用方法
2019/11/11 Python
django ListView的使用 ListView中获取url中的参数值方式
2020/03/27 Python
美国围栏公司:Walpole Outdoors
2019/11/19 全球购物
2015年信息宣传工作总结
2015/05/26 职场文书
消防安全培训工作总结
2015/10/23 职场文书
解除合同协议书范本
2016/03/21 职场文书
Nginx实现高可用集群构建(Keepalived+Haproxy+Nginx)
2021/05/27 Servers