OpenCV findcontours() crash - opencv

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...

Related

Opencv Unhandled exception in contour.exe

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);

How to determine if a rectangle is well formed using open cv

I am currently trying to determine if a rectangle is well formed such as having perfect corners and straight lines.
This is what I am currently doing now to detect a rectangle
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR);
cvtColor( image,image1, CV_BGR2GRAY );
Canny( image1, canny_output,130, 200 );
vector<Point> approx;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point(0,0) );
for (unsigned int i=0; i<contours.size(); i++){
if((approx.size() == 4)){
cout<<"It is a rectangle"<<endl;
}
}
I can detect if it is a rectangle but I am not sure how to detect that is a not a well formed rectangle like the images below.
If the test images are like the ones that you have posted here, you could try to use Hough Transform, firstly to detect the lines and the check if the lines are parallel.
Try to have a look how to use OpenCV Hough Transform implementation on on OpenCV here.
However I need more informations to clarify better the answer.
I also checked there are some others threads about this problem you could check the following:
Hough transformation vs Contour detection for Rectangle recognition with perspective projection
Rectangle detection with Hough transform.
Moreover if you are familiar with research, have a look to this paper.

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 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())

OpenCV : number of nested contours

This is my first question here, thank you for reading it.
I am trying to count the number of inner contours inside a contour.
I found a nice tutorial showing how to use h_next and v_next
http://jmpelletier.com/a-simple-opencv-tutorial/
The problem is I use Mat and not IplImage.
I tried to convert it with:
Mat *oimg;
IplImage img = *oimg;
But I get an error when calling cvFindContours.
I also tried usign findContours which is built to work with Mat,
by going through the hierrarchy but it didnt work.
I'm usign C++ and OpenCV2.0
Thanks allot,
Tamir.
Instead of converting the cv::Mat to an IplImage to use the C API, I suggest directly using the C++ version of cvFindContours(): cv::findContours(). Instead of building a true tree data structure, it is flattened and stored in two vectors:
cv::Mat image = // ...
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(image, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
Check the C++ API documentation for instructions on how to interpret hierarchy (emphasis mine):
hiararchy – The optional output vector
that will contain information about
the image topology. It will have as
many elements as the number of
contours. For each contour contours[i]
, the elements hierarchy[i][0] ,
hiearchyi , hiearchy[i][2] ,
hiearchy[i][3] will be set to 0-based
indices in contours of the next and
previous contours at the same
hierarchical level, the first child
contour and the parent contour,
respectively. If for some contour i
there is no next, previous, parent or
nested contours, the corresponding
elements of hierarchy[i] will be
negative
Switching between the C and C++ API in the same codebase really hurts readability. I suggest only using the C API if the functionality you need is missing from the C++ API.

Resources