Обнаружение небольших квадратов, прикрепленных к чему-то другому на изображении - PullRequest
1 голос
/ 26 января 2020

Я хочу обнаружить маленькие квадраты, обведенные красным на изображении. Но проблема в том, что они находятся на другой белой линии. Я хочу знать, как отделить эти квадраты от белой линии и обнаружить их.

Squares to be detected encircled in red

Я использовал OpenCV Python для написания кода. До сих пор я обрезал изображение, чтобы получить доступ только к круглой части изображения. Затем я обрезал изображение, чтобы получить необходимую часть - белую линию. Затем я использовал эрозию, чтобы белая линия исчезла sh, а квадраты остались на изображении. Затем использовал круги Хафа, чтобы обнаружить квадраты. Это работает для некоторых изображений, но не может быть обобщено. Пожалуйста, помогите мне найти обобщенный код для этого. Дайте мне знать лог c, а также код python. Cropped image with the arena(ring)

Cropped image with the white line

Eroded image with remains of those 8 squares after erosion

Final image with detected squares

Также кто-нибудь может помочь мне обнаружить этот маркер аруко на изображении. Его отклоняют. Я не знаю почему. Изображение в этой ссылке. Обнаружение небольших квадратов на изображении

1 Ответ

1 голос
/ 26 января 2020

вот код C ++ с функцией distanceTransform. Поскольку я почти использовал только функции openCV, вы, вероятно, можете легко преобразовать его в код Python.

Я удалил белую полосу вверху изображения вручную, надеюсь, что это не проблема.

int main()
{
    cv::Mat input =  cv::imread("C:/StackOverflow/Input/SQUARES.png", cv::IMREAD_GRAYSCALE);
    cv::Mat thres = input > 0; // make binary mas
    cv::Mat dst;
    cv::distanceTransform(thres, dst, CV_DIST_L2, 3);

    double min, max;
    cv::Point minPt, maxPt;
    cv::minMaxLoc(dst, &min, &max, 0, 0);

    double distThres = max*0.65; // a real clustering would be better. This assumes that the white circle thickness is a bout 50% of the square size, so 65% should be ok...

    cv::Mat squaresMask = dst >= distThres;

    cv::imwrite("C:/StackOverflow/Input/SQUARES_mask.png", squaresMask);

    std::vector<std::vector<cv::Point> > contours;
    cv::findContours(squaresMask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);


    cv::Mat output;
    cv::cvtColor(input, output, cv::COLOR_GRAY2BGR);
    for (int i = 0; i < contours.size(); ++i)
    {
        cv::Point2f center;
        float radius;
        cv::minEnclosingCircle(contours[i], center, radius);

        cv::circle(output, center, 5, cv::Scalar(255, 0, 255), -1);
        //cv::circle(output, center, radius, cv::Scalar(255, 0, 255), 1);
    }

    cv::imwrite("C:/StackOverflow/Input/SQUARES_output.png", output);

    cv::imshow("output", output);
    cv::waitKey(0);
}

это входные данные:

enter image description here

это квадратыМаска после преобразования расстояния

enter image description here

и это результат

enter image description here

...