基於C++/opencv 提取圖像的直方圖


 一個圖像是由不同顏色值的像素組成的,像索值在圖像中的分布情況是這幅圖像的一個重要特征。圖像是由像素組成的,在一個單通道的灰度圖像中,每個像素的值介於0(黑色)-

255(白色)之間。根據圖像的內容,你會發現每個灰度值的像素數目是不同的。

直方圖是一個簡單的表,它給出了一幅圖像或一組圖像中擁有給定數值的像素數量。因此,灰度圖像的直方圖有256個條目(或稱為容器)。0號容器給出值為0的像素個數,1號容器給出值為1的像素個數,依此類推。顯然,如果你對方圖的所有項求和,會得到像素的總數。直方圖也可以被歸一化,歸一化后的所有項之和等於1。在這種情況下,每一項給出的都是擁有特定數值的像素在圖像中占的比例。

謝謝原博:http://blog.csdn.net/andrewseu/article/details/49616279

     http://blog.csdn.net/garfielder007/article/details/49931049

以下是兩種提取圖像直方圖的方法:

法一:

 1 // test1_320平滑處理.cpp : 定義控制台應用程序的入口點。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include"iostream"
 6 #include<cv.h>
 7 #include <opencv2/core/core.hpp>
 8 #include<opencv2/imgproc/imgproc.hpp>
 9 #include <opencv2/highgui/highgui.hpp>
