Opencv Unhandled exception in contour.exe - opencv

My code in OpenCV works well up until when I want to find contours:
findContours(src, contours,hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
then I keep getting the following error:
"Unhandled exception at 0x773e3e28 in Contour.exe: Microsoft C++
exception: cv::Exception at memory location 0x002ff3ac.."
Do you have any idea about this error?
My full code is below.
Thanks
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);

Quoting from OpenCV documentation about 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).
You can adjust your code converting your CV_64FC1 image to a CV_8UC1 like:
...
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);
...
In addition, from the comments turns out that you are using Visual Studio 2010, but linking OpenCV built with msvc11 (Visual Studio 2012).
You need either to use Visual Studio 2012, or recompile OpenCV with msvc10 (Visual Studio 2010). If you decide to upgrade VS, you can go directly to VS2013 (and link to vc12), or to VS2015 (but you need to recompile OpenCV as well).

Your problem is you are giving "findContours" a CV_64F image when it requires a CV_8UC1 image. You generally pass findContours the output of an edge detector. (E.G. Canny).
If you modify your code to the following you can find the contours in an image after filtering it through 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);

Related

OpenCV findcontours() crash

Cow browncow;
vector <Cow> Cows;
Mat temp;
threshold.copyTo(temp);
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
I'm making some code that needs to find the contours in a image, and my code breaks. My code breaks on the findContours(); function call and my debugger says
"An invalid parameter was passed to a function that considers invalid parameters fatal." any ideas why this is?
Try to use CV_RETR_TREE instead of CV_RETR_CCOMP. If it doesn't help I had once fixed findContours() with just switching to release mode of the build. Or look at Sagar's comment.
same error with me you can just copy
vector< vector > contours;
vector hierarchy;**
this and make these variables global outside your function and change the debug mode with release mode hope it will work...

opencv structured forest edge detection and findcontours

I am trying to use opencv via visual c++ to extract contours of an image. I was able to do that using the opencv tutorial for findcontours.
findcontours works in two steps
Detect edges using canny edge detector.
Feed the output of canny to findcontours.
I want to try out the same with 'Structured Forest Edge Detection' (Zitnick et al). I am able to extract the edges and display them, but when I try to feed the output to findcontours. I am getting a 'cv::Exception at memory location 0x0020EE9C' error. (see code below). What am I doing wrong?
Mat src = imread("image.jpg");
src.convertTo(src, CV_32F, 1.0 / 255.0);
Mat edges(src.size(), src.type());
Ptr<StructuredEdgeDetection> pDollar = createStructuredEdgeDetection("model.yml.gz");
pDollar->detectEdges(src, edges);
findContours(edges, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
pDollar->detectEdges(src, edges);
edges type is CV_32F. you must convert it to 8-bit single-channel image

OpenCV findContours destroying source image

I writing a code that draw circle, line and rectangle in a single channel blank image. After that I just find out the contour in the image and I am getting all the contour correctly. But after finding the contour my source image is getting distorted. Why this happening ? Any one can help me to solve it out. And my code look like below.
using namespace cv;
using namespace std;
int main()
{
Mat dst = Mat::zeros(480, 480, CV_8UC1);
Mat draw= Mat::zeros(480, 480, CV_8UC1);
line(draw, Point(100,100), Point(150,150), Scalar(255,0,0),1,8,0);
rectangle(draw, Rect(200,300,10,15), Scalar(255,0,0),1, 8,0);
circle(draw, Point(80,80),20, Scalar(255,0,0),1,8,0);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( draw, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color( 255,255,255);
drawContours( dst, contours, i, color, 1, 8, hierarchy );
}
imshow( "Components", dst );
imshow( "draw", draw );
waitKey(0);
}
Source image
Distorted source after finding contour
Documentation clearly states that source image is altered when using findContours.
http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours
See first note.
If you need the source image, you have to run findContours on copy.
try using
findContours( draw.clone(), contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
For me, the second image looks like what I would expect as a result from an edge detection algorithm. My guess is the findContours function overwrites the original image with the result found.
Have a look here.
I think that the problem is that you are expecting a perfect plot from the findContours and it gives you an ugly drawing.
FindContours is not gonna give an exact plot of your figures. You must use the drawContours in order to generate a properly image.
Look the reference here: http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours
You can see that the first parameter is Input/Output array. So the function uses the same array to open, modify and saving the image. That's why you are getting a distorted image.
In addition see the parameters explanation. When it talks about the first parameter it says: "The function modifies the image while extracting the contours."
I havn't worked a lot with findContours but i never had a clear image of what I wanted. I must use always the drawContours to get a nice plot of it.
Otherwise you can use the Canny function wich is gonna give you the edges instead of the contours.

findContours for blob finding

I'm using OpenCV's findContours() for blob-finding, by floodfilling at an arbitrary seed point in the contour and taking the bounding rectangle of the floodfill. However, when two blobs touch at a corner, e.g.
they share a contour, so only one of the two blobs will be floodfilled, depending on which seed point was chosen.
I could change the floodfill connectivity setting from 4 to 8, so that the blobs are fused in the floodfill. What I'd really like to do instead is ignore the small defect and count only the big blob. Can this be done without substantially changing the algorithm?
Unlike for floodfill, there's no way to use findContours with 4-connectivity natively in OpenCV.
You should take a look at findContours() documentation.
findContours can return multiple contours if they appear in the image, in your case, if you choose 4-connectivity, you should get 2 contours, and then you can compare their bounding box size to decide which one to keep.
cv::Mat img = cv::imread('test.png', 0);
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(img, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
for (size_t i = 0;i < contours.size(); ++i) {
cv::Rect bbox = cv::boundingRect(contours[i]);
std::cout<<"Contour"<<i<<" Area"<<bbox.area()<<std::endl;
}
Hope this helps.

findContours in opencv with "System.AccessViolationException"

I am trying to use the findContours function in Opencv2.4.4 with VS2010express(C++) the code is below.
Mat canny_output;
std::vector > contours;
/// Detect edges using canny
Canny( src_gray, canny_output, 100, 200, 3 );
/// Find contours
threshold(canny_output,canny_output,0,255,THRESH_BINARY);
findContours( canny_output, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE );
but the program will always trigger breakpoint at the last line with the system error System.AccessViolationException.
Anyone has any idea?
Suggestions:
make sure contours is vector< vector<Point> >
After a Canny operation you can directly feed the edges to findContour..why are you doing a thresholding? that too with a threshold value of zero...skip that line...because the output of canny is a binary image.
Make sure cannny_output is also a gray image.
EDIT: try this ..although this gives external contours..check wether findcontour is orking or not..
findContours(canny_output,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE,Point())

Resources