2013-03-04 77 views
4

我已經多次閱讀calcHist()的文檔,但我認爲我對OpenCV和生鏽的編程技巧的經驗不足,完全妨礙我理解它。OpenCV - 混淆使用calcHist

我正在尋找一個HSV圖像(色調,或通道[0])的一個通道中的像素進行分割的目的,它使用十個接近於顏色的接收器,根據類似的東西(讓我們用這個作爲例子,I偷範圍斷網 - FWIW,似乎錯誤省略紫紅色):

紅:0-19 & 330-360 紅黃色(RY):20-49 黃色:50-69 YG:70-84 綠色:85-170 GB:171-191 藍色:192-264 BP:265-289 紫色:290-329

依此類推...

那麼我該如何用calcHist做到這一點?

我儘可能:

#include <opencv2/opencv.hpp> 
#include <vector> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream> 

using namespace std; 
using namespace cv; 

int main(int argc, char *argv[]) 
{ 
    Mat scene, sceneHSV, dest, histo; 
    int numImages = 1, histChannel[] = {0}, dims = 1, histSize[] = {10}; 

    float redRange[] = {0, 10}; 
    float roRange[] = {10, 25}; 
    float orangeRange[] = {25, 35}; 
    float oyRange[] = {35, 42}; 
    float yellowRange[] = {42, 85}; 
    float ygRange[] = {85, 96}; 
    float greenRange[] = {96, 132}; 
    float gbRange[] = {132, 145}; 
    float blueRange[] = {145, 160}; 
    float bpRange[] = {160, 165}; 
    float purpleRange[] = {165, 180}; 

    const float* ranges[] = {redRange, roRange, orangeRange, oyRange, yellowRange, ygRange, greenRange, gbRange, blueRange, bpRange, purpleRange}; 

    vector<Mat> channels; 

    scene = imread("Apple.jpg", 1); 
    if (scene.data == NULL) 
    { 
     cout<<"FAIL"<<endl; 
     cin.get(); 
    } 

    cvtColor(scene, sceneHSV, CV_BGR2HSV); 
    dilate(sceneHSV, sceneHSV, Mat(), Point(-1, -1), 1, BORDER_CONSTANT, 1); 
    pyrMeanShiftFiltering(sceneHSV, dest, 2, 50, 3); 
    split(sceneHSV, channels); 

    calcHist(&scene, 1, histChannel, Mat(), histo, dims, histSize, ranges, false, false); 

    cout<<histo<<endl; 

    waitKey(0); 

    return 0; 
} 

現在怎麼辦?在這種情況下,calcHist的參數會是什麼樣子?輸出直方圖的外觀如何?只是一個1x9陣列的整個int?

非常感謝。

回答

4

我從here

修改了代碼,您可能也想看看cvtColor的here

請注意,我還沒有試過編譯或運行這段代碼,所以我不保證文檔它會工作。但是,它可能是有用的參考。

Mat hist; 
int nimages = 1; // Only 1 image, that is the Mat scene. 
int channels[] = {0} // Index for hue channel 
int dims = 1 // Only 1 channel, the hue channel 
int histSize[] = {9} // 9 bins, 1 each for Red, RY, Yellow, YG etc. 
float hranges[] = { 0, 180 }; // hue varies from 0 to 179, see cvtColor 
const float *ranges[] = {hranges}; 

// Compute the histogram. 
calcHist(&scene, 
nimages, 
channels, 
Mat(), // No mask 
hist, dims, histSize, ranges, uniform=true) 

// Now hist will contain the counts in each bin. 
// Lets just print out the values. Note that you can output Mat using std::cout 
cout << "Histogram: " << endl << hist << endl; 

// To access the individual bins, you can either iterate over them 
// or use hist.at<uchar>(i, j); Note that one of the index should be 0 
// because hist is 1D histogram. Print out hist.rows and hist.cols to see if hist is a N x 1 or 1 x N matrix. 
/* 
MatIterator_<uchar> it, end; 
int binIndex = 0; 
for(it = hist.begin<uchar>(), end = hist.end<uchar>(); it != end; ++it) 
{ 
    printf("Count in %d bin: %d\n", binIndex, *it); 
    ++binIndex; 
} 
*/ 
+0

我會試試這個,雖然還有一些其他的東西 - 我注意到OpenCV的HSV範圍從0-180變化,所以我只需要將所有這些範圍縮小一半 - 感謝您的提醒。 – TonyRo 2013-03-05 02:20:59

+0

另外,上述說明如何考慮顏色不均勻間隔的範圍? – TonyRo 2013-03-05 03:48:08

+1

我認爲如果您在將矩陣轉換爲cvtColor(...)之前將矩陣轉換爲CV_32F或CV_64F,則色相的範圍將在0至360之間。要處理不均勻間隔的範圍,需要更改一些內容。首先,將「統一」參數設置爲false。其次,將hranges改爲浮動hranges [] = {0,20,20,50,50,70,...,Li,Ui,...},其中hranges包含histSize [i] +1元素,即1比你的箱子數量多。 Li,Ui是垃圾箱i的相應較低(含)和較高(獨佔)邊界。請參閱上面給出的calcHist的鏈接以獲取更多詳細信息。希望這可以幫助。 – lightalchemist 2013-03-05 04:24:19