2

I have a picture with high and low contrast transitions.

enter image description here

I need to detect edges on the above picture. I need binary image. I can easily detect the black and "dark" blue edges with Sobel operator and thresholding.

However, the edge between "light" blue and "light" yellow color is problematic.

I start with smooth image with median filter for each channel to remove noise.

What I have tried already to detect edges:

  • Sobel operator
  • Canny operator
  • Laplace
  • grayscale, RGB, HSV, LUV color spaces (with multichannel spaces, edges are detected in each channel and then combined together to create one final edge image)
  • Preprocessing RGB image with gamma correction (the problem with preprocessing is the image compression. The source image is JPG and if I use preprocessing edge detection often ends with visible grid caused by JPG macroblocks.)

So far, Sobel on RGB works best but the low-contrast line is also low-contrast.

enter image description here

Further thresholding remove this part. I consider edge everything that is under some gray value. If I use high threshold vales like 250, the result for low contrast edge is better but the remaining edges are destroyed. Also I dont like gaps in low-contrast edge.

enter image description here

So, if I change the threshold further and say that all except white is edge, I have edges all over the place.

enter image description here

Do you have any other idea how to combine low and high contrast edge detection so that the edges are without gaps as much as possible and also not all over the place?

Note: For test I use mostly OpenCV and what is not available in OpenCV, I programm myself

4

2 回答 2

3

IMO this is barely doable, if doable at all if you want an automated solution.

Here I used binarization in RGB space, by assigning every pixel to the closest color among two colors representative of the blue and yellow. (I picked isolated pixels, but picking an average over a region would be better.)

enter image description here

Maybe a k-means classifier could achieve that ?


Update:

Here is what a k-means classifier can give, with 5 classes.

enter image description here

于 2020-09-03T08:04:21.030 回答
1

All kudos and points to Yves please for coming up with a possible solution. I was having some fun playing around experimenting with this and felt like sharing some actual code, as much for my own future reference as anything. I just used ImageMagick in Terminal, but you can do the same thing in Python with Wand.

So, to get a K-means clustering segmentation with 5 colours, you can do:

magick edge.png -kmeans 5 result.png

enter image description here

If you want a swatch of the detected colours underneath, you can do:

magick edge.png \( +clone -kmeans 5 -unique-colors -scale "%[width]x20\!" \) -background none -smush +10 result.png

enter image description here

Keywords: Python, ImageMagick, wand, image processing, segmentation, k-means, clustering, swatch.

于 2020-09-03T09:48:15.300 回答