<html>
1.概述
反向投影是一种记录给定图像中的像素点怎样适应直方图模型像素分布的方式,简单来讲。反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的特征。反向投影在某一位置的值就是原图相应位置像素值在原图像中的总数目。
2.反向投影原理
原理採用OpenCV docs介绍。使用肤色直方图来解释反向投影的工作原理。如果我们已经获得一个肤色直方图(Hue-Staturation),旁边的直方图就是模型直方图(代表手掌的肤色色调)。能够通过掩码操作来抓取手掌所在区域的直方图:
我们须要做的就是使用模型直方图(代表手掌的皮肤色调)来检測測试图像中的皮肤区域。下面是检測步骤:
a.对測试图像中的每一个像素 p(i,j),获取色调数据并找到该色调在直方图中的bin位置
b.查询模型直方图中相应的bin-并读取该bin的数值。
c.将此数值存储在新的图像中(BackProjection)。
也能够先归一化模型直方图。这样測试图像的输出就能够在屏幕上显示了。
d.通过对測试中的图像中的每一个像素採用以上步骤。能够得到例如以下的BackProjection结果图:
e.使用统计学的语言,BackProjection中存储的数值代表了測试图像中该像素属于皮肤区域的概率。
以上图为例,亮的区域是皮肤区域的可能性更大,而暗的区域则表示更低的可能性。
这个过程能够笼统的说与计算图像直方图相反。由图像计算直方图的过程比較easy理解,就是统计图像中像素分布的概率,而反向投影正好反过来。是通过直方图来形成图像。其步骤有点相似于直方图均衡化,仅仅只是直方图均衡化是将图像中的每一个像素值由一个地方迁移到另外一个地方。而反向投影是直接去直方图中的值,如某种像素值在直方图中的值越大,在进行反向投影操作时其相应的像素值越大即月亮。反过来,如果某灰度值所占面积越小,其反向投影后像素值就会更小。
举个简单的样例来帮助理解这段话的意思。比如灰度图像的像素值例如以下例如以下
grayImage
0 1 2 3
4 5 6 7
8 9 10 11
8 9 14 15
对图像进行直方图统计(bin指定的区间为[0,3)。[4,7)。[8,11)。[12,16))例如以下所看到的:
Histogram=
4 4 6 2
也就是说在[0,3)这个区间的像素值有4个。其他含义同样
依据上述的直方图进行反向投影,得到反向投影图像像素值例如以下:
Back_Projection=
4 4 4 4
4 4 4 4
6 6 6 6
6 6 2 2
比如位置(0,0)上的像素值为0,相应的bin为[0,3)。所以反向直方图在该位置上的值这个bin的值4。而在位置(3,3)上的像素为15,其在直方图中的统计为2。故其反向投影图像中的像素为2
3.OpenCV提供API
calcBackProjection()函数共同拥有三种形式,依据传入參数的不同选择不同的调用。为重载函数
void cv::calcBackProject ( const Mat * images,
int nimages,
const int * channels,
InputArray hist,
OutputArray backProject,
const float ** ranges,
double scale = 1,
bool uniform = true
)
參数解释:
const Mat* images:输入图像,图像深度必须位CV_8U,CV_16U或CV_32F中的一种,尺寸同样,每一幅图像都能够有随意的通道数
int nimages:输入图像的数量
const int* channels:用于计算反向投影的通道列表,通道数必须与直方图维度相匹配,第一个数组的通道是从0到image[0].channels()-1,第二个数组通道从图像image[0].channels()到image[0].channels()+image[1].channels()-1计数
InputArray hist:输入的直方图,直方图的bin能够是密集(dense)或稀疏(sparse)
OutputArray backProject:目标反向投影输出图像。是一个单通道图像,与原图像有同样的尺寸和深度
const float ranges**:直方图中每一个维度bin的取值范围
double scale=1:可选输出反向投影的比例因子
bool uniform=true:直方图是否均匀分布(uniform)的标识符,有默认值true
另外两种定义形式例如以下:
void cv::calcBackProject ( const Mat * images,
int nimages,
const int * channels,
const SparseMat & hist,
OutputArray backProject,
const float ** ranges,
double scale = 1,
bool uniform = true
)
void cv::calcBackProject ( InputArrayOfArrays images,
const std::vector< int > & channels,
InputArray hist,
OutputArray dst,
const std::vector< float > & ranges,
double scale
)
4.演示样例代码
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
//定义全局变量
Mat srcImage, hsvImage,hueImage;
const int hueBinMaxValue = 180;
int hueBinValue=25;
//声明回调函数
void Hist_and_Backprojection(int, void*);
int main()
{
srcImage=imread("Back_Projection_Theory2.jpg");
//推断图像是否载入成功
if(srcImage.empty())
{
cout << "图像载入失败" << endl;
return -1;
}
else
cout << "图像载入成功..." << endl << endl;
//将图像转化为HSV图像
cvtColor(srcImage, hsvImage, CV_BGR2HSV);
//仅仅使用图像的H參数
hueImage.create(hsvImage.size(), hsvImage.depth());
int ch[]={0,0};
mixChannels(&hsvImage, 1, &hueImage, 1, ch, 1);
//轨迹条參数设置
char trackBarName[20];
sprintf(trackBarName,"Hue bin:%d",hueBinMaxValue);
namedWindow("SourceImage",WINDOW_AUTOSIZE);
//创建轨迹条并调用回调函数
createTrackbar(trackBarName, "SourceImage", &hueBinValue, hueBinMaxValue, Hist_and_Backprojection);
Hist_and_Backprojection(hueBinValue, 0);
imshow("SourceImage", srcImage);
waitKey(0);
return 0;
}
void Hist_and_Backprojection(int, void*)
{
MatND hist;
int histsize=MAX(hueBinValue, 2);
float hue_range[]={0,180};
const float* ranges={hue_range};
//计算图像直方图并归一化处理
calcHist(&hueImage, 1, 0, Mat(), hist, 1, &histsize, &ranges, true, false);
normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());
//获取反向投影
MatND backProjection;
calcBackProject(&hueImage, 1, 0, hist, backProjection, &ranges, 1, true);
//输出反向投影
imshow("BackProjection", backProjection);
//绘制图像直方图
int w=400;
int h=400;
int bin_w = cvRound((double)w/histsize);
Mat histImage = Mat::zeros(w, h, CV_8UC3);
for(int i=0; i < hueBinValue; i++)
{
rectangle(histImage, Point(i*bin_w, h), Point((i+1)*bin_w, h-cvRound(hist.at<float>(i)*h/255.0)), Scalar(0,0,255), -1);
}
imshow("HistImage", histImage);
}
程序执行结果:
- 本文已收录于下面专栏:
- opencv2/3基础教程
相关文章推荐
-
反向投影图calcBackProject的使用方法
原文地址:http://blog.163.com/thomaskjh@126/blog/static/370829982010112810358501/ 图像的反向投影图是用输入图像的某...- u013129690
- 2014-09-16 11:53
- 747
-
直方图匹配-Opencv种cvCalcBackProject的理解
转自:http://blog.163.com/chenliangren@126/blog/static/168305659201071711434658/ 演示样例可看本博客:http://blog.1...- SevenColorFish
- 2011-10-02 18:21
- 13670
-
CalcBackProject函数
反向投影 目标 本文档尝试解答例如以下问题: 什么是反向投影,它能够实现什么功能? 怎样使用OpenCV函数 calcBackProject 计算反向投影? 怎样使用Open...- qq_18343569
- 2015-08-27 15:09
- 1375
-
cvCalcBackProject的样例
在学习 《学习opencv》的cvCalcBackProject时自己写的样例 [cpp] view plaincopy #include ...- qq_18343569
- 2015-08-27 15:20
- 204
-
OpenCV反向投影cvCalcBackProject的演示样例,用图像中某中颜色的区域
在学习 《学习opencv》的cvCalcBackProject时自己写的样例#include #include #include #include #include usin...- Augusdi
- 2013-06-04 14:29
- 3829
-
opencv3 计算反向投影-calcBackProject函数-滚动栏
#include #include #include using namespace cv; using namespace std; vector modeHImage; Mat findIma...- qq_23880193
- 2015-11-05 22:56
- 628
-
直方图匹配-Opencv种cvCalcBackProject的理解
直方图的对照 OpenCv提供了5种对照直方图的方式:CORREL(相关)、CHISQR(卡方)、INTERSECT(相交)、BHATTACHARYYA、EMD(最小工作距离),当中...- szlcw1
- 2014-07-31 21:01
- 532
-
opencv 反向投影 cvCalcBackProject的演示样例 ,用图像中某中颜色的区域
在学习 《学习opencv》的cvCalcBackProject时自己写的样例 #include #include #include #include #include using ...- fdl19881
- 2011-08-27 21:24
- 6453
-
opencv学习之visual studio2015+opencv2.4.13配置
换实验室啦。换电脑啦,又一次配置开发环境。正好这个系列缺一篇完整的配置教程。索性在中途补上。可能会造成这个系列排版变乱!。!这次配置选择的事visual studio2015和opencv2.4.13。
...
- keith_bb
- 2016-11-24 20:10
- 6477
-
opencv学习(十)之调节图像亮度和对照度
在图像处理中。图像像素的值依赖于输入图像的值。能够通过对输入像素值进行数值运算已达到对图像处理的目的。以调节图像对照度和亮度为例,通过结合之前学过的图像像素訪问和轨迹条等内容,对图像对照度和亮度进行调...
- keith_bb
- 2016-11-21 21:28
- 481
0条评论