c++ - Proper way to determine thresholding parameters -


i trying find triangles (blue contours) , trapezoids (yellow contours) in real time. in general it's okay. enter image description here
there problems. first it's false positives. triangles become trapezoids , vice versa. , don't know how how solve problem. enter image description here second it's "noise". enter image description here. tried check area of figure, noise can equal area. did not much. noise depends on thresholding parameters. enter image description here cv::adaptivethresholddoes not @ all. it's adds more noise (and slow) erode , dilate cant fix in proper way enter image description here

and here code.

cv::mat detect(cv::mat imagergb) {     //rgb -> gray     cv::mat imagegray;     cv::cvtcolor(imagergb, imagegray, cv_bgr2gray);     //bluring     cv::mat image;     cv::gaussianblur(imagegray, image, cv::size(5,5), 2);     //thresholding     cv::threshold(image, image, 100, 255, cv_thresh_binary_inv);      //slow , noise     //cv::adaptivethreshold(image, image, 255.0, cv_adaptive_thresh_gaussian_c, cv_thresh_binary, 21, 0);      //calculating canny params.     cv::scalar mu;     cv::scalar sigma;     cv::meanstddev(image, mu, sigma);      cv::mat imagecanny;      cv::canny(image,               imagecanny,               mu.val[0] + sigma.val[0],               mu.val[0] - sigma.val[0]);      //detecting conturs.     std::vector<std::vector<cv::point> > contours;     std::vector<cv::vec4i> hierarchy;     cv::findcontours(imagecanny, contours, hierarchy,cv_retr_tree, cv_chain_approx_none);      //hierarchy not needed here clear it.     hierarchy.clear();      (std::size_t = 0; < contours.size(); i++)     {         //fitellipse need @ last 5 points.         if (contours.at(i).size() < 5)         {             continue;         }         //skip small contours.         if (std::fabs(cv::contourarea(contours.at(i))) < 800.0)         {             continue;         }         //calculating rotatedrect contours not hull         //because fitellipse need @ last 5 points.          cv::rotatedrect bellipse = cv::fitellipse(contours.at(i));          //finds convex hull of point set.         std::vector<cv::point> hull;         cv::convexhull(contours.at(i), hull, true);         //approx it, we'll 3 point triangles         //and 4 points trapez.         cv::approxpolydp(hull, hull, 15, true);         //is our contour convex. it's mast be.         if (!cv::iscontourconvex(hull))         {             continue;         }         //triangle         if (hull.size() == 3)         {             cv::drawcontours(imagergb, contours, i, cv::scalar(255, 0, 0), 2);             cv::circle(imagergb, bellipse.center, 3, cv::scalar(0, 255, 0), 2);         }         //trapez         if (hull.size() == 4)         {             cv::drawcontours(imagergb, contours, i, cv::scalar(0, 255, 255), 2);             cv::circle(imagergb, bellipse.center, 3, cv::scalar(0, 0, 255), 2);         }     }     return imagergb; } 

so... in general problems coused wrong thresholding parameters, how can calculete in proper way (automatically, of course)? , how can can (lol, sorry english) prevent false positives?

thesholding - think should try otsu binarization - here theory , nice picture , here documentation. kind of thresholding trying find 2 common values in image , use average value of them threshold value.

alternatively consider using hsv color space, might easier distinguish black , white regions other regions. idea use inrange function (in rgb or in hsv color space - should work in woth situations) - need find 2 ranges (one black regions , 1 white) , search regions (using inrange function) - at post.

another way accomplish task might using library blob extraction like one or blob extractor part of opencv.

distinguish triangle trapezoid - see 2 basic ways improve solution here:

  • in line cv::approxpolydp(hull, hull, 15, true); make third parameter (15 in situation) not constant value, part of contour area or length. should adapt contour size, can't canstant value. it's hard how calculate without testing - try start 1-5% of contour area or length (i start length, guess) , see whether value fine/to big/to small check other values if needed. unfortunetely there no other way, finding equation manually shouldn't take long time.
  • when have 4 or 5 points calculate equations of lines join consecutive points (point 1 point 2, point 2 point 3, etc don't forget calculate line between first point , last point), check whether 2 of lines parallel (or @ least close being parallel - angle between them close 0 degress) - if find parallel lines contour trapezoid, otherwise it's triangle.

Comments

Popular posts from this blog

c++ - Delete matches in OpenCV (Keypoints and descriptors) -

java - Could not locate OpenAL library -

sorting - opencl Bitonic sort with 64 bits keys -