c# - Detect display corners with Emgu -


i want detect display on image (more precisely corners). segment image in display color , not display color:

image<gray, byte> segmentedimage = greyimage.inrange(new gray(180), new gray(255)); 

enter image description here

then use corner harris find corners:

emgu.cv.image<emgu.cv.structure.gray, byte> harrisimage = new image<emgu.cv.structure.gray, byte>(greyimage.size); cvinvoke.cornerharris(segmentedimage, harrisimage, 2); cvinvoke.normalize(harrisimage, harrisimage, 0, 255, normtype.minmax, depthtype.cv32f); 

enter image description here

there white pixels in corners, cannot access them:

for (int j = 0; j < harrisimage.rows; j++) {     (int = 0; < harrisimage.cols; i++)     {         console.writeline(harrisimage[j, i].intensity);     } } 

it writes 0s. how can access them? , if can access them, how can find 4 corners of screen in harris image? there function find perspectively transformed rectangle points?

edit:
on opencv irc said findcontours not precise. , when try run on segmentedimage, this: enter image description here (ran findcontours on segmentedimage, approxpolydp , drew found contour on original greyscale image)
cannot find contours more precise...

edit2: cannot work me. code, exact same result... here full emgu code:

emgu.cv.image<emgu.cv.structure.gray, byte> imageframegrey = new image<emgu.cv.structure.gray, byte>(bitmap); image<gray, byte> segmentedimage = imageframegrey.inrange(new gray(180), new gray(255)); // rid of small objects int morph_size = 2; mat element = cvinvoke.getstructuringelement(emgu.cv.cvenum.elementshape.rectangle, new system.drawing.size(2 * morph_size + 1, 2 * morph_size + 1), new system.drawing.point(morph_size, morph_size)); cvinvoke.morphologyex(segmentedimage, segmentedimage, emgu.cv.cvenum.morphop.open, element, new system.drawing.point(-1, -1), 1, emgu.cv.cvenum.bordertype.default, new mcvscalar());  // find edges form rectangles list<rotatedrect> boxlist = new list<rotatedrect>(); using (vectorofvectorofpoint contours = new vectorofvectorofpoint()) {     cvinvoke.findcontours(segmentedimage, contours, null, emgu.cv.cvenum.retrtype.external, chainapproxmethod.chainapproxsimple);     int count = contours.size;     (int = 0; < count; i++)     {         using (vectorofpoint contour = contours[i])         using (vectorofpoint approxcontour = new vectorofpoint())         {             cvinvoke.approxpolydp(contour, approxcontour, cvinvoke.arclength(contour, true) * 0.01, true);             if (cvinvoke.contourarea(approxcontour, false) > 10000)             {                 if (approxcontour.size == 4)                 {                     bool isrectangle = true;                     system.drawing.point[] pts = approxcontour.toarray();                     linesegment2d[] edges = emgu.cv.pointcollection.polyline(pts, true);                     (int j = 0; j < edges.length; j++)                     {                         double angle = math.abs(edges[(j + 1) % edges.length].getexteriorangledegree(edges[j]));                         if (angle < 80 || angle > 100)                         {                             isrectangle = false;                             break;                         }                     }                      if (isrectangle)                     boxlist.add(cvinvoke.minarearect(approxcontour));                 }             }         }     } } 

so promised tried myself. in c++ should adopt easy emgu. first rid of small object in segmented image opening:

int morph_elem = cv_shape_rect; int morph_size = 2; mat element = getstructuringelement(morph_elem, size(2 * morph_size + 1, 2 * morph_size + 1), point(morph_size, morph_size)); // apply opening morphologyex(segmentedimage, segmentedimage_open, cv_mop_open, element); 

then detect contours , take large ones , check rectangular shape:

vector< vector<point>> contours; findcontours(segmentedimage_open, contours, cv_retr_external, cv_chain_approx_simple);  each (vector<point> var in contours) {     double area = contourarea(var);     if (area> 30000)      {         vector<point> approx;         approxpolydp(var, approx, 0.01*arclength(var, true), true);          if (4 == approx.size()) //rectangular shape          {             //         }     } } 

here result contour in red , approximated curve in green:

enter image description here

edit:

you can improve code increasing approximation factor until contour 4 points or pass threshold. wrap loop around approxpolydp. can define range approximation value , prevent code fail if object differs rectangle.


Comments

Popular posts from this blog

php - Auto increment employee ID -

php - isset function not working properly -

javascript - Thinglink image not visible until browser resize -