opencv2通过比较直方图检索相似图片

#if !defined COLHISTOGRAM
#define COLHISTOGRAM

#include 
#include 

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.
	cv::MatND getHistogram(const cv::Mat &image) {

		cv::MatND 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; 

		// Compute histogram
		cv::calcHist(&image, 
			1,			// histogram of 1 image only
			channels,	// the channel used
			cv::Mat(),	// no mask is used
			hist,		// the resulting histogram
			3,			// it is a 3D histogram
			histSize,	// number of bins
			ranges		// pixel value range
		);

		return hist;
	}

	// Computes the histogram.
	cv::SparseMat getSparseHistogram(const cv::Mat &image) {

		cv::SparseMat hist(3,histSize,CV_32F);

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

		// Compute histogram
		cv::calcHist(&image, 
			1,			// histogram of 1 image only
			channels,	// the channel used
			cv::Mat(),	// no mask is used
			hist,		// the resulting histogram
			3,			// it is a 3D histogram
			histSize,	// number of bins
			ranges		// pixel value range
		);

		return hist;
	}

	// Computes the 2D ab histogram.
	// BGR source image is converted to Lab
	cv::MatND getabHistogram(const cv::Mat &image) {

		cv::MatND hist;

		// Convert to Lab color space
		cv::Mat lab;
		cv::cvtColor(image, lab, CV_BGR2Lab);

		// Prepare arguments for a 2D color histogram
		hranges[0]= -128.0;
		hranges[1]= 127.0;
		channels[0]= 1; // the two channels used are ab 
		channels[1]= 2; 

		// Compute histogram
		cv::calcHist(&lab, 
			1,			// histogram of 1 image only
			channels,	// the channel used
			cv::Mat(),	// no mask is used
			hist,		// the resulting histogram
			2,			// it is a 2D histogram
			histSize,	// number of bins
			ranges		// pixel value range
		);

		return hist;
	}

	// Computes the 1D Hue histogram with a mask.
	// BGR source image is converted to HSV
	cv::MatND getHueHistogram(const cv::Mat &image) {

		cv::MatND hist;

		// Convert to Lab color space
		cv::Mat hue;
		cv::cvtColor(image, hue, CV_BGR2HSV);

		// Prepare arguments for a 1D hue histogram
		hranges[0]= 0.0;
		hranges[1]= 180.0;
		channels[0]= 0; // the hue channel 

		// Compute histogram
		cv::calcHist(&hue, 
			1,			// histogram of 1 image only
			channels,	// the channel used
			cv::Mat(),	// no mask is used
			hist,		// the resulting histogram
			1,			// it is a 1D histogram
			histSize,	// number of bins
			ranges		// pixel value range
		);

		return hist;
	}

	cv::Mat colorReduce(const cv::Mat &image, int div=64) {

	  int n= static_cast(log(static_cast(div))/log(2.0));
	  // mask used to round the pixel value
	  uchar mask= 0xFF<::const_iterator it= image.begin();
	  cv::Mat_::const_iterator itend= image.end();

	  // Set output image (always 1-channel)
	  cv::Mat result(image.rows,image.cols,image.type());
	  cv::Mat_::iterator itr= result.begin();

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

};


#endif


#if !defined ICOMPARATOR
#define ICOMPARATOR

#include 
#include 
#include "ColorHistogram.h"

class ImageComparator {

  private:

	cv::Mat reference;
	cv::Mat input;
	cv::MatND refH;
	cv::MatND inputH;

	ColorHistogram hist;
	int div;

  public:

	ImageComparator() : div(32) {

	}

	// Color reduction factor
	// The comparaison will be made on images with
	// color space reduced by this factor in each dimension
	void setColorReduction( int factor) {

		div= factor;
	}

	int getColorReduction() {

		return div;
	}

	void setReferenceImage(const cv::Mat& image) {

		reference= hist.colorReduce(image,div);
		refH= hist.getHistogram(reference);
	}

	double compare(const cv::Mat& image) {

		input= hist.colorReduce(image,div);
		inputH= hist.getHistogram(input);

		return cv::compareHist(refH,inputH,CV_COMP_INTERSECT);
	}
};


#endif

#include 
using namespace std;

#include 
#include 
#include

#include "imageComparator.h"

int main()
{
	// Read reference image
	cv::Mat image= cv::imread("D:/test/opencv/waves.jpg");
	if (!image.data)
		return 0; 

	// Display image
	cv::namedWindow("Query Image");
	cv::imshow("Query Image",image);

	ImageComparator c;
	c.setReferenceImage(image);

	// Read an image and compare it with reference
	cv::Mat input= cv::imread("D:/test/opencv/dog.jpg");
	cout << "waves vs dog: " << c.compare(input) << endl;

	// Read an image and compare it with reference
	input= cv::imread("D:/test/opencv/marais.jpg");
	cout << "waves vs marais: " << c.compare(input) << endl;

	// Read an image and compare it with reference
	input= cv::imread("D:/test/opencv/bear.jpg");
	cout << "waves vs bear: " << c.compare(input) << endl;

	// Read an image and compare it with reference
	input= cv::imread("D:/test/opencv/beach.jpg");
	cout << "waves vs beach: " << c.compare(input) << endl;

	// Read an image and compare it with reference
	input= cv::imread("D:/test/opencv/polar.jpg");
	cout << "waves vs polar: " << c.compare(input) << endl;

	// Read an image and compare it with reference
	input= cv::imread("D:/test/opencv/moose.jpg");
	cout << "waves vs moose: " << c.compare(input) << endl;

	// Read an image and compare it with reference
	input= cv::imread("D:/test/opencv/lake.jpg");
	cout << "waves vs lake: " << c.compare(input) << endl;

	// Read an image and compare it with reference
	input= cv::imread("D:/test/opencv/fundy.jpg");
	cout << "waves vs fundy: " << c.compare(input) << endl;

	cv::waitKey(0);
	return 0;
}


opencv2通过比较直方图检索相似图片_第1张图片

你可能感兴趣的:(opencv2)