# How to detect octogonal shapes using contours

I want to detect octagonal stop sign like the following image with contours but i can't figure out how it is done

I already manage to detect triangles

Mat ROI = new Mat();
Mat bgrClone = bgr.clone();
MatOfPoint approxContour = new MatOfPoint();
MatOfPoint2f approxContour2f = new MatOfPoint2f();
List<MatOfPoint> contourDraw = new ArrayList<MatOfPoint>();

for(int i = 0; i < contourList.size(); i++) {
MatOfPoint2f contour2f = new MatOfPoint2f(contourList.get(i).toArray());
double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02;//0.225
Imgproc.approxPolyDP(contour2f, approxContour2f, approxDistance, true);

approxContour2f.convertTo(approxContour, CvType.CV_32S);
if (approxContour.size().height == 3 && (Imgproc.contourArea(contour2f) > 3000) ) { //&& (Imgproc.contourArea(contour2f) > 5000)

Imgproc.drawContours(bgr, contourDraw, -1, new Scalar(0,255,0), 1);

Rect cord = Imgproc.boundingRect(approxContour);
Core.rectangle(bgr, new Point(cord.x, cord.y), new Point(cord.x+cord.width, cord.y+cord.height),new Scalar(0,255,0), 1);

ROI = bgrClone.submat(cord.y, cord.y+cord.height, cord.x, cord.x+cord.width);
showResult(ROI);
}


}

edit retag close merge delete

Sort by ยป oldest newest most voted

The following C++ code works OK. It finds all of the 8-gons, there's three of them. To differentiate between an octagon and some other shaped 8-gon, you would make sure that the 8-gon is convex, and that all 8 angles are roughly the same (2*pi / 8 radians).

#include <iostream>
using namespace std;

#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world340.lib")

int main(void)
{

threshold(stopsign_img, stopsign_img, 127, 255, THRESH_BINARY);

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours(stopsign_img, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

vector<vector<Point> > contours_poly(contours.size());

for (int i = 0; i < contours.size(); i++)
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);

Mat stopsign_contours = Mat::zeros(stopsign_img.size(), CV_8UC3);

for (int i = 0; i < contours_poly.size(); i++)
{
if(1 == contours_poly[i].size())
{
// a point
line(stopsign_contours, contours_poly[i][0], contours_poly[i][0], Scalar(0, 255, 0), 1, 8, 0);
}
else if (2 == contours_poly[i].size())
{
// a line segment
line(stopsign_contours, contours_poly[i][0], contours_poly[i][1], Scalar(0, 0, 255), 1, 8, 0);
}
else
{
if (8 == contours_poly[i].size())
cout << "8-gon found" << endl;

// an n-gon, where n = contours_poly[i].size()
for (int j = 0; j < contours_poly[i].size() - 1; j++)
line(stopsign_contours, contours_poly[i][j], contours_poly[i][j + 1], Scalar(255, 0, 0), 1, 8, 0);

line(stopsign_contours, contours_poly[i][contours_poly[i].size() - 1], contours_poly[i][0], Scalar(255, 0, 0), 1, 8, 0);
}
}

imshow("stopsign_contours", stopsign_contours);

waitKey(0);

destroyAllWindows();

return 0;
}

more

Official site

GitHub

Wiki

Documentation