1

I am trying to create an app that could detect the traffic signs from the camera. However, I meet some difficulties about detecting the sign.

Since the traffic signs might be different in color, so I hope to detect the shape of the sign first.

I have tried to find all the contours first and try to detect the shape of each contour. However, the contour of the sign is not clear enough and the tree background contains lots of small contours that would affect the detection. So that the program is not able to find the complete contour of the traffic sign. I know that using fastNlMeansDenoisingColored() from openCV could significantly remove the noise and make to detection become more accurate. But it is too slow for the real time processing.

I am not only checking the circular signs, but also the the triangular or quadrilateral sign. Therefore, I hope to find the contour of all objects first and try to check the shape of the object.

Here is the code I used to find the contours inside the picture, and it's result. I am going to develop an iOS app, so it is in objective-c.

- (cv::Mat)findSigns:(cv::Mat)src {
    Mat edge;
    Mat src_gray;
    cvtColor(src, src_gray, COLOR_RGB2GRAY);
    medianBlur(src_gray, src_gray, 5);
    Canny(src_gray, edge, 80, 80, 3);
    Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3,3));
    Mat dilated;
    cv::dilate(edge, dilated, kernel);
    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
    RNG rng(12345);
    cv::findContours(edge, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    Scalar color = Scalar(255, 0, 255);
    for(int i = 0; i<contours.size(); i++){
        std::vector<cv::Point> c = contours[i];
        double area = cv::contourArea(c);
        if (area > 100) {
            drawContours(src, contours, i, color, 2, 8, hierarchy);
        }
    }

    edge.release();
    src_gray.release();
    kernel.release();
    dilated.release();

    return src;
}

src picture:

src picture

result without filtering out the contours with small area

Since there are too much contours, so I tried to remove the contours with small area. And here is the result.

final result

Besides, I have also tried to check if hierarchy[i][2] == -1 to see if there is any closed contours. But all of them are equal to -1.

May I know how should I detect the shape of the traffic signs? Should I remove the tree background by removing the green object for easier detection?

Dan Mašek
  • 17,852
  • 6
  • 57
  • 85
boboboboboboo
  • 41
  • 1
  • 6
  • You noticed that there are various questions on stackoverflow covering that exact topic? – Swordfish Nov 13 '18 at 11:52
  • @Swordfish Yes, I have read this page https://stackoverflow.com/questions/32797073/opencv-speed-traffic-sign-detection. Someone suggested that ellipse detection could be used, but I am not only detecting the circular sign. I also hope to detect the triangular or quadrilateral sign. Therefore, I hope to find some means that could make the findContours function become more accurate. Such that, I could try to analysis the contours and check the shape of the object. I would try to read more questions on stackoverflow and find the answer. Thank you. – boboboboboboo Nov 13 '18 at 12:41
  • Please, do not add "[solved]" to the question title. Please read the [help](https://stackoverflow.com/help/someone-answers) on how to correctly handle this. – Dan Mašek Nov 13 '18 at 16:34
  • you could try to threshold for red and/or white colors to detect red traffic signs and blue color for blue signs. – Micka Nov 13 '18 at 19:57
  • you could try to use only inner contours, since there is a white area around the red sign – Micka Nov 13 '18 at 19:59
  • give lineSegmentDetector a chance. Probably not optimal for circle objects, but typically much less cluttered edges. – Micka Nov 13 '18 at 20:01
  • @Micka Thank you for your suggestion, I would try the lineSegmentDetector later. I have tried to increase the color contrast before finding the contours and I think it performs quite well on detecting the contours. – boboboboboboo Nov 14 '18 at 03:10

1 Answers1

0

To detect the contours correctly, you need to first smooth the image.

Please check the link for reference. Link: http://answers.opencv.org/question/164533/how-to-smooth-the-edges-of-a-low-quality-image/

SAIF
  • 126
  • 8
  • I have tried different blur function in opencv before, but the contours are still not correct. Besides, I have also tried to increase the ksize of medianBlur(src, src_copy, ksize). The results becomes more accurate, but the run time is too slow. Since I am going to detect the sign in real time, so the run time should not be that slow : ( – boboboboboboo Nov 13 '18 at 13:19