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