Keywords: contour detection, analysis, Hoff circle detection, circumscribed rectangle, circumscribed rotating rectangle, center point, multi deformation filling, target object detection and segmentation
Input:
Contour detection and analysis:
Including circle detection, position, center point, circumscribed rectangle, circumscribed rectangle, contour area, perimeter, rotation angle, etc.
Contour background separation and extraction:
Method 2,
Target object detection and segmentation:
Method two,
Reference code,
void Test22() { //0: pencil; 1: lighter; 2: circle with shadow above; 3: big circle on the right; 4: small circle on the bottom left vector<Point> contoursorder[5]; Mat src, srcback, srcback2, src_gray0, src_gray, binImg; //1. Read in and test src = imread("D:/images/stuff.jpg", 1); srcback = imread("D:/images/stuff.jpg"); srcback2 = srcback.clone(); string str = "Hello, 2020!"; putText(srcback2, str, Point(100,200), FONT_HERSHEY_SIMPLEX, 2.0, Scalar(0, 0, 255), 2, 16); imshow("src", srcback2); waitKey(0); Mat RoiSrcImg(src.rows, src.cols, CV_8UC3); RoiSrcImg.setTo(255);//Color is set to white //imshow("RoiSrcImg", RoiSrcImg); //waitKey(0); Mat RoiSrcImg0(src.rows, src.cols, CV_8UC3); RoiSrcImg0.setTo(255);//Color is set to white //declare and initialize both parameters that are subjects to change int cannyThreshold = 21; int accumulatorThreshold = 34; cannyThreshold = std::max(cannyThreshold, 1); accumulatorThreshold = std::max(accumulatorThreshold, 1); Mat src1 = CalculateImageGradient(src, false); //imshow("src1", src1); //waitKey(0); //////////////////////////////////////Find profile ////////////////////////////////////Grayscale //src_gray = src1; int iii = src1.channels(); cvtColor(src1, src_gray, COLOR_RGB2GRAY); //2. Turn to grayscale, and blur to remove noise -- preprocessing cvtColor(src, src_gray0, COLOR_BGR2GRAY); GaussianBlur(src_gray0, src_gray0, Size(9, 9), 2, 2); //Two valued threshold(src_gray, binImg, 0, 255, THRESH_BINARY | THRESH_OTSU); //imshow("bin", binImg); //waitKey(0); /////////////////////////////////// vector<vector<Point>> contours; //vector<Rect> boundRect(contours.size()); //Note that the fifth parameter is CV? Retr? External, only retrieve the outline / / find the outline findContours(binImg, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); ////////////////////////////////////////////////////// cout << contours.size() << endl; int iSeq = -1; for (int i = 0; i < contours.size(); i++) { double area = contourArea(contours[i]); double len = arcLength(contours[i], true); if (area > 1000)// continue; { if (area > 6300 && area < 6400) { contoursorder[1] = contours[i]; Rect recttt = boundingRect(Mat(contours[i])); rectangle(src, recttt, (0, 0, 255), 2, 8, 0); //cv::drawContours(RoiSrcImg, contours, i, Scalar(0), FILLED); rectangle(RoiSrcImg, recttt,Scalar(0), -1); //imshow("RoiSrcImg1", RoiSrcImg); //waitKey(0); cv::RotatedRect &&rotate_rect = cv::minAreaRect(contours[i]); circle(src, rotate_rect.center, 3, Scalar(0, 0, 255), -1, 8, 0); string strarea = "area:" + doubleConverToString(area); putText(src, strarea, rotate_rect.center, FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255, 0, 0), 1, 8); } else if (area > 5900 && area < 6000) { contoursorder[0] = contours[i]; //cv::drawContours(RoiSrcImg, contours, i, Scalar(0), FILLED); DrawCircumscribedRectangle2(src, RoiSrcImg,contours[i]); } else { //Parameters: src [gray], src [display], canny threshold, accumulation threshold HoughDetection2(src_gray0, src, RoiSrcImg,cannyThreshold, accumulatorThreshold); } } else { drawContours(binImg, contours, i, Scalar(0), FILLED); } } bitwise_not(RoiSrcImg, RoiSrcImg); imshow("outline+background", RoiSrcImg); waitKey(0); }
Hoff circle test reference code,
void HoughDetection2(const Mat& src_gray, const Mat& src_display, Mat& src_display2, int cannyThreshold, int accumulatorThreshold) { //Detection result vector std::vector<Vec3f> circles; //Hoff circle test //Parameters: src, output array, Hoff gradient, dp?, minimum center distance, Canny threshold, accumulation threshold HoughCircles(src_gray, circles, HOUGH_GRADIENT, 1, src_gray.rows / 8, cannyThreshold, accumulatorThreshold, 0, 0); Mat display = src_display.clone(); for (size_t i = 0; i < circles.size(); i++) { //Center -(x,y) Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); //Radius - r int radius = cvRound(circles[i][2]); Point ptlt, ptlb, ptrb, ptrt; ptlt.x = circles[i][0] - radius; ptlt.y = circles[i][1] - radius; ////////////////////////////////////////////////////// ptlb.x = circles[i][0] - radius; ptlb.y = circles[i][1] + radius; ///////////////////////////////////////////////////// ptrb.x = circles[i][0] + radius; ptrb.y = circles[i][1] + radius; ///////////////////////////////////////////////////// ptrt.x = circles[i][0] + radius; ptrt.y = circles[i][1] - radius; ///////////////////////////////////////////////////// //Central circle circle(display, center, 3, Scalar(0, 255, 0), -1, 8, 0); if (0 == i) { //Outer circle circle(display, center, radius, Scalar(0, 0, 255), 3, 8, 0); circle(src_display2, center, radius, Scalar(0, 0, 0), -1); //rectangle(display, ptlt, ptrb, Scalar(0, 0, 255), 2, 8, 0); double darea = PI * radius*radius; string strarea = "area:" + doubleConverToString(darea); double dlength = 2 * PI*radius; string strperimeter = "length:" + doubleConverToString(dlength); putText(display, strarea, Point(cvRound(circles[i][0]), cvRound(circles[i][1])), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 1, 8); //putText(display, strperimeter, Point(cvRound(circles[i][0]), cvRound(circles[i][1] + radius / 2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 1, 8); } else if (1 == i) { //Outer circle circle(display, center, radius, Scalar(0, 0, 255), 3, 8, 0); circle(src_display2, center, radius, Scalar(0, 0, 0), -1); //rectangle(display, ptlt, ptrb, Scalar(0, 0, 255), 2, 8, 0); double darea = PI * radius*radius; string strarea = "area:" + doubleConverToString(darea); double dlength = 2 * PI*radius; string strperimeter = "length:" + doubleConverToString(dlength); putText(display, strarea, Point(cvRound(circles[i][0]), cvRound(circles[i][1] - radius / 2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 1, 8); putText(display, strperimeter, Point(cvRound(circles[i][0]), cvRound(circles[i][1] + radius / 2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 1, 8); } else if (2 == i) { //Outer circle circle(display, center, radius, Scalar(0, 0, 255), 3, 8, 0); circle(src_display2, center, radius, Scalar(0, 0, 0), -1); //rectangle(display, ptlt, ptrb, Scalar(0, 0, 255), 2, 8, 0); double darea = PI * radius*radius; string strarea = "area:" + doubleConverToString(darea); double dlength = 2 * PI*radius; string strperimeter = "length:" + doubleConverToString(dlength); //putText(display, strarea, Point(cvRound(circles[i][0]), cvRound(circles[i][1] - radius / 2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 1, 8); putText(display, strperimeter, Point(cvRound(circles[i][0]), cvRound(circles[i][1] + radius / 2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 1, 8); } else { } } imshow("Contour detection and analysis", display); waitKey(0); destroyAllWindows(); }
Published 201 original articles, won praise 159, visited 630000+