как удалить прямые линии или некривые линии в хитроумном изображении

У меня есть изображение хитрого края введите здесь описание изображения

Я хочу удалить все строки, кроме линий, которые выглядят как полукруг/эллипс или буква «С». Пробовал преобразование Hough Circle, он обнаруживает все кривые. Это не нужно.


person Abhishek V. Pai    schedule 04.05.2016    source источник
comment
1. попробуйте извлечь каждый подключенный компонент. 2. попытайтесь определить, прямой ли он. Например, используйте PCA и сравните оба основных компонента. pdfs.semanticscholar.org/92ce/   -  person Micka    schedule 04.05.2016


Ответы (2)


Простым подходом будет:

  1. Найдите связанные компоненты
  2. Найдите минимальный ориентированный ограничивающий прямоугольник
  3. Вычислите соотношение сторон окна и проверьте, не слишком ли оно вытянуто.

На вашем изображении я отметил красным цветом почти прямые линии, а зеленым – изогнутые линии. Вы можете поиграть с порогом соотношения сторон:

введите описание изображения здесь

Код:

#include<opencv2/opencv.hpp>
using namespace cv;


int main()
{
    // Load image
    Mat1b img = imread("path_to_img", IMREAD_GRAYSCALE);

    // Create output image
    Mat3b out;
    cvtColor(img, out, COLOR_GRAY2BGR);

    // Find contours
    vector<vector<Point>> contours;
    findContours(img.clone(), contours, RETR_LIST, CHAIN_APPROX_NONE);

    for (const auto& contour : contours)
    {
        // Find minimum area rectangle
        RotatedRect rr = minAreaRect(contour);

        // Compute aspect ratio
        float aspect_ratio = min(rr.size.width, rr.size.height) / max(rr.size.width, rr.size.height);

        // Define a threshold on the aspect ratio in [0, 1]
        float thresh = 0.2f;

        Vec3b color;
        if (aspect_ratio < thresh) { 
            // Almost straight line
            color = Vec3b(0,0,255); // RED
        }
        else {
            // Curved line
            color = Vec3b(0, 255, 0); // GREEN
        }

        // Color output image
        for (const auto& pt : contour) {
            out(pt) = color;
        }
    }

    imshow("Out", out);
    waitKey();

    return 0;
}
person Miki    schedule 04.05.2016

  1. Найдите контуры от края.
  2. Получить ограничительную рамку.
  3. Вычислить отношение размера диагонали ограничивающей рамки к размеру контура.

Это значение будет близко к «1» для прямых краев. Чем выше значение этого коэффициента, тем извилистым будет край. Он может грубо, но довольно точно оценить волнистость края.

Удачного кодирования

person Pervez Alam    schedule 04.05.2016