Is There a Formula to Determine Overall Color Given Bgr Values? (Opencv and C++)

Converting an OpenCV BGR 8-bit Image to CIE L*a*b*

That's because L value is in range [0..255] in OpenCV. You can simply scale this value to needed interval ([0..100] in your case).

Discover an image from under bright color bars

The first thing that jumps out about your example image is that the color bands are very RGB-specific; the colors overlaid are pure red, green, blue, magenta, yellow, cyan, and white. This seems to suggest that the way that the image is modified is to send some random selection of the channels to 255 (or otherwise scale them up by some constant or multiplier). None of the bright spots in the image get darkened, which suggests that the values are only changed to higher values. The values are a little fuzzy as well, due to the image being a compressed jpeg.

To see this behavior a little more closely, we can take a look at the distribution of values in each color channel in the image over a specific column of the image. For example, the first column of the image has the following color distribution for the pixels:

hist

It's super obvious from this plot that the distribution of values on the red channel is completely different from the green and blue channels, and that all of the values are near the maximum for the red channel. This suggests a detection strategy of taking the median or mean of each channel over each column and threshold it to select the "bad" channels. For example, whatever channels have an average value over 230 or something for each column is a "bad" channel. Running through this process gives the following channels as bad; you can see that it maps pretty closely to the actual color bands in the image:

thresh

orig

You could also use statistical techniques, e.g. threshold the standard deviation instead of the actual values (or use some combination of values, standard deviation, skewness, kurtosis, etc) for some robustness.

We can impute the values in the bad channels with the mean or median of the rest of the channels:

clean from std < thresh

However, you can see there's some bright single-column strips throughout when you do this, which correspond to columns where the bad channel identification failed a bit. The failures happen partly because the image is a jpeg, partly because some of the colors blend together (i.e., the color changes don't necessarily happen right on the edge of a pixel), hard to select the right threshold, and so on. These issues are easier to see on an enlarged image:

enlarged

However, we can do something much simpler than all the above. In particular, for each column, we know that the bad channels are always the brightest channels. Since the image is grayscale ultimately, we only need one channel for every pixel. That means that we can simply pick the darkest channel for each column, and we'll never get a bad column (unless all three channels are bad, in which case the information is destroyed).

So the process is just to select the minimum over the color channels for each column, which is much more easily expressed in code than the above approaches. And we don't have to tune any thresholds, either.

# take the average value over each column
mean_columns = np.mean(img, axis=0)

# find the channels which have the minimum average value
channel_select = np.argmin(mean_columns, axis=1)

# reshape the result just to be passed into take_along_axis
channel_select = np.expand_dims(channel_select, axis=(0, 2))

# take the selected channels, squeeze just removes an unnecessary axis
gray = np.take_along_axis(img, channel_select, axis=2).squeeze()

And here's the result from that operation:

corrected

A tidy way you can view this is a grayscale image in RGB has three identical channels, i.e. it holds redundant information. Some of your image columns are corrupted by some of the channels being scaled up in value, but the minimum value is invariant under this process unless all the channels are corrupted. So exploiting this invariant allows you to recover most of the data.



Related Topics



Leave a reply



Submit