反向投影

反向投影用于在输入图像中查找与特定图像最匹配的点或者区域,也就是定位模板图像出现在输入图像的位置。

1、计算反向投影的函数

void calcBackProject(const Mat *image,int nimages,const int *channels,InputArray Hist,OutputArray backProject,const float **ranges,double scale =1,bool uniform =true)

参数一:输入数组或者数组集,必须是相同深度的,通道可以任意

参数二:输入图片数或数组的个数

参数三:通道索引

参数四:输入的直方图

参数五:目标反向投影阵列

参数六:每一个维度数组的每一维边界阵列,每一维数组的取值范围

参数七:输出的反向投影可选缩放因子

参数八:直方图是否均匀标识符

2、复制通道函数

void mixChannels(const Mat *src,size_t nsrcs,Mat *dst,size_t ndsts,const int *fromTo,size_t npairs)

参数一:输入数组,所有矩阵必须有相同的尺寸和深度

参数二:参数一输入的矩阵数

参数三:输出矩阵阵列,所有数组必须初始化且磁村和深度与src[0]相同

参数四:参数三的输出矩阵数

参数五:对指定通道进行复制的数组的索引

参数六:参数五的索引数

void mixChannels(const vector<Mat>&src,vector<Mat>&dst,const int *fromTo,size_t npairs)

参数一:输入矩阵,都必须有相同的尺寸和深度

参数二:输出阵列

参数三:对指定通道进行复制的数组的索引

参数四:参数三的索引数

此函数为重排通道数提供了非常先进的机制,split() merge()函数都是调用该函数来实现通道分离和合并的。

示例:将一个rgba图像转化为rgb和alpha图像

Mat rgba(100,100,CV_8UC4,Scalar(1,2,3,4))

Mat rgb(rgba.rows,rgba.cols,CV_8UC3)

Mat alpha(rgba.rows,rgba.cols,CV_8UC1)

Mat out[] ={rgb,alpha}

//说明:rgba[0]->rgb[2] rgba[1]->rgb[1]  rgba[2]->rgb[0] rgba[3]->alpha[0]

int fromTo[] ={0,2 ,1,1 ,2,0, 3,3}

mixChannels(&rgba,1,out,2,fromTo,4)


综合示例:


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

#define WINDOW_NAME1  "原始图"
#define WINDOW_NAME2  "投影图"
using namespace std;
using namespace cv;

Mat g_srcImage,g_hsvImage,g_hueImage;
int g_bins = 30;
void on_binChange(int,void *);

int main(int argc,char *argv[])
{
	if(argc!=2)
		return -1;
	g_srcImage = imread(argv[1],1);
	if(g_srcImage.empty())
	{
		cout<<"读取图片失败,请检查该图片是否存在\n"<<endl;
		return -1;
	}
	cvtColor(g_srcImage,g_hsvImage,COLOR_BGR2HSV);
	g_hueImage.create(g_hsvImage.size(),g_hsvImage.depth());
	int ch [] = {0,0};
	mixChannels(&g_hsvImage,1,&g_hueImage,1,ch,1);
	
	namedWindow(WINDOW_NAME1,WINDOW_AUTOSIZE);
	createTrackbar("色调组矩",WINDOW_NAME1,&g_bins,180,on_binChange);
	on_binChange(0,0);
	
	imshow(WINDOW_NAME1,g_srcImage);
	waitKey(0);
	return 0;
}

void on_binChange(int,void *)
{
	MatND hist;
	int histSize = MAX(g_bins,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("反向投影图",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_bins;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("直方图",histImg);
	 
}

来自:opencv3编程入门 毛星云pdf


猜你喜欢

转载自blog.csdn.net/gg101001/article/details/79696150