Я ищу несколько примеров того, как реализовать грубое преобразование для обнаружения треугольников. Это для обнаружения знака необходимо. Я уже сделал цветовой порог. Что вы думаете об использовании HoughLinesP()
? Я делаю Canny, затем устанавливаю пороги и использую HoughLines, но в результате получается много строк, и они тоже находятся внутри моего знака. Я не думаю, что нахождение пересечения сейчас будет моим решением.
Как вы думаете? Есть примеры или другие идеи? Я также пытался findContours()
, но треугольники закруглены, поэтому они нуждаются в большом приближении, и это делает обнаружение мусора полным.
На мой взгляд, это будет очень сложно использовать HoughLinesP
для этой задачи, потому что она нестабильна и сильно зависит от предварительной обработки входных изображений и параметров. Некоторое время назад я решил аналогичную задачу и рекомендую вам следующий конвейер обработки (при условии, что входное изображение имеет оттенки серого):
cv::blur
для улучшения изображенияcv::MSER
чтобы найти регионы (нужно настроить параметры здесь). Вы можете отказаться от небольших регионов.Для каждого региона:
3.1. cv::convexHull
найти выпуклую оболочку региона.
3.2. Делать cv::approxPolyDP
для выпуклой оболочки с увеличением epsilon
параметр, пока он не возвращает 3 или менее полилиний. Вы можете отклонить регионы с количеством строк менее 3.
3.3. Наконец, вы можете рассчитать углы между линиями и проверить, что это треугольник. Если все углы ближе к 60 градусам (или чуть меньше 90 градусов), отметьте этот регион как треугольник.
Надеюсь, это поможет. Если вы успешно решите эту задачу, пожалуйста, опишите ваш опыт здесь.
Проблема в том, что число строк чрезвычайно велико или равно одному. Это мой код:
#define red 10, 180, 180, 25, 255, 255
void SetScalars(int h1, int s1, int v1, int h2, int s2, int v2){
color_min = Scalar(h1, s1, v1);
color_max = Scalar(h2, s2, v2);
}
void triangles(){
ToHSV();
SetScalars(red);
Thresh();
Mat dst = frame.clone();
vector<vector<Point>> contours;
blur(frame_thresh, frame_thresh, Size(3, 3));
MSER(15,250,1000,0.15)(frame_thresh, contours);
// Find the convex hull object for each contour
vector<vector<Point> >hull(contours.size());
for (int i = 0; i < contours.size(); i++)
{
int vtc = hull[i].size();
convexHull(Mat(contours[i]), hull[i], false);
approxPolyDP(Mat(contours[i]), hull[i], arcLength(Mat(contours[i]), true) * 0.1, true);
cout << vtc << endl;
if (vtc == 3){
vector<double> cos;
cos.push_back(angle(hull[i][0], hull[i][1], hull[i][2]));
cos.push_back(angle(hull[i][1], hull[i][2], hull[i][0]));
cos.push_back(angle(hull[i][0], hull[i][2], hull[i][1]));
sort(cos.begin(), cos.end());
double mincos = cos.front();
double maxcos = cos.back();
if (vtc == 3 && mincos > 0.4 && maxcos < 0.6){
Rect r = boundingRect(contours[i]);
Mat croppedImage = dst(r);
imshow("detected triangle", croppedImage);
}
}
}
Mat drawing = Mat::zeros(frame_thresh.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
drawContours(drawing, contours, i, Scalar(0,0,255));
drawContours(drawing, hull, i, Scalar(255, 0, 255));
int vtc = hull[i].size();
}
imshow("mser", drawing);
}
То, что вы ищете, это Обобщенное преобразование Хафа который является обобщением преобразования Хафа для обнаружения произвольных форм. Таким образом, вы можете указать свою форму в виде треугольника.
В OpenCV есть реализация Generalized Hough:
http://docs.opencv.org/master/d7/dd4/classcv_1_1GeneralizedHough.html
и вы можете использовать метод setTemplate, чтобы определить свою форму.