c# - Emgu object detection using MatchShapes for connected components with holes -


i've been working on shape matching function, using emgu, detecting objects given template of object , target image in find it. target image can contain multiple instances of template.

the function built works reasonably well. have 1 concern. if template has more 1 hole, function not give correct answer.

here important part of code:

private image<bgr, byte> drawcontours(image<gray, byte> image, contour<point> contours, bgr color, int thickness, int maxlevel) {     image<bgr, byte> resultimage = new image<bgr, byte>(image.size);     resultimage = image.convert<bgr, byte>();     cvinvoke.cvdrawcontours(resultimage, contours, color.mcvscalar, color.mcvscalar, maxlevel, thickness, line_type.cv_aa, new point(0, 0));     return resultimage; }  private contour<point> getedgecontours(image<gray, byte> image, image<gray, byte> mask, int threshold) {     cvinvoke.cvthreshold(image, image, 255, 255, thresh.cv_thresh_binary | thresh.cv_thresh_otsu);     image = image.dilate(3).erode(3);     contour<point> cont = image.findcontours(chain_approx_method.cv_chain_approx_tc89_l1, retr_type.cv_retr_ccomp);     return cont; }  private polygon mcvbox2d2polygon(mcvbox2d box) {     system.windows.media.pointcollection polypoints = new system.windows.media.pointcollection();      foreach (var p in box.getvertices())         polypoints.add(new system.windows.point(p.x, p.y));     polygon poly = new polygon();     poly.points = polypoints;     return poly; }  private bool processshapematching(ref image<gray, byte> templateimage ,  out image<gray, byte> targetimage) {     positions = new list<polygon>();     contour<point> templatecontours = getedgecontours(templateimage, null, 100);     contour<point> targetcontours = getedgecontours(targetimage, maskimage, 100);      mcvbox2d box = templatecontours.getminarearect();      double precision = 0.0001;     double distancethreshold = 0.4;     int nccomplevels = 2; // connected components have 2 levels. 1 of outer boundary en possibly 1 inner boundaries (holes)      using (memstorage storage = new memstorage()) //allocate storage contour approximation     {         //find largest connected component countour in template         contour<point> templatecontour = new contour<point>(storage);         double largestarea = 0;         (contour<point> cont = templatecontours; cont != null; cont = cont.hnext)             if (cont.area > largestarea)                 templatecontour = cont;         if (templatecontour == null)             throw new nullreferenceexception("no contours found in template image");          // reduce nr of vertices in template polygons         templatecontour = templatecontour.approxpoly(templatecontour.perimeter * precision, nccomplevels, storage);          // reduce nr of  vertices in target polygons         if (templatecontour.area > targetimage.height * targetimage.width / 1000) //only consider contours plausible area         {             double distance = 0;             (contour<point> targetcontour = targetcontours; targetcontour != null; targetcontour = targetcontour.hnext)             {                 if (targetcontour.area < targetimage.height * targetimage.width / 1000) //only consider contours plausible area                     continue;                  contour<point> approximatedtargetcontour = targetcontour.approxpoly(targetcontour.perimeter * precision, nccomplevels, storage);                 distance += templatecontour.matchshapes(approximatedtargetcontour, contours_match_type.cv_contours_match_i3);                  imageviewer.show(drawcontours(targetimage, approximatedtargetcontour, new bgr(color.cyan), 2, 0), "contour");                  //this smelly part, works when number of holes in template 0 or 1                             // in template , target shapes                  if ((templatecontour.vnext != null) && (targetcontour.vnext != null))                     distance += templatecontour.matchshapes(approximatedtargetcontour, contours_match_type.cv_contours_match_i3);                 if ((templatecontour.vnext != null) && (targetcontour.vnext == null))                     continue; // no match                 if ((templatecontour.vnext == null) && (targetcontour.vnext != null))                     continue; // no match                 //http://stackoverflow.com/questions/15555615/equivalent-of-hierarchy-in-emgu                  if (distance > distancethreshold)                     continue;                  // have match, let's add position                 positions.add(mcvbox2d2polygon(targetcontour.getminarearect()));                  // draw annotation                 image<bgr, byte> imageanotated = drawcontours(targetimage, approximatedtargetcontour, new bgr(color.salmon), 2, nccomplevels);                 mcvbox2d boxi = approximatedtargetcontour.getminarearect();                 imageanotated.draw(boxi, new bgr(color.turquoise), 2);                 imageviewer.show(imageanotated, string.format("current contour {0}", distance));             }         }     }     return false; } 

i hoping suggestions on how compare innards of shape, meaning holes in connected component. maybe there standard ways overlooking?

thanks in advance!


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

java - Using an Integer ArrayList in Android -