c++ - Detecting squares in an image -
i found square detection code online , i'm trying understand it, understand line @ end does? states: "gray = gray0 >= (l+1)*255/n;"
mat pyr, timg, gray0(image.size(), cv_8u), gray;
// down-scale , upscale image filter out noise pyrdown(image, pyr, size(image.cols/2, image.rows/2)); pyrup(pyr, timg, image.size()); vector<vector<point> > contours; // find squares in every color plane of image for( int c = 0; c < 3; c++ ) { int ch[] = {c, 0}; mixchannels(&timg, 1, &gray0, 1, ch, 1); // try several threshold levels for( int l = 0; l < n; l++ ) { // hack: use canny instead of 0 threshold level. // canny helps catch squares gradient shading if( l == 0 ) { // apply canny. take upper threshold slider // , set lower 0 (which forces edges merging) canny(gray0, gray, 0, thresh, 5); // dilate canny output remove potential // holes between edge segments dilate(gray, gray, mat(), point(-1,-1)); } else { // apply threshold if l!=0: // tgray(x,y) = gray(x,y) < (l+1)*255/n ? 255 : 0 gray = gray0 >= (l+1)*255/n; }
this code snipped part of git repository cvsquares
. experience, know library not work on real images though works in computer generated images. plus method of detection on rgb without converting grayscale computationally expensive.
anyways line of code asking threshold filter makes binary gray
mat array based on threshold applied array gray0
according level. if condition true, array contains white pixel @ location else black pixel
a more generic detection code based on grayscale image work better this:
mat binary_img(color_img.size(),cv_8uc1); vector<vec4i> hierarchy; vector<vector<point> > contours; vector<cv::point> approx; cv::gaussianblur(color_img, color_img, cv::size(9,9), 3); cv::medianblur(color_img, color_img, 9); cv::medianblur(color_img, color_img, 9); cvtcolor(color_img,binary_img,cv_bgr2gray); iplimage tempbinary=iplimage(binary_img); cvinranges(&tempbinary, scalar(20), scalar(100), &tempbinary); mat imgmat=mat(&tempbinary); findcontours( imgmat, contours, hierarchy, cv_retr_tree, cv_chain_approx_simple, point(0, 0) ); for(int = 0; < contours.size(); i++ ) { approxpolydp(mat(contours[i]), approx, arclength(mat(contours[i]), true)*0.0005, true); if(approx.size()==4) //draw approx }
Comments
Post a Comment