doubts regarding the output of canny and findcountours in OpenCV - opencv

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

Related

object and contour detection in an image

I am new to image processing and trying to get the contours of the apples in these images. To do so, i use openCV. But i do not get a propper contour detection. I want the algorithm also be able to get contours of other objects. So not limmited to apples (= circles).
Original picture
If i follow the instructions there are 4 steps to be taken.
Open the image file
Convert the file to grayscale
Do some processing (blur, errode, dillitate, you name it)
Get the contours
The first point that confuses me is the grayscale conversion.
I did:
Mat image;
Mat HSVimage;
Mat Grayimage;
image = imread(imageName, IMREAD_COLOR); // Read the file
cvtColor(image, HSVimage, COLOR_BGR2HSV);
Mat chan[3];
split(HSVimage, chan);
Grayimage = chan[2];
First question:
Is this correct choice, or shoud i just read the file in Grayscale or use YUV ?
I only use 1 channel of the HSV, is this correct ?
I tried alot of processing methodes, but there are so many i lost track. The best result i got was when i used a treshold and an adaptiveTreshold.
threshold(Grayimage, Grayimage,49, 0, THRESH_TOZERO);
adaptiveThreshold(Grayimage, Tresholdimage, 256, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 23, 4);
The result i get is:
result after processing
But a find contours does not find a closed object. So i get:
contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(Tresholdimage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
I tried hough cicles,
vector<Vec3f> circles;
HoughCircles(Tresholdimage, circles, HOUGH_GRADIENT, 2.0, 70);
and i got:
hough circles ok
So i was a happy man, but as soon is i tried the code on an other picture, i got:
second picture original
hough circles wrong
I can experiment with the HoughCircles function i see there are alot of posibilities, but i can only detect circles with it, so it is not my first choice.
I am a newbie at this. My questions are:
Is this a correct way or is it better to use technics like blob detection or ML to find the objects in the picture ?
If it is a correct way, what functions should i use to get the better results ?
Regards,
Peter

OpenCV: findContours seems to be tricked by combination of large filled areas and lines

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.

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

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.

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