1.轮廓发现
void outline_demo()
{QString appPath = QCoreApplication::applicationDirPath();QString imagePath = appPath + "/morph3.png";Mat img = cv::imread(imagePath.toStdString());if (img.empty()) {return;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", img);GaussianBlur(img, img, Size(3, 3), 0);Mat gray, binary;cvtColor(img, gray, COLOR_BGR2GRAY);imshow("gray", gray);double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);imshow("BINARY", binary);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());drawContours(img, contours, -1, Scalar(0, 0, 255), 2, 8);imshow("outline", img);waitKey();destroyAllWindows();
}
2.轮廓分析
void outline_analysis_demo()
{QString appPath = QCoreApplication::applicationDirPath();QString imagePath = appPath + "/zhifang_ball.png";Mat img = cv::imread(imagePath.toStdString());if (img.empty()) {return;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", img);GaussianBlur(img, img, Size(3, 3), 0);Mat gray, binary;cvtColor(img, gray, COLOR_BGR2GRAY);imshow("gray", gray);double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);imshow("BINARY", binary);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());for (size_t t = 0; t < contours.size(); t++){double area = contourArea(contours[t]);double size = arcLength(contours[t],true);qDebug() << "area:" << area << " " << "size:" << size;if (area < 100 || size < 10) continue;Rect box = boundingRect(contours[t]);rectangle(img,box,Scalar(0,0,255),2,8,0);RotatedRect rrt = minAreaRect(contours[t]);ellipse(img, rrt, Scalar(255, 0, 0), 2, 8);Point2f pts[4];rrt.points(pts);for (int i = 0; i < 4; i++){line(img, pts[i], pts[(i + 1) % 4], Scalar(0, 255, 0), 2, 8);}drawContours(img, contours, t, Scalar(0, 0, 255), 2, 8);}imshow("outline", img);waitKey();destroyAllWindows();
}
3.轮廓匹配
void outline_match_demo()
{QString appPath = QCoreApplication::applicationDirPath();Mat img1 = cv::imread(appPath.toStdString() + "/abc.png");Mat img2 = cv::imread(appPath.toStdString() + "/a5.png");if (img1.empty() || img2.empty()) {return;}imshow("input1", img1);imshow("input2", img2);vector<vector<Point>> contours1,contours2;contour_info(img1, contours1);contour_info(img2, contours2);Moments mm2 = moments(contours2[0]);Mat hu2;HuMoments(mm2, hu2);for (size_t t = 0; t < contours1.size(); t++){Moments mm = moments(contours1[t]);double cx = mm.m10 / mm.m00;double cy = mm.m01 / mm.m00;circle(img1,Point(cx, cy), 3, Scalar(255, 0, 0), 2,8, 0);Mat hu;HuMoments(mm, hu);double dist = matchShapes(hu, hu2, CONTOURS_MATCH_I1,0);if (dist < 1.0){drawContours(img1, contours1, t, Scalar(0, 0, 255), 2, 8);}}imshow("match contrours demo", img1);waitKey();destroyAllWindows();
}void contour_info(Mat &image, vector<vector<Point>> &contours)
{GaussianBlur(image, image, Size(3, 3), 0);Mat gray, binary;cvtColor(image, gray, COLOR_BGR2GRAY);double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());}
4.多边形逼近
void outline_fit_clicked()
{QString appPath = QCoreApplication::applicationDirPath();QString imagePath = appPath + "/contours.png";Mat img = cv::imread(imagePath.toStdString());if (img.empty()) {return;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", img);GaussianBlur(img, img, Size(3, 3), 0);Mat gray, binary;cvtColor(img, gray, COLOR_BGR2GRAY);imshow("gray", gray);double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);imshow("BINARY", binary);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());for (size_t t = 0; t < contours.size(); t++){Moments mm = moments(contours[t]);double cx = mm.m10 / mm.m00;double cy = mm.m01 / mm.m00;circle(img, Point(cx, cy), 3, Scalar(255, 0, 0), 2, 8, 0);double area = contourArea(contours[t]);double clen = arcLength(contours[t], true);Mat result;approxPolyDP(contours[t], result, 4, true);qDebug() << result.rows << " " << result.cols;if (result.rows == 6){putText(img, "poly", Point(cx,cy-10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1,8);}if (result.rows == 4){putText(img, "rectangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);}if (result.rows == 3){putText(img, "trriangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);}if (result.rows >10){putText(img, "circle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);}}imshow("多边形逼近", img);waitKey();destroyAllWindows();
}
5.拟合圆和椭圆
void actual::fit_circle_demo(Mat &image)
{Mat gray, binary;cvtColor(image, gray, COLOR_BGR2GRAY);double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());for (size_t t = 0; t < contours.size(); t++){RotatedRect rrt = fitEllipse(contours[t]);float w = rrt.size.width;float h = rrt.size.height;Point center = rrt.center;circle(image, center, 3, Scalar(255.0, 0), 2, 8, 0);ellipse(image, rrt, Scalar(0, 255, 0), 2, 8);}imshow("拟合圆和椭圆", image);
}