Detect almost uniform color object

Hello,
I would like to detect some little almost color uniform object, on a picture.
I tried a lot of cv2 functions to highlight them, but no way.
Please, can you help me to do that ?
example

I want to detect the 3 objects which are almost color uniform

Than for your help

Hello
I’m not a native English speaker.
Please understand even if I am not good at expressing my words.

I think it is possible through the following process.

  1. Change the image to HSV or HSL.
  2. Next, determine the appropriate saturation range and make a corresponding mask image.
  3. Reduce hole noise through morphology operation and blurring of the mask image.
  4. AND operation of the mask image and the original image to obtain a desired result.

Looking at the example picture above, I think it would be possible to use a method of detecting high saturation.

I hope it helps you a little bit.

Best Regard

2 Likes

Hello,
I am not native English speaker neither. So, same for my expressing :upside_down_face:
Thank you for your help. I will try that. But I am not very aware about cv2. I may have to ask help on the different steps you propose.
I will come back if need.

https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html

1 Like

I tried a lot of things , but I am blocked on step 2(determine the appropriate saturation range)
I do not know how to do that, because I think the mask has to correspond to a color. (Am I right ?)
The problem is the colors of the objects may be different than this example.
So, I looked for some example to know how to have a good filter, but I really do not know how to do that.
Any idea ?

this is what i tried, actually : I tried to filter the 3 chanels:

    img_array =np.array(img)
    img_grey = cv2.cvtColor(img_array,cv2.COLOR_BGR2GRAY)

    # 1 HSV
    img_hsv = cv2.cvtColor(img_array, cv2.COLOR_BGR2HSV)

    # 2 Saturation
    # 2 1 determinate values

    val, mask = cv2.threshold(img_grey, 128, 255, cv2.THRESH_BINARY)
    h = cv2.calcHist([img_hsv], channels=[0], mask=mask, histSize=[32], ranges=[0, 255])
    skin1 = cv2.calcBackProject([img_hsv], [0], h, ranges=[0, 255], scale=1.0)
    skin2 = cv2.calcBackProject([img_hsv], [1], h, ranges=[0, 255], scale=1.0)
    skin3 = cv2.calcBackProject([img_hsv], [1], h, ranges=[0, 255], scale=1.0)

    cv2.imshow('h1', skin1)
    cv2.imshow('h2', skin2)
    cv2.imshow('h3', skin3)

But the result is not really good

Thank

Hi, sylvain_tymop.

I made a simple example and I’m going to show you the possibilities.

Of course, the quality is not perfect.
And the result is just an image of objects.
The location and number of objects are not known.

After that, you can find the number of Contours using FindContours().
You need to use momentum to locate it.

I also think it is necessary to bring objects from a close distance together for split objects.

I hope you achieve the results you want.

Best Regard,


PS) Example, There was a mistake in color conversion, so I corrected it.

import numpy as np
import cv2

imgSRC = cv2.imread(“D:\Resources\Images\Color Pattern\Color Objects.png”)
if (imgSRC is None):
print(“Oops! Image not loaded.”)
exit()

maxy, maxx = imgSRC.shape[:2]

if (maxx == 0):
print(“Oops! Image not loaded.”)
exit()

imgMSK = np.zeros((maxy, maxx, 3), np.uint8)
imgHLS = cv2.cvtColor(imgSRC, cv2.COLOR_BGR2HLS)

sLow = 128
sHi = 255
lLow = 64
lHi = 180

for y in range(maxy):
for x in range(maxx):
H = imgHLS[y, x][0]
L = imgHLS[y, x][1]
S = imgHLS[y, x][2]
if (sLow <= S and S <= sHi):
if (lLow <= L and L <= lHi):
imgMSK[y, x][0] = 255
imgMSK[y, x][1] = 255
imgMSK[y, x][2] = 255

kernel = np.ones((3, 3), np.uint8)
imgMSK = cv2.erode(imgMSK, kernel, 1)
imgMSK = cv2.dilate(imgMSK, kernel, 3)
imgMSK = cv2.erode(imgMSK, kernel, 2)

imgRST = cv2.bitwise_and(imgHLS, imgMSK)
imgBGR = cv2.cvtColor(imgRST, cv2.COLOR_HLS2BGR)

cv2.imshow(“SRC”, imgSRC);
cv2.imshow(“RESULT”, imgBGR);
cv2.waitKey(0)
cv2.destroyAllWindows()

Hello.
I adapted a little, because I had some errors.
But this seems to work pretty well (tested on 2 pictures)
thanks a lot.
Now, I have to digest and understand your code.
Many thanks.

    imgsrc = np.array(img)

    maxy, maxx = imgsrc.shape[:2]

    imgMSK = np.zeros((maxy, maxx, 3), np.uint8)
    imgHLS = cv2.cvtColor(imgsrc, cv2.COLOR_BGR2HLS)

    sLow = 128
    sHi = 255
    lLow = 64
    lHi = 180

    for y in range(maxy):
        for x in range(maxx):
            H = imgHLS[y, x][0]
            L = imgHLS[y, x][1]
            S = imgHLS[y, x][2]
            if (sLow <= S and S <= sHi):
                if (lLow <= L and L <= lHi):
                    imgMSK[y, x][0] = 255
                    imgMSK[y, x][1] = 255
                    imgMSK[y, x][2] = 255

    kernel = np.ones((3, 3), np.uint8)
    imgMSK = cv2.erode(imgMSK, kernel, 1)
    imgMSK = cv2.dilate(imgMSK, kernel, 3)
    imgMSK = cv2.erode(imgMSK, kernel, 2)

    imgRST = cv2.bitwise_and(imgHLS, imgMSK)
    imgBGR = cv2.cvtColor(imgRST, cv2.COLOR_HLS2BGR)

    cv2.imshow('SRC', imgsrc)
    cv2.imshow('RESULT', imgBGR)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
1 Like