Home > Mobile >  Show single channel in it's color (not grayscale) with OpenCV
Show single channel in it's color (not grayscale) with OpenCV

Time:06-17

I can successfully convert a BGR image to CMYK and I get a array of size (height, width, 4), the 4 being the C, M, Y and K channels, ranging from 0 to 1.

After I split that CMYK array, I have 4 arrays of size (height, width) that indicates me the amount of C, M, Y and K for each pixel.

If I want to show only the C (cyan) channel for exemple, I cannot use cv.imshow('Cyan', C) because it gives me a grayscale image, as expected.

So, how can I show the C channel/array in cyan, with the correct amount of "saturation" based on the C array ?
Or, how can I get that grayscale image to show cyan, with the same "saturations" in cyan for each pixel ?

EDIT:

My goal is to split an BGR image into 4 channels (C, M, Y and K) that give me the amount of color (cyan, magenta, yellow or black) I should use for each pixel to represent the image, in full colours, on a white background (as a printer would do it).

Exemple:

This image:

full color image

Would be split like this:

cmyk channels split

Those 4 'channels' stacked/painted on a white background would give the full colour image.
So I would like to be able to generate those 4 images and to have a way to know the quantity of each color (cyan, magenta, yellow, black) needed for each pixel (for additive coloring on white surface)

CodePudding user response:

Once you go to CMYK, you do not have saturation. For that you need HSV and separate the S channel. You can then colorize the S channel with cyan if you want in Python OpenCV by setting the blue and green channels to some fixed values such as 255.

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread("barn.jpg")

# convert to HSV and get S channel
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
s = hsv[:,:,1]

# make 3 equal channels, then colorize with cyan (blue = green = 255)
s_cyan = cv2.merge([s,s,s])
s_cyan[:,:,0] = 255
s_cyan[:,:,1] = 255

# write results to disk
cv2.imwrite("barn_saturation_cyan.jpg", s_cyan)

# show results
cv2.imshow('s_cyan', s_cyan)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:

enter image description here

If by "saturations" you just mean "intensities", then you can colorize the CMYK cyan channel, by separating cyan from your CMYK image and do the same colorization of setting blue = green = 255 after converting the single channel image to 3 equal channels.

CodePudding user response:

Here are two ways to colorize the (grayscale) cyan channel in Python/OpenCV with a cyan color.

Method 1: Get cyan channel from CMYK colorspace. Convert grayscale channel to 3 channels and set the blue and green channels with value of 255

Method 2: Get the cyan channel from CMY colorspace as float. Create a "red" image of the same dimensions and type. Then multiply the two and divide by 255, invert and convert the result to uint8. Note that red is the complement of cyan and inverting complements it back. I used cyan from CMY, since it produces a result closer to what you show. See the difference of cyan from CMY and CMYK at enter image description here

Colorized by method 1:

enter image description here


Input (C from CMY):

enter image description here

Colorized by method 2:

enter image description here


For completeness, here is the result of colorizing cyan from CMYK using method 2:

enter image description here

  • Related