简体   繁体   中英

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

Stop Sign:

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)

        contourDraw.add(approxContour);
        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);
    }
  }

I am using Java but any in any language would be appreciated.

You can perform shape detection using contours with OpenCV. I implemented the following in python.

Steps:

  1. Since you are dealing with traffic signs, most of them would be red in color. In the RGB color space the amount of red is the highest in the red channel. But since white color also comprises of red I did not use it. I rather used the blue channel where red content is minimal.

Blue channel image:

在此处输入图片说明

  1. Next I applied Otsu threshold to the image above and inverted it.

Otsu threshold and Inversion:

在此处输入图片说明

  1. Finally I found contours and marked those contours having roughly 8 arcs around it.

Final Result:

在此处输入图片说明

Code:

import numpy as np
import cv2
import os

path = r'C:\Desktop\Stack\contour\shape_detection'
filename = 'stop.png'

img = cv2.imread(os.path.join(path, filename), 1)
cv2.imshow('img1',img[:,:,0])

ret,thresh1 = cv2.threshold(img[:,:,0], 0, 255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
cv2.imshow('thresh1', thresh1)

_, contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for cnt in contours:
    approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
    print len(approx)
    if len(approx)==8:
        print "octagon"
        cv2.drawContours(img, [cnt], 0, (0, 255, 0), 6)

cv2.imshow('sign', img)       
cv2.waitKey(0)
cv2.destroyAllWindows()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM