我有什麼應該是一個簡單的OpenCV練習,但似乎無法讓它工作。我試圖確定圖像的一部分邊緣的密度。這是我遵循的過程: 1.從圖像中拉取子圖像 2.使用Canny在子圖像中查找邊緣 3.用於創建二值圖像的閾值 4.爲二值圖像創建直方圖 5.獲取二值圖像中的像素數(255) 6.計算「邊緣密度」爲numPixelsOn/totalPixels從OpenCV直方圖獲取值
我檢查了上述1,2和3的結果,並且結果看起來不錯。步驟4和5似乎給我帶來麻煩。
這裏是我的計算直方圖代碼:
int histSize = 256; // bin size
float range[] = { 0, 256} ;
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat hist;
/// Compute the histograms:
calcHist(&gray, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
這似乎並不奏效。當我調用calcHist後檢查hist時,它沒有數據(即數據== 0)...或者我不明白我在看什麼。
現在爲了訪問直方圖中的「容器」,我嘗試了一些東西。首先,我想這:
uchar* p;
p = hist.ptr<uchar>(0);
double edgePixels = p[255];
我還試圖用:
cvQueryHistValue_1D(hist,255); // #include <opencv2/legacy/compat.hpp>
這不會編譯。給出2個錯誤:'cv :: Mat'沒有重載成員'operator - >'和'bin':不是'cv :: Mat'的成員
我想我需要一些幫助。
爲什麼你需要一個直方圖?是不是更容易只是遍歷梯度圖像或只是使用sum(I)/ 255來獲取像素數目?最後,使用Canny並不是一個好主意,因爲它非常非線性,因此重複性差。最好使用簡單的Sobel求和sqrt(hor_grad^2 + ver_grad^2)來獲得更好的邊緣度量。 – Vlad
@Vlad - 感謝您的建議。雖然我很欣賞在直方圖上獲得幫助,但您的意見是有道理的。我不完全理解你對如何使用Sobel獲得更好的「邊緣」度量的評論。你是否建議我簡單地使用cv :: Sobel函數而不是cv :: Canny?再次感謝! –
我建議您使用絕對值(平方和的平方或平方)作爲絕對梯度的估計值。它比Canny更快更穩定。後者執行大量的非線性操作,因此如果您需要這些屬性,則不是很好的重複性和匹配性。另一方面,即使對於弱連續邊緣也是敏感的。 – Vlad