10 using namespace std;
11 using namespace cv;
12 
13 
14 int _tmain(int argc, _TCHAR* argv[])
15 {
16 IplImage* src = cvLoadImage("Blind.jpg");
17 IplImage* hsv = cvCreateImage(cvGetSize(src), 8, 3);
18 IplImage* h_plane = cvCreateImage(cvGetSize(src), 8, 1);
19 IplImage* s_plane = cvCreateImage(cvGetSize(src), 8, 1);
20 IplImage* v_plane = cvCreateImage(cvGetSize(src), 8, 1);
21 IplImage* planes[] = {h_plane,s_plane};
22 
23 //H分量划分為16個等級,S分量划分為8個等級
24 int h_bins = 16, s_bins = 8;
25 int hist_size[] = { h_bins, s_bins };
26 
27 //H分量的變化范圍
28 float h_ranges[] = { 0, 180 };
29 //S分量的變化范圍
30 float s_ranges[] = { 0, 255 };
31 float* ranges[] = { h_ranges, s_ranges };
32 //輸入圖像轉到HSV顏色空間
33 cvCvtColor(src, hsv, CV_BGR2HSV);
34 cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane,0);
35 //創建直方圖,二維,每個維度上均分
36 CvHistogram * hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
37 //根據H,S兩個平面數據統計直方圖
38 cvCalcHist(planes, hist, 0, 0);
39 //獲取直方圖統計的最大值,用於動態顯示直方圖
40 float max_value;
41 cvGetMinMaxHistValue(hist, 0, &max_value, 0, 0);
42 //設置直方圖顯示圖像
43 int height = 240;
44 int width = (h_bins*s_bins * 6);
45 IplImage* hist_Img = cvCreateImage(cvSize(width, height), 8, 3);
46 cvZero(hist_Img);
47 //用來進行HSV到RGB顏色轉換的臨時單位圖像
48 IplImage * hsv_color = cvCreateImage(cvSize(1, 1), 8, 3);
49 IplImage * rgb_color = cvCreateImage(cvSize(1, 1), 8, 3);
50 int bin_w = width / (h_bins*s_bins);
51 for (int h = 0; h < h_bins;h++)
52 {
53 for (int s = 0; s < s_bins;s++)
54 {
55 int i = h*s_bins + s;
56 //獲取直方圖中的統計次數,計算顯示在圖像中的高度
57 float bin_val = cvQueryHistValue_2D(hist, h, s);
58 int intensity = cvRound(bin_val*height / max_value);
59 //獲取當前直方圖代表的顏色,轉換成RGB用於繪制
60 cvSet2D(hsv_color, 0, 0, cvScalar(h*180.f / h_bins, s*255.f / s_bins, 255,0));
61 cvCvtColor(hsv_color, rgb_color, CV_HSV2BGR);
62 CvScalar color = cvGet2D(rgb_color, 0, 0);
63 cvRectangle(hist_Img, cvPoint(i*bin_w, height),
64 cvPoint((i+1)*bin_w,height-intensity),color,-1,8,0);
65 }
66 }
67 cvNamedWindow("Source", 1);
68 cvShowImage("Source", src);
69 cvNamedWindow("H-S Histogram", 1);
70 cvShowImage("H-S Histogram", hist_Img);
71 cvWaitKey(0);
72 return 0;
73 }

 

 法二:

  1 // test2_321.cpp : 定義控制台應用程序的入口點。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include<iostream>
  6 #include<opencv2/opencv.hpp>  
  7 #include <opencv2/core/core.hpp>
  8 #include<opencv2/imgproc/imgproc.hpp>
  9 #include <opencv2/highgui/highgui.hpp>
 10 using namespace std;
 11 using namespace cv;
 12 
 13 class HistogramND
 14 {
 15 private:
 16     Mat image;//源圖像  
 17     int hisSize[1], hisWidth, hisHeight;//直方圖的大小,寬度和高度  
 18     float range[2];//直方圖取值范圍  
 19     const float *ranges;
 20     Mat channelsRGB[3];//分離的BGR通道  
 21     MatND outputRGB[3];//輸出直方圖分量  
 22 public:
 23     HistogramND(){
 24         hisSize[0] = 256;
 25         hisWidth = 400;
 26         hisHeight = 400;
 27         range[0] = 0.0;
 28         range[1] = 256.0;
 29         ranges = &range[0];
 30     }
 31 
 32     //導入圖片  
 33     bool importImage(String path){
 34         image = imread(path);
 35         if (!image.data)
 36             return false;
 37         return true;
 38     }
 39 
 40     //分離通道  
 41     void splitChannels(){
 42         split(image, channelsRGB);
 43     }
 44 
 45     //計算直方圖  
 46     void getHistogram(){
 47         calcHist(&channelsRGB[0], 1, 0, Mat(), outputRGB[0], 1, hisSize, &ranges);
 48         calcHist(&channelsRGB[1], 1, 0, Mat(), outputRGB[1], 1, hisSize, &ranges);
 49         calcHist(&channelsRGB[2], 1, 0, Mat(), outputRGB[2], 1, hisSize, &ranges);
 50 
 51         //輸出各個bin的值  
 52         for (int i = 0; i < hisSize[0]; ++i){
 53             cout << i << "   B:" << outputRGB[0].at<float>(i);
 54             cout << "   G:" << outputRGB[1].at<float>(i);
 55             cout << "   R:" << outputRGB[2].at<float>(i) << endl;
 56         }
 57     }
 58 
 59     //顯示直方圖  
 60     void displayHisttogram(){
 61         Mat rgbHist[3];
 62         for (int i = 0; i < 3; i++)
 63         {
 64             rgbHist[i] = Mat(hisWidth, hisHeight, CV_8UC3, Scalar::all(0));
 65         }
 66         normalize(outputRGB[0], outputRGB[0], 0, hisWidth - 20, NORM_MINMAX);
 67         normalize(outputRGB[1], outputRGB[1], 0, hisWidth - 20, NORM_MINMAX);
 68         normalize(outputRGB[2], outputRGB[2], 0, hisWidth - 20, NORM_MINMAX);
 69         for (int i = 0; i < hisSize[0]; i++)
 70         {
 71             int val = saturate_cast<int>(outputRGB[0].at<float>(i));
 72             rectangle(rgbHist[0], Point(i * 2 + 10, rgbHist[0].rows), 
 73                 Point((i + 1) * 2 + 10, rgbHist[0].rows - val), Scalar(0, 0, 255), 1, 8);
 74             val = saturate_cast<int>(outputRGB[1].at<float>(i));
 75             rectangle(rgbHist[1], Point(i * 2 + 10, rgbHist[1].rows), Point((i + 1) * 2 + 10, 
 76                 rgbHist[1].rows - val), Scalar(0, 255, 0), 1, 8);
 77             val = saturate_cast<int>(outputRGB[2].at<float>(i));
 78             rectangle(rgbHist[2], Point(i * 2 + 10, rgbHist[2].rows), Point((i + 1) * 2 + 10, 
 79                 rgbHist[2].rows - val), Scalar(255, 0, 0), 1, 8);
 80         }
 81 
 82         cv::imshow("R", rgbHist[0]);
 83         imshow("G", rgbHist[1]);
 84         imshow("B", rgbHist[2]);
 85         imshow("image", image);
 86     }
 87 };
 88 
 89 
 90 
 91 
 92 int _tmain(int argc, _TCHAR* argv[])
 93 {
 94     String path = "D:\\LiHong\\Blind Way Recognition\\MyProject\\test2_321\\test2_321\\Blind.jpg";
 95     /*cv::Mat img = cv::imread("Blind.jpg");*/
 96     HistogramND hist;
 97     /*if (!img.data)
 98     {
 99         return -1;
100     }*/
101     if (!hist.importImage(path)){
102         cout << "Import Error!" << endl;
103         return -1;
104     }
105     hist.splitChannels();
106     hist.getHistogram();
107     hist.displayHisttogram();
108     cv::waitKey();
109 
110 
111     return 0;
112 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM