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())
Related
I want to process the output from external image segmentation algorithm (the left frame), which consists of the large color-filled areas and contour lines between them. The grayscale image that is used to find contours seems Ok (right frame), so I don't think that Canny thresholds are the issue. However, when I try to find contours on this image (frame in the middle) I get this result. How can I detect the big areas properly?
int thresh = 100;
// segmenting received image by external algorithm
Felzenszwalb_segment(seg,src2_bgr,k,0.5,500);
// finding contours on the segmented image
Mat src_gray;
cvtColor( src2_bgr, src_gray, CV_BGR2GRAY );
imshow("gray", src_gray);
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
/// Find contours
findContours( canny_output,
contours,
hierarchy,
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
If it's needed, here is the segmentation algorithm I'm using, the file to include is segment.cpp, usage is shown in the commented out main() function.
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
I am using the standard flow to process an image and just find I cannot understand the meaning of contours generated by canny and findCountours.
Here is the image:
And after canny:
after findContours, it has 4 contours. So I draw the 4 contours out.
That is the confusing part: why does it have 4 contours instead of 2? Because from the canny output, we can only see 2 contours: the outside one and the inside one.
Could someone clear my doubts?
Thanks
Deryk
code is here:
Mat src = imread("images/andgate.png");
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat bw;
Canny(gray, bw, 100, 200);
vector<vector<Point> > contours2;
vector<Vec4i> hierarchy2;
findContours(bw, contours2, hierarchy2,CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
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.
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.