A few days ago, I found a giant cow's artificial intelligence learning website . It is easy to understand, funny and humorous. I can't help but share it with you:
content
1. Contour detection
The following figure is an example:
The grayscale image directly extracts the contour:
int main()
{
Mat img = imread("D:/1.png", 0);
resize(img, img, Size(0, 0), 0.5, 0.5);
Mat src=img;
cv::imshow("src", src);
std::vector<std::vector<Point>> contours;
std::vector<Vec4i> hierarchy;
findContours(src, contours, hierarchy, RETR_LIST, CHAIN_APPROX_NONE, Point(0, 0));
cout << contours.size()<<endl;
//sort(contours.begin(), contours.end(), cmp< Point>);
//for (int i = 0; i < contours.size(); i++)cout << contours[i].size() << " ";
src = 0;
cv::drawContours(src, contours, -1, cv::Scalar::all(255));
cv::imshow("Contours", src);
cv::waitKey(0);
return 0;
}
The resulting number of contours is 1, the outermost contour of the entire graph.
Optimization idea: first perform a certain binarization process.
int main()
{
Mat img = imread("D:/1.png", 0);
resize(img, img, Size(0, 0), 0.5, 0.5);
Mat src;
threshold(img, src, 200, 255, THRESH_TRUNC);
threshold(src, src, 100, 255, THRESH_TOZERO);
cv::imshow("src", src);
std::vector<std::vector<Point>> contours;
std::vector<Vec4i> hierarchy;
findContours(src, contours, hierarchy, RETR_LIST, CHAIN_APPROX_NONE, Point(0, 0));
cout << contours.size()<<endl;
//sort(contours.begin(), contours.end(), cmp< Point>);
//for (int i = 0; i < contours.size(); i++)cout << contours[i].size() << " ";
src = 0;
cv::drawContours(src, contours, -1, cv::Scalar::all(255));
cv::imshow("Contours", src);
cv::waitKey(0);
return 0;
}
Generally, it is better to do edge detection before extracting contours.
Edge detection is biased towards the change of pixel points in the image, and contour detection is more inclined to focus on upper-level semantic objects.
Second, edge detection
Use Canny operator for edge detection:
int main()
{
Mat img = imread("D:/1.png", 0);
resize(img, img, Size(0, 0), 0.5, 0.5);
Mat src;
threshold(img, src, 200, 255, THRESH_TRUNC);
threshold(src, src, 100, 255, THRESH_TOZERO);
Canny(src, src, 200, 100, 3);
cv::imshow("src", src);
cv::waitKey(0);
return 0;
}
The edge detection results are clear.
Complete application: