2017-10-05 122 views
0

我試圖在OpenCV 3.2中創建材質的直方圖,但被HSV範圍弄糊塗 - 它們似乎與文檔不匹配,或者我接近錯誤。OpenCV cvtColor CV_BGR2HSV CV_32FC3飽和度範圍

// cv::Mat bgrPhoto contains a test image 

cv::Mat3f hsvPhoto; 
bgrPhoto.convertTo(hsvPhoto, CV_32FC3); 
cv::cvtColor(hsvPhoto, hsvPhoto, CV_BGR2HSV, CV_32FC3); 
std::vector<cv::Mat1f> hsvChannels; 
cv::split(hsvPhoto, hsvChannels); 

// Documentation [0.0, 1.0]: measured here Hue to 360.0, Sat to 1.0, Val to 255.0 
double minHue, maxHue, minSat, maxSat, minVal, maxVal; 
cv::minMaxIdx(hsvChannels[0], &minHue, &maxHue, 0, 0); 
cv::minMaxIdx(hsvChannels[1], &minSat, &maxSat, 0, 0); 
cv::minMaxIdx(hsvChannels[2], &minVal, &maxVal, 0, 0); 
+0

OpenCV存儲來自[0 - 255]的[0 - 180],'S'和'V'值的'H'通道值。對於'float',相應地轉換值。 – zindarod

+0

H [0,360],S,V in [0,1]。請參閱[文檔](http://docs.opencv.org/master/de/d25/imgproc_color_conversions.html#color_convert_rgb_hsv)。此外,您正在嘗試使用21(CV_32FC3評估爲21)目標通道創建輸出圖像。只需使用'cv :: cvtColor(hsvPhoto,hsvPhoto,CV_BGR2HSV);'。另外'bgrPhoto.convertTo(hsvPhoto,CV_32F);'因爲只需要指定類型而不是深度。 – Miki

回答

1

當您將圖像從8位轉換爲32位時,您尚未將值從[0,255]縮放爲[0,1]。 convertTo()只是轉換類型;它不會默認重新調整值。這會影響你的輸出,因爲從docs for color conversion from BGR to HSV,V簡單地被設置爲max(B, G, R)(這將是最多達到255的數字的最大值)。您會注意到在cvtColor()的文檔中,它對8位和16位圖像表示,它們被縮放以適合[0,1]範圍;但不適用於浮動圖像。但是,H通道和S通道仍然會縮放到正確的範圍,因爲它們使用V來縮放圖像。

當您執行bgrPhoto.convertTo(hsvPhoto, CV_32FC3)時,您需要除以255以將值設置爲[0,1]。如果您查看docs for convertTo(),您會注意到可以設置第三個位置參數,這是一個比例因子。如文檔所述,只需使用bgrPhoto.convertTo(hsvPhoto, CV_32FC3, 1.0/255.0)即可按該因子縮放每個像素值。另外,Miki對OP的評論中的觀點完全滑落了我,但這是一個很棒的發現;檢查docs for cvtColor();第四個參數是參數的目標通道數量,而不是dtype,所以cv::cvtColor(hsvPhoto, hsvPhoto, CV_BGR2HSV)是你想要的。

+0

可以提一下,你可以直接在convertTo函數中做到這一點:'bgrPhoto.convertTo(hsvPhoto,CV_32F,1.0/255.0);' – Miki

+0

感謝@Miki,現在鏈接更多的文檔。 –

+0

謝謝亞歷山大 - 傑出的答案! – Ike