opencv2反投影直方图以检測特定的图像内容
#ifndef HISTOGRAM_H_ #define HISTOGRAM_H_ #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> #include <opencv2/calib3d/calib3d.hpp> #include<iostream> #include <vector> using namespace std; using namespace cv; class Histogram1D { private: int histSize[1]; float hranges[2]; const float *ranges[1]; int channels[1]; public: Histogram1D(); cv::MatND getHistogram(const cv::Mat &image); cv::Mat getHistogramImage(const cv::Mat &image); cv::Mat applyLookUp(const cv::Mat &image,const cv::Mat &lookup); cv::Mat stretch(const cv::Mat &image,int minValue=0); cv::Mat equalize(const cv::Mat &image); cv::Mat calcBack(const cv::Mat &image,const cv::MatND hist); cv::Mat threShold(const cv::Mat &image); }; #endif /* HISTOGRAM_H_ */ #include"Histogram1D.h" Histogram1D::Histogram1D() { histSize[0]=256; hranges[0]=0.0; hranges[1]=255.0; ranges[0]=hranges; channels[0]=0; }; cv::MatND Histogram1D::getHistogram(const cv::Mat &image) { cv::MatND hist; cv::calcHist(&image,1,channels,cv::Mat(),hist,1,histSize,ranges); return hist; }; cv::Mat Histogram1D::getHistogramImage(const cv::Mat &image) { cv::MatND hist=getHistogram(image); double maxVal=0; double minVal=0; cv::minMaxLoc(hist,&minVal,&maxVal,0,0); cv::Mat histImg(histSize[0],histSize[0],CV_8U,cv::Scalar(255)); int hpt=static_cast<int>(0.9*histSize[0]); for(int h=0;h<histSize[0];h++) { float binVal=hist.at<float>(h); int intensity=static_cast<int>(binVal*hpt/maxVal); cv::line(histImg,cv::Point(h,histSize[0]),cv::Point(h,histSize[0]-intensity),cv::Scalar::all(0)); } return histImg; }; cv::Mat Histogram1D::applyLookUp(const cv::Mat &image,const cv::Mat &lookup) { cv::Mat result; cv::LUT(image,lookup,result); return result; } cv::Mat Histogram1D::stretch(const cv::Mat &image,int minValue) { cv::MatND hist=getHistogram(image); int imin=0; for(;imin<histSize[0];imin++) { std::cout<<hist.at<float>(imin)<<std::endl; if(hist.at<float>(imin)>minValue) break; } int imax=histSize[0]-1; for(;imax>=0;imax--) { if(hist.at<float>(imax)>minValue) break; } int dim(256); cv::Mat lookup(1,&dim,CV_8U); for(int i=0;i<256;i++) { if(i<imin)lookup.at<uchar>(i)=0; else if(i>imax)lookup.at<uchar>(i)=255; else lookup.at<uchar>(i)=static_cast<uchar>(255.0*(i-imin)/(imax-imin)+0.5); } cv::Mat result; result=applyLookUp(image,lookup); return result; } cv::Mat Histogram1D::equalize(const cv::Mat &image) { cv::Mat result; cv::equalizeHist(image,result); return result; } cv::Mat Histogram1D::calcBack(const cv::Mat &image,const cv::MatND hist) { cv::Mat result; cv::calcBackProject(&image,1,channels,hist,result,ranges,255.0); return result; } cv::Mat Histogram1D::threShold(const cv::Mat &image) { cv::Mat thresholded; cv::threshold(image,thresholded,0,255,cv::THRESH_BINARY); return thresholded; } #include"Histogram1D.h" int main() { cv::Mat image=cv::imread("d:\\test\\opencv\\waves.jpg",0); if( !image.data ) exit(0); cv::Mat imageROI; imageROI=image(cv::Rect(360,55,40,50)); cv::Mat back; cv::Mat result; Histogram1D h; cv::MatND hist=h.getHistogram(imageROI); namedWindow("hist"); imshow("hist",h.getHistogramImage(imageROI)); cv::normalize(hist,hist,1.0); back=h.calcBack(image,hist); result=h.threShold(back); namedWindow("Backprojection"); imshow("Backprojection",back); namedWindow("Detection Result"); imshow("Detection Result",result); waitKey(0); return 0; }