Histogram obrazu

Histogram dla obrazuw odcieniach szarości 

Aby stworzyć histogram w OpenCV można użyć funkcji calcHist(); 

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

using namespace std;
using namespace cv;

int main(){
  Mat dst;

  Mat img = imread("/LENA_512.jpg", 1 );
  cvtColor(img, img, CV_BGR2GRAY);

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

  /// Set the ranges )
  float range[] = { 0, 256 } ;
  const float* histRange = { range };

  bool uniform = true; 
  bool accumulate = false;

  Mat grey_hist;

  /// Compute the histograms:
  calcHist( &img, 1, 0, Mat(), grey_hist, 1, &histSize, &histRange, uniform, accumulate );

  // Draw the histograms 
  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(grey_hist, grey_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(grey_hist.at<float>(i-1)) ) ,
    Point( bin_w*(i), hist_h - cvRound(grey_hist.at<float>(i)) ),
    Scalar( 120, 120, 120), 2, 8, 0  );
  }

  /// Display
  namedWindow("Hist", CV_WINDOW_AUTOSIZE );
  imshow("Hist", histImage )
  waitKey(0);
  return 0;
}

Wygładzenie Histogramu 

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

using namespace std;
using namespace cv;

int main(){
  Mat dst;
  Mat img = imread("./LENA_512.jpg", 1 );
  cvtColor(img, img, CV_BGR2GRAY);

  int histSize = 256;
  float range[] = { 0, 256 } ;
  const float* histRange = { range };

  bool uniform = true; 
  bool accumulate = false;

  Mat grey_hist;

  calcHist( &img, 1, 0, Mat(), grey_hist, 1, &histSize, &histRange, uniform, accumulate );
  Mat smoothed_his = grey_hist.clone();;
  for(int i = 2; i < grey_hist.rows - 2; ++i){
    smoothed_his.at<float>(i) = (grey_hist.at<float>(i-2) + grey_hist.at<float>(i-1) + grey_hist.at<float>(i) + grey_hist.at<float>(i+1) + grey_hist.at<float>(i+2)) / 5;
  }
  
  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(grey_hist, grey_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
  normalize(smoothed_his, smoothed_his, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
  
  for( int i = 1; i < histSize; i++ ){
    line( histImage, Point( bin_w*(i-1), hist_h - cvRound(grey_hist.at<float>(i-1)) ) ,
    Point( bin_w*(i), hist_h - cvRound(grey_hist.at<float>(i)) ),
    Scalar( 120, 120, 120), 2, 8, 0  );
    line( histImage, Point( bin_w*(i-1), hist_h - cvRound(smoothed_his.at<float>(i-1)) ) ,
    Point( bin_w*(i), hist_h - cvRound(smoothed_his.at<float>(i)) ),
    Scalar( 0, 0, 255), 2, 8, 0  );
  }
  namedWindow("Hist", CV_WINDOW_AUTOSIZE );
  imshow("Hist", histImage );
  waitKey(0);
  return 0;

Histogram dla zdjęć kolorowych 

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

using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
  Mat dst;

  /// Load image
  Mat img = imread("./LENA_512.jpg", 1 );
  
  /// Separate the image in 3 places ( B, G and R )
  vector bgr_planes;
  split( img, 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("Hist", CV_WINDOW_AUTOSIZE );
  imshow("Hist", histImage );
  waitKey(0);

  return 0;
}

Wyrównywanie Histogramu (obraz w odcienich szarości) 

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

using namespace cv;
using namespace std;

int main(){
  Mat src, dst;

  char* source_window = "Source image";
  char* equalized_window = "Equalized Image";

  /// Load image
  src =  imread("./LENA_512.jpg", 1 );

  /// Convert to grayscale
  cvtColor( src, src, CV_BGR2GRAY );

  /// Apply Histogram Equalization
  equalizeHist( src, dst );

  /// Display results
  namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

  imshow( source_window, src );
  imshow( equalized_window, dst );
   
  /// Wait until user exits the program
  waitKey(0);

  return 0;
}

Wyrównywanie Histogramu (obraz kolorowy) 

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

using namespace cv;
using namespace std;

int main(){
  Mat src, dst;

  char* source_window = "Source image";
  char* equalized_window = "Equalized Image";

  /// Load image
  src =  imread("./LENA_512.jpg", 1 );
  vector<Mat> channels;
  cvtColor( src, src, CV_BGR2YCrCb );
  
  split(src, channels); 
  equalizeHist(channels[0], channels[0]); 
  
  merge(channels, dst); 

  cvtColor(dst, dst, CV_YCrCb2BGR); 

  /// Display results
  namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

  imshow( equalized_window, dst );
  waitKey(0);
  return 0;
}

Rozciągnięcie histogramu (zdjęcie w odcieniach szarości) 

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

using namespace cv;
using namespace std;

int main(){
  Mat src, dst;

  char* source_window = "Source image";
  char* equalized_window = "Equalized Image";

  /// Load image
  src =  imread("./LENA_512.jpg", 1 );

  /// Convert to grayscale
  cvtColor( src, src, CV_BGR2GRAY );

  /// Apply Histogram Equalization
  normalize( src, dst, 0, 255, CV_MINMAX);
  
  /// Display results
  namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

  imshow( source_window, src );
  imshow( equalized_window, dst );
  waitKey(0);
  return 0;
}

Rozciągnięcie histogramu (zdjęcie kolorowe) 

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

using namespace cv;
using namespace std;

int main(){
  Mat src, dst;

  char* source_window = "Source image";
  char* equalized_window = "Equalized Image";

  /// Load image
  src =  imread("./LENA_512.jpg", 1 );
  vector<Mat> channels;
  cvtColor( src, src, CV_BGR2YCrCb );
  split(src, channels); 
  normalize( channels[0], channels[0], 0, 255, CV_MINMAX);
  merge(channels, dst); 
  cvtColor(dst, dst, CV_YCrCb2BGR);

  /// Display results
  namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

  imshow( equalized_window, dst );  
  waitKey(0);
  return 0;
}

Porównanie Histogramów (odcienie szarości) 

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

using namespace std;
using namespace cv;

int main(){
  Mat src_1 = imread( "./c1.jpg", 1 );
  Mat src_2 = imread( "./c2.jpg", 1 );
  Mat src_3 = imread( "./c3.jpg", 1 );
  Mat src_4 = imread( "./c4.jpg", 1 );
  Mat src_5 = imread( "./c5.jpg", 1 );
  Mat src_6 = imread( "./c6.jpg", 1 );

  cvtColor( src_1, src_1, CV_BGR2GRAY );
  cvtColor( src_2, src_2, CV_BGR2GRAY );
  cvtColor( src_3, src_3, CV_BGR2GRAY );
  cvtColor( src_4, src_4, CV_BGR2GRAY );
  cvtColor( src_5, src_5, CV_BGR2GRAY );
  cvtColor( src_6, src_6, CV_BGR2GRAY );

  int histSize = 256; 
  float range[] = { 0, 256 } ;
  const float* histRange = { range };
  bool uniform = true; 
  bool accumulate = false;
 
  MatND hist_1;
  MatND hist_2;
  MatND hist_3;
  MatND hist_4;
  MatND hist_5;
  MatND hist_6;
  
  calcHist( &src_1 , 1, 0, Mat(), hist_1, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &src_2 , 1, 0, Mat(), hist_2, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &src_3 , 1, 0, Mat(), hist_3, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &src_4 , 1, 0, Mat(), hist_4, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &src_5 , 1, 0, Mat(), hist_5, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &src_6 , 1, 0, Mat(), hist_6, 1, &histSize, &histRange, uniform, accumulate );    
 
  normalize( hist_1, hist_1, 0, 1, NORM_MINMAX, -1, Mat() );
  normalize( hist_2, hist_2, 0, 1, NORM_MINMAX, -1, Mat() );
  normalize( hist_3, hist_3, 0, 1, NORM_MINMAX, -1, Mat() );
  normalize( hist_4, hist_4, 0, 1, NORM_MINMAX, -1, Mat() );
  normalize( hist_5, hist_5, 0, 1, NORM_MINMAX, -1, Mat() );
  normalize( hist_6, hist_6, 0, 1, NORM_MINMAX, -1, Mat() );

  /// Apply the histogram comparison methods
  for( int i = 0; i < 4; i++ ){
    int compare_method = i;
    double base_1 = compareHist( hist_1, hist_1, compare_method );
    double base_2 = compareHist( hist_1, hist_2, compare_method );
    double base_3 = compareHist( hist_1, hist_3, compare_method );
    double base_4 = compareHist( hist_1, hist_4, compare_method );
    double base_5 = compareHist( hist_1, hist_5, compare_method );
    double base_6 = compareHist( hist_1, hist_6, compare_method );
    printf( " Method [%d] : %f, %f, %f, %f, %f, %f \n", i, base_1, base_2, base_3, base_4, base_5, base_6);
  }
  return 0;
}

Histpgram 2D 

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

using namespace std;
using namespace cv;

int main(){

  Mat hsv;
  Mat src = imread( "./LENA_512.jpg", 1 );

  cvtColor(src, hsv, CV_BGR2HSV);

  // 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(), hist, 2, histSize, ranges,true, 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/maxVal);
      rectangle( 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 );     
    waitKey();
}

Porównanie histogramów 2D 

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

using namespace std;
using namespace cv;

int main(){
    
  Mat src_1 = imread( "./c1.jpg", 1 );
  Mat src_2 = imread( "./c2.jpg", 1 );
  Mat src_3 = imread( "./c3.jpg", 1 );
  Mat src_4 = imread( "./c4.jpg", 1 );
  Mat src_5 = imread( "./c5.jpg", 1 );
  Mat src_6 = imread( "./c6.jpg", 1 );
    
  cvtColor( src_1, src_1, COLOR_BGR2HSV );
  cvtColor( src_2, src_2, COLOR_BGR2HSV );
  cvtColor( src_3, src_3, COLOR_BGR2HSV );
  cvtColor( src_4, src_4, COLOR_BGR2HSV );
  cvtColor( src_5, src_5, COLOR_BGR2HSV );
  cvtColor( src_6, src_6, COLOR_BGR2HSV );
    
  /// Using 50 bins for hue and 60 for saturation
  int h_bins = 50; int s_bins = 60;
  int histSize[] = { h_bins, s_bins };

  // hue varies from 0 to 179, saturation from 0 to 255
  float h_ranges[] = { 0, 180 };
  float s_ranges[] = { 0, 256 };

  const float* ranges[] = { h_ranges, s_ranges };

  // Use the o-th and 1-st channels
  int channels[] = { 0, 1 };
  MatND hist_1, hist_2, hist_3, hist_4, hist_5, hist_6;

  calcHist( &src_1, 1, channels, Mat(), hist_1, 2, histSize, ranges, true, false );
  normalize( hist_1, hist_1, 0, 1, NORM_MINMAX, -1, Mat() );
   
  calcHist( &src_2, 1, channels, Mat(), hist_2, 2, histSize, ranges, true, false );
  normalize( hist_2, hist_2, 0, 1, NORM_MINMAX, -1, Mat() );
    
  calcHist( &src_3, 1, channels, Mat(), hist_3, 2, histSize, ranges, true, false );
  normalize( hist_3, hist_3, 0, 1, NORM_MINMAX, -1, Mat() );
    
  calcHist( &src_4, 1, channels, Mat(), hist_4, 2, histSize, ranges, true, false );
  normalize( hist_4, hist_4, 0, 1, NORM_MINMAX, -1, Mat() );
    
  calcHist( &src_5, 1, channels, Mat(), hist_5, 2, histSize, ranges, true, false );
  normalize( hist_5, hist_5, 0, 1, NORM_MINMAX, -1, Mat() );
    
  calcHist( &src_6, 1, channels, Mat(), hist_6, 2, histSize, ranges, true, false );
  normalize( hist_6, hist_6, 0, 1, NORM_MINMAX, -1, Mat() );

  /// Apply the histogram comparison methods
  for( int i = 0; i < 4; i++ ){
    int compare_method = i;
    double base_1 = compareHist( hist_1, hist_1, compare_method );
    double base_2 = compareHist( hist_1, hist_2, compare_method );
    double base_3 = compareHist( hist_1, hist_3, compare_method );
    double base_4 = compareHist( hist_1, hist_4, compare_method );
    double base_5 = compareHist( hist_1, hist_5, compare_method );
    double base_6 = compareHist( hist_1, hist_6, compare_method );

    printf( " Method [%d] : %f, %f, %f, %f, %f, %f \n", i, base_1, base_2, base_3, base_4, base_5, base_6);
  }

  return 0;
}

Porównanie histogramów 2D 

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

using namespace std;
using namespace cv;

int main(){
  Mat src_base, hsv_base;
  Mat src_test1, hsv_test1;
  Mat src_test2, hsv_test2;

  src_base = imread( "./s1.jpg", 1 );
  src_test1 = imread( "./s2.jpg", 1 );
  src_test2 = imread( "./s3.jpg", 1 );

  /// Convert to HSV
  cvtColor( src_base, hsv_base, COLOR_BGR2HSV );
  cvtColor( src_test1, hsv_test1, COLOR_BGR2HSV );
  cvtColor( src_test2, hsv_test2, COLOR_BGR2HSV );

  /// Using 50 bins for hue and 60 for saturation
  int h_bins = 50; int s_bins = 60;
  int histSize[] = { h_bins, s_bins };

  // hue varies from 0 to 179, saturation from 0 to 255
  float h_ranges[] = { 0, 180 };
  float s_ranges[] = { 0, 256 };

  const float* ranges[] = { h_ranges, s_ranges };

  // Use the o-th and 1-st channels
  int channels[] = { 0, 1 };


  /// Histograms
  MatND hist_base;
  MatND hist_test1;
  MatND hist_test2;

  /// Calculate the histograms for the HSV images
  calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
  normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );

  calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );
  normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );

  calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );
  normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );

  /// Apply the histogram comparison methods
  for( int i = 0; i < 4; i++ ){
    int compare_method = i;
    double base_base = compareHist( hist_base, hist_base, compare_method );
    double base_test1 = compareHist( hist_base, hist_test1, compare_method );
    double base_test2 = compareHist( hist_base, hist_test2, compare_method );
    printf( " Method [%d] : %f, %f, %f \n", i, base_base , base_test1, base_test2 );
  }
  return 0;
}

Back-projection 

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

using namespace std;
using namespace cv;
int main(){
  Mat img = imread( "./LENA_512.jpg", 1 );
  cvtColor(img, img, CV_BGR2GRAY);
  for(int i = 1; i < 10; i++){
    Mat grey_hist;
    int histSize = i;
    float range[] = { 0, 256 } ;
    const float* histRange = { range };
    bool uniform = true; 
    bool accumulate = false;
    calcHist( &img, 1, 0, Mat(), grey_hist, 1, &histSize, &histRange, uniform, accumulate );
    normalize(grey_hist , grey_hist, 0, 255, NORM_MINMAX, -1, Mat() );
    MatND backproj;
    calcBackProject( &img, 1, 0, grey_hist, backproj, &histRange, 1, true );   
  }
  waitKey(0);
  return 0;
}

Back-projection 

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

using namespace std;
using namespace cv;

/// Global Variables
Mat img; 
int bins = 25;

/// Function Headers
void Hist_and_Backproj(int, void* );

int main(){
  /// Read the image
  img = imread( "./LENA_512.jpg", 1 );
  /// Transform it to Grey
  cvtColor(img, img, CV_BGR2GRAY);


  /// Create Trackbar to enter the number of bins
  char* window_image = "Source image";
  namedWindow( window_image, CV_WINDOW_AUTOSIZE );
  createTrackbar("* Hue  bins: ", window_image, &bins, 255, Hist_and_Backproj );
  Hist_and_Backproj(0, 0);

  /// Show the image
  imshow( window_image, img );

  /// Wait until user exits the program
  waitKey(0);
  return 0;
}

void Hist_and_Backproj(int, void* ){
  Mat grey_hist;
  int histSize = MAX( bins, 2 );
  float range[] = { 0, 256 } ;
  const float* histRange = { range };
  bool uniform = true; 
  bool accumulate = false;
  

  calcHist( &img, 1, 0, Mat(), grey_hist, 1, &histSize, &histRange, uniform, accumulate );
  normalize(grey_hist , grey_hist, 0, 255, NORM_MINMAX, -1, Mat() );


  /// Get Backprojection
  MatND backproj;
  calcBackProject( &img, 1, 0, grey_hist, backproj, &histRange, 1, true );

  /// Draw the backproj
  imshow( "BackProj", backproj );

  /// Draw the histogram
  int w = 400; int h = 400;
  int bin_w = cvRound( (double) w / histSize );
  Mat histImg = Mat::zeros( w, h, CV_8UC3 );

  for( int i = 0; i < bins; i ++ )
     { rectangle( histImg, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound( grey_hist.at<float>(i)*h/255.0 ) ), Scalar( 0, 0, 255 ), -1 ); }

  imshow( "Histogram", histImg );
}