Как найти треугольник на изображении без deep learning
Что проверяют
Знаете ли вы классический конвейер компьютерного зрения и умеете ли собрать его в рабочий код за время собеседования. Следом обычно усложняют условие: треугольник повёрнут, частично перекрыт, лежит на шумном фоне или его нужно отличить от других фигур.
Как отвечать
Самый надёжный путь через контуры, в OpenCV он укладывается в десяток строк:
- предобработка:
cv2.cvtColorв оттенки серого,cv2.GaussianBlurпротив шума; - бинаризация или границы:
cv2.thresholdсTHRESH_OTSUдля контрастной фигуры илиcv2.Cannyдля сложного фона. После Canny иногда полезенcv2.dilate, чтобы замкнуть разрывы контура; - контуры:
cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE). В OpenCV 4 функция возвращает два значения, контуры и иерархию; - аппроксимация:
cv2.approxPolyDP(cnt, eps, True), гдеepsберут долей периметра, обычно около0.02 * cv2.arcLength(cnt, True). Если вершин три иcv2.isContourConvexвозвращаетTrue, это кандидат; - фильтрация: отсечь мелкий шум по
cv2.contourArea, при необходимости проверить углы через скалярное произведение векторов сторон.
Альтернативы стоит назвать вместе с условиями. cv2.HoughLinesP и поиск пересечений троек линий спасают, когда контур рваный или фигура нарисована тонкими линиями, но требуют склейки почти одинаковых отрезков. cv2.matchShapes на моментах Ху сравнивает контур с эталоном и устойчив к повороту и масштабу. cv2.matchTemplate годится, только если размер и ориентация известны заранее.
Где спотыкаются
Берут фиксированный eps в пикселях. Для маленького треугольника он слишком грубый, для большого слишком мелкий, и фигура распознаётся то как отрезок, то как четырёхугольник.
Забывают, что findContours ищет белые объекты на чёрном фоне. Тёмный треугольник на светлом фоне без инверсии маски (THRESH_BINARY_INV) превращается в один контур по краю картинки.
Перебирают все тройки линий Хафа без группировки. На реальном изображении это сотни почти совпадающих отрезков, перебор становится кубическим, а каждая настоящая фигура находится десятки раз.