您的位置:首页 > 运维架构

Oopencv学习之反向投影

2017-06-25 17:02 246 查看
Oopencv学习之反向投影

如果一幅图像的区域中显示的是一种结构纹理或者一个独特的物体,那么这个区域的直方图可以看作一个概率函数,其表现形式是某个像素属于该纹理或物体的概率。

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

反向投影用于在输入图像(通常较大)中查找与特定图像(通常较小或者仅1个像素,也就是模版图像)最匹配的点或者区域,也就是定位模板图像出现在输入图像的位置。

反向投影的结果包含了以每个输入图像像素点为起点的直方图对比结果。可以把它看成是一个二维的浮点型数组、二维矩阵或者单通道的浮点型图像。

计算反向投影–clacBackProject函数

函数用于计算直方图的反向投影

void clacBackProject(const mat* images,int nimages,const int channels,inputArray hist,outputArray backProject,const float* ranges,double scale=1,bool uniform=true)

*第一个参数,输入的数组(或者数组集),须为相同的深度(CV_8U或CV_32F)和相同的尺寸,通道数则可以任意。

*第二个参数,输入数组的个数,也就是第一参数中存放了多少张“图像”,有几个原数组。

*第三个参数,需要统计的通道(dim)索引,第一个数组通道从0到images[0].channels()-1,而第二个数组通道从images[0].channels()计算到images[0].channels()+images[1].channels()-1。

*第四个参数,输入的直方图。

*第五个参数,目标反向投影阵列,其须为单通道,并且和image[0]有相同的大小和深度。

*第六个参数,表示每一个维度数组(第六个参数dims)的每一维的边界阵列,可以理解为每一维数值的取值范围。

*第七个参数,默认值1,输出的方向投影可选的缩放因子,默认值为1。

*第八个参数,bool类型的uniform,指示直方图是否均匀的标识符,默认值true。

通道复制–mixChannels函数

由输入参数复制某通道到输出参数特定的通道中。

void mixChannels(const Mat* src,//输入的数组,所有矩阵必须有相同的尺寸和深度

size_t nsrcs,//第一个参数src输入的矩阵数

Mat* dst,//输出的数组,所有矩阵必须备初始化,且大小和深度必须与src[0]相同

size_t ndsts,//第三个参数dst输入的矩阵数

const int* fromTo,//对指定的通道进行复制的数组索引

size_t npairs//第五个参数fromTO的索引数

)

void mixChannels(

const vector& src,//输入的矩阵向量,所有的矩阵必须有相同的尺寸和深度

vector& dst,//输出的矩阵向量,所有矩阵须被初始化,且大小和深度须与src[0]相同

const int *fromTo,//对指定的通道进行复制的数组索引

size_t npairs//第三个参数fromTo的索引数

)

merge()、split()、cvColor()的某些形式都只是mixChannels()的一部分。

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace cv;

//全局变量声明
Mat g_srcImage,g_hsvImage,g_hueImage;
int g_nbins=30;//直方图组距

//全局函数声明
void on_BinChange(int,void *);

//主函数
int main()
{
//载入源图像,并转换到HSV空间
g_srcImage=imread("/Users/new/Desktop/3.jpg");
if(!g_srcImage.data){printf("读取源图像srcImage错误~!\n");return false;}
cvtColor(g_srcImage, g_hsvImage, COLOR_BGR2HSV);

//分离Hue色调通道
g_hueImage.create(g_hsvImage.size(),g_hsvImage.depth());
int ch[]={0,0};
mixChannels(&g_hsvImage, 1, &g_hueImage, 1, ch, 1);

//创建Trackbar来输入bin的数目
namedWindow("image[origin]");
createTrackbar("bins of hue: ", "image[origin]", &g_nbins, 180,on_BinChange);
on_BinChange(0, 0);

//显示效果图
imshow("image[origin]",g_srcImage);

waitKey(0);
return 0;
}

//回调函数定义
void on_BinChange(int,void *)
{
//参数准备
MatND hist;
int histSize=MAX(g_nbins,2);
float hue_range[]={0,180};
const float* ranges={hue_range};

//计算直方图并归一化
calcHist(&g_hueImage, 1, 0, Mat(), hist, 1, &histSize, &ranges,true,false);
normalize(hist,hist,0,255,NORM_MINMAX,-1,Mat());

//计算反向投影
MatND backproj;
calcBackProject(&g_hueImage, 1, 0, hist, backproj, &ranges,1,true);
//显示反向投影
imshow("image[backprojection]",backproj);
//绘制直方图的参数准备
int w=400,h=400;
int bin_w=cvRound((double)w/histSize);
Mat histImg=Mat::zeros(w,h,CV_8UC3);
//绘制直方图
for(int i=0;i<g_nbins;++i)
{
rectangle(histImg, Point(i*bin_w,h), Point((i+1)*bin_w,h-cvRound(hist.at<float>(i)*h/255.0)), Scalar(100,123,255),-1);
}
//显示直方图窗口
imshow("image[histogram]",histImg);
}






Opencv技巧

(1)求最大:MAX();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv