标签:opencv back project 直方图反向投影 object detect
|
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; using namespace std; class Histogram1D { private: int histSize[1]; // number of bins float hranges[2]; // min and max pixel value const float* ranges[1]; int channels[1]; // only 1 channel used here public: Histogram1D() { histSize[0]= 256; hranges[0]= 0.0; hranges[1]= 255.0; ranges[0]= hranges; channels[0]= 0; } Mat getHistogram(const cv::Mat &image) { Mat hist; calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges); return hist; } }; Mat applyLookUp(const cv::Mat& image,const cv::Mat& lookup) { Mat result; cv::LUT(image,lookup,result); return result; } int main( int, char** argv ) { Mat image,gray,backproj; image = imread( argv[1], 1 ); if( !image.data ) return -1; cvtColor(image, gray, CV_BGR2GRAY); Mat imageROI; imageROI= gray(cv::Rect(360,55,40,50)); // 模版图像 Histogram1D h; Mat hist= h.getHistogram(imageROI); normalize(hist,hist,1.0); //归一化,得到概率直方图 float range[] = { 0, 255 }; const float* ranges = { range }; calcBackProject( &gray, 1, 0, hist, backproj, &ranges, 255.0); //反向投影,最重要的一步 namedWindow("after project"); imshow("after project",backproj); Mat lut(1,256,CV_8U); for (int i=0; i<256; i++) { lut.at<uchar>(i)= 255-i; //reverse操作 } Mat out = applyLookUp(backproj,lut); namedWindow("after reverse"); imshow("after reverse",out); threshold(out, out, 240 ,255, THRESH_BINARY); // 以240为分界线,<240为0,否则为255 namedWindow("after threshold"); imshow("after threshold",out); waitKey(0); return 0; }
class ColorHistogram { private: int histSize[3]; float hranges[2]; const float* ranges[3]; int channels[3]; public: ColorHistogram() { // Prepare arguments for a color histogram histSize[0]= histSize[1]= histSize[2]= 256; hranges[0]= 0.0; // BRG range hranges[1]= 255.0; ranges[0]= hranges; // all channels have the same range ranges[1]= hranges; ranges[2]= hranges; channels[0]= 0; // the three channels channels[1]= 1; channels[2]= 2; } // Computes the histogram. Mat getHistogram(const Mat &image) { Mat hist; // BGR color histogram hranges[0]= 0.0; // BRG range hranges[1]= 255.0; channels[0]= 0; // the three channels channels[1]= 1; channels[2]= 2; calcHist(&image, 1, channels,Mat(), hist,3,histSize,ranges); return hist; } Mat colorReduce(const Mat &image, int div=64) { int n= (int)(log((double)(div))/log(2.0)); // mask used to round the pixel value uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0 Mat_<Vec3b>::const_iterator it= image.begin<Vec3b>(); Mat_<Vec3b>::const_iterator itend= image.end<Vec3b>(); // Set output image (always 1-channel) Mat result(image.rows,image.cols,image.type()); Mat_<Vec3b>::iterator itr= result.begin<Vec3b>(); for ( ; it!= itend; ++it, ++itr) { (*itr)[0]= ((*it)[0]&mask) + div/2; (*itr)[1]= ((*it)[1]&mask) + div/2; (*itr)[2]= ((*it)[2]&mask) + div/2; } return result; } };最需要注意的是colorReduce这个方法
class ContentFinder { private: float hranges[2]; const float* ranges[3]; int channels[3]; float threshold; Mat histogram; public: ContentFinder() : threshold(-1.0f) { hranges[0]= 0.0; hranges[1]= 255.0; channels[0]= 0; channels[1]= 1; channels[2]= 2; ranges[0]= hranges; ranges[1]= hranges; ranges[2]= hranges; } // Sets the threshold on histogram values [0,1] void setThreshold(float t) { threshold= t; } // Gets the threshold float getThreshold() { return threshold; } //设置了直方图,并归一化,生成概率直方图 void setHistogram(const Mat& h) { histogram= h; normalize(histogram,histogram,1.0); } Mat find(const Mat& image) { Mat result; //最重要的一步,产生反向投影图 calcBackProject(&image, 1,channels,histogram,result,ranges,255.0); //二值化 if (threshold>0.0) cv::threshold(result, result,255*threshold, 255, cv::THRESH_BINARY); return result; } };
int main( int, char** argv ) { Mat color; color = imread( argv[1], 1 ); if( !color.data ) return -1; ColorHistogram hc; // reduce colors color = hc.colorReduce(color,32); // blue sky area Mat imageROI = color(Rect(0,0,165,75)); Mat hist= hc.getHistogram(imageROI); ContentFinder finder; finder.setHistogram(hist); finder.setThreshold(0.05f); Mat result= finder.find(color); namedWindow("sample"); imshow("sample",result); waitKey(0); return 0; }
OpenCV2马拉松第10圈——直方图反向投影(back project),布布扣,bubuko.com
OpenCV2马拉松第10圈——直方图反向投影(back project)
标签:opencv back project 直方图反向投影 object detect
原文地址:http://blog.csdn.net/abcd1992719g/article/details/25499753