# color detection in different background of human machine interface

Now I want to use a camera to help me look at the human-machine interface of plc so I can fool around during working.

When I do a little test, I use InRange function to detect some yellow color in HSV color space in (H,S,V)=(10,45,150)~(30,255,255)

at first, everything is fine.

However, if I want to change the background to other colors, all things go wrong. I change to a slightly yellow background and the colors go wired and the HSV range does not work for now.

and green background, you can see that the color of the lights changed.

I think this is a white-balance issue so I try to write a white balance algorithm such as gray world white balance but It didn't help this situation. I also disable the white balance of my camera but the color shifting is still there. what kind of keyword I can search for this problem?

edit retag close merge delete

Sort by » oldest newest most voted

Here are the steps that seem to work well from left to right in the image below.

1. original image

2. apply Sobel filter with 5x5 kernel and first order derivatives in both x and y

3. convert to mono and threshold about 80

4. dilation with Rect 3x3 kernel for 4 iterations

From, here you can filter contours by aspect ratio and size so only the powdered donuts are left.

And here are the results on all three.

Here was my simple white balance trick. After finding the locations of the lights, pick an area in between 2 lights that should be background. Use OpenCV mean to get the average rgb values in this background area. A "white" background should have r==b==g but some of these images are blue-green. So compute an offset or delta that will change this average so that rgb are all equal and apply this delta to the whole image.

Scalar colorAvg = mean(srcImg, maskImg);

float channelAvg = (colorAvg[0] + colorAvg[1] + colorAvg[2]) / 3;

Scalar delta(channelAvg - colorAvg[0], channelAvg - colorAvg[1], channelAvg - colorAvg[2]);

balanceImg = srcImg + delta;
enter code here


Then using the found locations of the lights, set up a mask that is a semicircle on the bottom half of the light (first image below). The reason for this is to avoid the glare on the top half of the light. Then we can use OpenCV mean to get the average rgb values in that masked area for each different light. Then I apply this logic to the rgb mean: if (g > r && g > b) then green else if (r > 1.3 * max(b, g)) then red else yellow

more

thanks for the answer. But actually what I need is to detect the yellow color.

( 2019-05-14 19:03:49 -0500 )edit

Official site

GitHub

Wiki

Documentation