how to remove straight lines or non-curvical lines in a canny image
Solution 1:
A simple approach would be:
- Find connected components
- Find the minimum oriented bounding box
- 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:
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:
- Find contours from edge.
- Get bounding box.
- 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