反向投影
反向投影用於在輸入影象中查詢與特定影象最匹配的點或者區域,也就是定位模板影象出現在輸入影象的位置。
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