how to remove straight lines or non-curvical lines in a canny image

Solution 1:

A simple approach would be:

  1. Find connected components
  2. Find the minimum oriented bounding box
  3. Compute the aspect ratio of the box, and check if it's too much elongated.

On your image, I marked in red almost straight lines, and in green the curved lines. You can play with the threshold on the aspect ratio:

enter image description here

Code:

#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;
}

Solution 2:

  1. Find contours from edge.
  2. Get bounding box.
  3. Calculate ratio of size of diagonal of bounding box to size of contour.

This value will be close to '1' for straight edges. The higher the value of this ratio, the curvy the edge is going to be. It can roughly but quite accurately estimate curliness of the edge.

Happy coding