2015-09-14 68 views
1

我在OpenCV的代碼工作得很好,直到當我想找到輪廓opencv的未處理異常contour.exe

findContours(src, contours,hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); 

然後我不斷收到以下錯誤:

"Unhandled exception at 0x773e3e28 in Contour.exe: Microsoft C++ exception: cv::Exception at memory location 0x002ff3ac.."

你對這個錯誤有什麼想法嗎?

我的完整代碼如下。

感謝

Mat src=Mat(100,200,CV_64F),newimg; 
vector<vector<Point>> contours; 
vector<Vec4i> hierarchy; 

for (int i=25;i<80;i++) 
    for(int j=25;j<80;j++) 
     src.at<double>(i,j)=1; 
imshow("img",src); 
waitKey(0); 

findContours(src, contours,hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); 
+0

findContours只接受CV_8UC1圖像(特別是CV_32SC1)。您傳遞的是CV_64F而不是 – Miki

+0

您通常將邊緣檢測器(E.G. Canny)應用於圖像,然後取出Canny輸出並將其送入邊緣檢測器。函數findContours接受一個CV_8UC1圖像來尋找輪廓。 –

+0

@Masoud然後檢查你是否在調試模式下使用版本庫,或反之亦然 – Miki

回答

1

來自OpenCV的文件引述有關findContours

image – Source, an 8-bit single-channel image. Non-zero pixels are treated as 1’s. Zero pixels remain 0’s, so the image is treated as binary . You can use compare() , inRange() , threshold() , adaptiveThreshold() , Canny() , and others to create a binary image out of a grayscale or color one. The function modifies the image while extracting the contours. If mode equals to CV_RETR_CCOMP or CV_RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1).

你可以調整你的代碼,你CV_64FC1圖像轉換爲CV_8UC1,如:

... 
Mat1b img8u; 
src.convertTo(img8u, CV_8U); 

vector<vector<Point>> contours; 
vector<Vec4i> hierarchy; 

findContours(img8u, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); 
... 

另外,從評論中可以看出,您使用的是Visual Studio 2010,但將使用msvc11(Visual Studio 2012)構建的OpenCV鏈接起來。

您需要使用Visual Studio 2012或使用msvc10(Visual Studio 2010)重新編譯OpenCV。如果您決定升級VS,則可以直接轉到VS2013(並鏈接到vc12)或VS2015(但您需要重新編譯OpenCV)。

0

你的問題是當你需要一個CV_8UC1圖像時,你會給「findContours」一個CV_64F圖像。您通常會將findContours傳遞給邊緣檢測器的輸出。 (E.G. Canny)。

如果將代碼修改爲以下代碼,可以通過Canny進行過濾後在圖像中找到輪廓。

Mat src=Mat(100,200,CV_64F),newimg; 
Mat tCannyMat; 
vector<vector<Point>> contours; 
vector<Vec4i> hierarchy; 

for (int i=25;i<80;i++) 
    for(int j=25;j<80;j++) 
     src.at<double>(i,j)=1; 
imshow("img",src); 
waitKey(0); 

int lowThreshold = 0x3f;//This is the single value threshold 
int ratio = 3;//This is the ratio to apply for the entire pixel 
int kernel_size = 3;//This is the canny kernel size 

//You can use your own edge detector/a different one here if you wish. 
//Canny merely serves to give a working example. 
cv::Canny(src, tCannyMat, lowThreshold, lowThreshold*ratio, kernel_size); 

findContours(tCannyMat, contours,hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); 
+0

我見過的最混亂的'Canny'電話:D。你也不需要Canny來使它工作。 – Miki

+0

@Miki哈哈,當我看到這個問題時,它直接從我正在處理的項目中複製。 (我有各種值動態分配,但我決定保持變量,因爲它是一個很好的方式來操縱函數。) –

+0

謝謝你們,但即使我將它轉換爲CV_8UC1並使用Canny(或即使沒有Canny)! – mask