直方图 单通道 多通道

// opencv_2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <cv.h>
#include <highgui.h>

using namespace cv;
using namespace std;


class Histogram1D
{
private:
	int histsize[1];
	float hranges[2];
	const float* ranges[1];
	int channels[1];

public:
	Histogram1D() 	
	{
		histsize[0] = 256 ;
		hranges[0] = 0.0;
		hranges[1] = 255.0;
		ranges[0] = hranges;
		channels[0] = 0;
	}

	Mat getHistogram(const Mat &image);
	Mat getHistogramImage(const Mat &image);
};

Mat Histogram1D::getHistogram(const Mat &image)
{
	Mat hist;
	calcHist(&image, 1, channels, Mat(), hist, 1, histsize, ranges);
	return hist;
}


Mat Histogram1D::getHistogramImage(const Mat &image)
{
	Mat hist = getHistogram(image);

	double maxVal = 0;
	double minVal = 0;
	minMaxLoc(hist, &minVal, &maxVal);

	Mat histImg(histsize[0],histsize[0],CV_8U,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);
		line(histImg, Point(h, histsize[0]),
			          Point(h,histsize[0] - intensity),
					  Scalar(0));
	}

	return histImg;



}

int _tmain(int argc, _TCHAR* argv[])
{
	Mat image = imread("F:\\testImg\\1.jpg", 0 );
	int sum = 0;
	int max = 0;
	Histogram1D h;
	Mat histo = h.getHistogramImage(image);

	//for (int i = 0; i < 256; i++)
	//{
	//	if (histo.at<float>(i) > max)
	//	{
	//		max = histo.at<float>(i);
	//	}
	//	/*cout<<"Value"<<i<<"="<<histo.at<float>(i)<<endl;*/
	//	/*sum += histo.at<float>(i);*/
	//	
	//}
	//cout<<max<<endl;
	imshow("dst", histo);
	waitKey(0);
	

	return 0;
}
</pre><pre name="code" class="cpp">
</pre><pre name="code" class="cpp">
/**
 * @function calcHist_Demo.cpp
 * @brief Demo code to use the function calcHist
 * @author
 */


#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>


using namespace std;
using namespace cv;


/**
 * @function main
 */
int main( int argc, char** argv )
{
  Mat src, dst;


  /// Load image
  src = imread( argv[1], 1 );


  if( !src.data )
    { return -1; }


  /// Separate the image in 3 places ( B, G and R )
  vector<Mat> bgr_planes;
  split( src, bgr_planes );


  /// Establish the number of bins
  int histSize = 256;


  /// Set the ranges ( for B,G,R) )
  float range[] = { 0, 256 } ;
  const float* histRange = { range };


  bool uniform = true; bool accumulate = false;


  Mat b_hist, g_hist, r_hist;


  /// Compute the histograms:
  calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );


  // Draw the histograms for B, G and R
  int hist_w = 512; int hist_h = 400;
  int bin_w = cvRound( (double) hist_w/histSize );


  Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );


  /// Normalize the result to [ 0, histImage.rows ]
  normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
  normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
  normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );


  /// Draw for each channel
  for( int i = 1; i < histSize; i++ )
  {
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
                       Scalar( 255, 0, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
                       Scalar( 0, 255, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
                       Scalar( 0, 0, 255), 2, 8, 0  );
  }


  /// Display
  namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE );
  imshow("calcHist Demo", histImage );


  waitKey(0);


  return 0;


}
 
 
//多通道

</pre><pre name="code" class="cpp">#include <cv.h>
#include <highgui.h>
using namespace cv;
int main( int argc, char** argv )
{
	Mat src;
	if( argc != 2 || !(src=imread(argv[1], 1)).data )
	return -1;
	Mat hsv;
	cvtColor(src, hsv, CV_BGR2HSV);
	// let’s quantize the hue to 30 levels
	// and the saturation to 32 levels
	int hbins = 30, sbins = 32;
	int histSize[] = {hbins, sbins};
	// hue varies from 0 to 179, see cvtColor
	float hranges[] = { 0, 180 };
	// saturation varies from 0 (black-gray-white) to
	// 255 (pure spectrum color)
	float sranges[] = { 0, 256 };
	const float* ranges[] = { hranges, sranges };
	MatND hist;
	// we compute the histogram from the 0-th and 1-st channels
	int channels[] = {0, 1};
	calcHist( &hsv, 1, channels, Mat(), // do not use mask
	hist, 2, histSize, ranges,
	true, // the histogram is uniform
	false );
	double maxVal=0;
	minMaxLoc(hist, 0, &maxVal, 0, 0);
	int scale = 10;
	Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
	for( int h = 0; h < hbins; h++ )
	for( int s = 0; s < sbins; s++ )
	{
		float binVal = hist.at<float>(h, s);
		int intensity = cvRound(binVal*255/maxValue);
		cvRectangle( histImg, Point(h*scale, s*scale),
		Point( (h+1)*scale - 1, (s+1)*scale - 1),
		Scalar::all(intensity),
		CV_FILLED );
	}
	namedWindow( "Source", 1 );
	imshow( "Source", src );
	namedWindow( "H-S Histogram", 1 );
	imshow( "H-S Histogram", histImg );
}


你可能感兴趣的:(直方图 单通道 多通道)