我是OpenCV和C ++的新手。 而且我被这个问题困住了,这看起来似乎很琐碎。
我正在尝试将圆形与其他形状(例如矩形,正方形,三角形等)区分开来。
这是我使用的代码
void setLabel(Mat& image, string str, vector<Point> contour){
int fontface = FONT_HERSHEY_SIMPLEX;
double scale = 0.5;
int thickness = 1;
int baseline = 0;
Size text = getTextSize(str, fontface, scale, thickness, &baseline);
Rect r = boundingRect(contour);
Point pt(r.x + ((r.width - text.width) / 2), r.y + ((r.height + text.height) / 2));
rectangle(image, pt + Point(0, baseline), pt + Point(text.width, -text.height), CV_RGB(200, 200, 200), CV_FILLED);
putText(image, str, pt, fontface, scale, CV_RGB(0, 0, 0), thickness, 8);
}
int main(){
Mat img_input, img_result, img_gray;
String filepath("C:\\Users\\PC\\Desktop\\kist\\test.png");
img_input = imread(filepath, IMREAD_COLOR);
if (img_input.empty()){
cout << "Could not open or find the image" << std::endl;
return -1;
}
cvtColor(img_input, img_gray, COLOR_BGR2GRAY);
medianBlur(img_gray, img_gray, 5);
vector <Vec3f> circles;
HoughCircles(img_gray, circles, CV_HOUGH_GRADIENT, 1, 20, 200, 50, 0, 0);
threshold(img_gray, img_gray, 125, 255, THRESH_BINARY_INV | THRESH_OTSU);
vector<vector<Point> > contours;
findContours(img_gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
vector<Point2f> approx;
img_result = img_input.clone();
for (size_t i = 0; i < contours.size(); i++){
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
if (fabs(contourArea(Mat(approx))) > 0){
int size = approx.size();
if (size % 2 == 0) {
line(img_result, approx[0], approx[approx.size() - 1], Scalar(0, 255, 0), 2);
for (int k = 0; k < size - 1; k++)
line(img_result, approx[k], approx[k + 1], Scalar(0, 255, 0), 2);
for (int k = 0; k < size; k++)
circle(img_result, approx[k], 3, Scalar(0, 0, 255));
for (size_t j = 0; j < circles.size(); j++) {
Vec3i c = circles[j];
Point center = Point(c[0], c[1]);
circle(img_result, center, 2, Scalar(0, 255, 0), 2, LINE_AA);
int radius = c[2];
circle(img_result, center, radius, Scalar(0, 255, 0), 2, LINE_AA);
}
}
else if (size % 2 > 0) {
line(img_result, approx[0], approx[approx.size() - 1], Scalar(0, 255, 0), 2);
for (int k = 0; k < size - 1; k++)
line(img_result, approx[k], approx[k + 1], Scalar(0, 255, 0), 2);
for (int k = 0; k < size; k++)
circle(img_result, approx[k], 3, Scalar(0, 0, 255));
}
if (size == 3)
setLabel(img_result, "triangle", contours[i]);
else if (size == 4 && isContourConvex(Mat(approx)))
setLabel(img_result, "rectangle", contours[i]);
else if (size == 5 && isContourConvex(Mat(approx)))
setLabel(img_result, "pentagon", contours[i]);
else if (size == 6 && isContourConvex(Mat(approx)))
setLabel(img_result, "hexagon", contours[i]);
else if (size == 10 && isContourConvex(Mat(approx)))
setLabel(img_result, "decagon", contours[i]);
else {
setLabel(img_result, to_string(approx.size()), contours[i]);
}
}
else if (fabs(contourArea(Mat(approx))) == 0) {
for (size_t i = 0; i < circles.size(); i++) {
Vec3i c = circles[i];
Point center = Point(c[0], c[1]);
circle(img_result, center, 2, Scalar(0, 100, 100), 2, LINE_AA);
int radius = c[2];
circle(img_result, center, radius, Scalar(255, 0, 255), 2, LINE_AA);
}
setLabel(img_result, to_string(approx.size()), contours[i]);
}
}
imshow("input", img_input);
imshow("result", img_result);
如下图所示,我能够找出每个图的顶点并绘制线条。
但是,我要删除顶点和直线,并从圆形中保留圆形轮廓。此外,我想将圆形描述为“圆形”并计算每种形状的数量。
请帮助我~~
谢谢!