manatttta
manatttta

Reputation: 3130

Identify large lines on image

I have images that consist of vegetation disponsed in lines (may or may not be straight lines).

I need to implement an algorithm that identifies those lines and produces a binary mask image tagging the vegetation pixels. This mask can whether be a dense mask (flagging all the identified vegetation pixels) or skeleton mask (1-pixel wide lines identifying the center of the vegetation lanes).

Here is an example of input images:

Image 1

And here is one of the possible expected outputs:

Example output

So far, I've tried the following approaches which result in the following problems:

Anyone has more ideas?

Thanks

Upvotes: 2

Views: 137

Answers (2)

Jeru Luke
Jeru Luke

Reputation: 21233

If working in RGB color space does not help you, try a different one. For the particular image given, I used the HSV color space.

1. HSV image:

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('hsv.jpg', hsv)

enter image description here

2. Extracting the saturation channel yields this:

saturation_channel = hsv[:,:,1]
cv2.imshow('saturation_channel.jpg', saturation_channel)

enter image description here

3. Applying an adaptive threshold on this image yields the following:

median = np.median(saturation_channel)
std = np.std(saturation_channel)

ret,thresh1 = cv2.threshold(saturation_channel, int(median - (1.05 * std)), 255,cv2.THRESH_BINARY_INV)
cv2.imwrite('thresh1.jpg', thresh1)

enter image description here

4. Now you can apply some morphological operations and mask it with the original image

NOTE: You can also convert the image to LAB color space and visualize the different channels.

The same image in LAB color space:

enter image description here

Upvotes: 3

zindarod
zindarod

Reputation: 6468

You can blur the image before applying Canny and then remove Canny noise by calculating best threshold. After that you can use HoughLinesP or your method of choice to detect the lines.

cv::Mat src=imread("image.png",-1),dst;

cv::GaussianBlur(src, dst, Size(3,3), 1.0); //blur the source image

cv::cvtColor(dst,dst,cv::COLOR_BGR2GRAY); //convert to gray

cv::Scalar m = cv::mean(dst); //calculate mean

//Calculate lower and upper threshold based on mean
double sigma = 0.33;
double lower_thresh = int(std::max((double)0, ((1.0 - sigma) * m[0])));
double upper_thresh = int(std::min((double)255, ((1.0 + sigma) * m[0])));

cv::Canny(dst, dst, lower_thresh, upper_thresh, 3); //apply canny

Blurred image:

Blurred image

Canny:

Canny

Upvotes: 0

Related Questions