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;
}


posted @ 2017-05-15 13:57  lytwajue  阅读(190)  评论(0编辑  收藏  举报