简体   繁体   English

如何将 rgb 图像转换为 cmyk?

[英]How to convert a rgb image into a cmyk?

I want to convert a RGB image into CMYK.我想将 RGB 图像转换为 CMYK。 This is my code;这是我的代码; the first problem is when I divide each pixel by 255, the value closes to zero, so the resulting image is approximately black!第一个问题是当我将每个像素除以 255 时,值接近于零,因此生成的图像大约是黑色的! The second problem is that I don't know how to convert the one-channel resultant image to 4 channels.第二个问题是我不知道如何将单通道结果图像转换为 4 通道。 Of course, I'm not sure the made CMYK in the following code is correct.当然,我不确定以下代码中制作的 CMYK 是否正确。 Thank you for your attention感谢您的关注


CMYK 公式 特朗普博士!

import cv2
import numpy as np
import time

img = cv2.imread('image/dr_trump.jpg')

B = img[:, :, 0]
G = img[:, :, 1]
R = img[:, :, 2]

B_ = np.copy(B) 
G_ = np.copy(G)
R_ = np.copy(R)

K = np.zeros_like(B) 
C = np.zeros_like(B) 
M = np.zeros_like(B) 
Y = np.zeros_like(B) 

ts = time.time()

for i in range(B.shape[0]):
    for j in range(B.shape[1]):
        B_[i, j] = B[i, j]/255
        G_[i, j] = G[i, j]/255
        R_[i, j] = R[i, j]/255

        K[i, j] = 1 - max(B_[i, j], G_[i, j], R_[i, j])
        if (B_[i, j] == 0) and (G_[i, j] == 0) and (R_[i, j] == 0):
        # black
              C[i, j] = 0
              M[i, j] = 0  
              Y[i, j] = 0
        else:
        
            C[i, j] = (1 - R_[i, j] - K[i, j])/float((1 - K[i, j]))
            M[i, j] = (1 - G_[i, j] - K[i, j])/float((1 - K[i, j]))
            Y[i, j] = (1 - B_[i, j] - K[i, j])/float((1 - K[i, j]))


CMYK = C + M + Y + K 
        
t = (time.time() -ts)
print("Loop: {:} ms".format(t*1000))


cv2.imshow('CMYK by loop',CMYK)
cv2.waitKey(0)
cv2.destroyAllWindows()

You can let PIL/Pillow do it for you like this:你可以让 PIL/Pillow 像这样为你做这件事:

from PIL import Image

# Open image, convert to CMYK and save as TIF
Image.open('drtrump.jpg').convert('CMYK').save('result.tif')

If I use IPython , I can time loading, converting and saving that at 13ms in toto like this:如果我使用IPython ,我可以像这样以 13 毫秒时间加载、转换和保存它:

%timeit Image.open('drtrump.jpg').convert('CMYK').save('PIL.tif')
13.6 ms ± 627 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

If you want to do it yourself by implementing your formula, you would be better off using vectorised Numpy rather than for loops.如果你想通过实现你的公式来自己做,你最好使用向量化的 Numpy 而不是for循环。 This takes 35ms.这需要 35 毫秒。

#!/usr/bin/env python3

import cv2
import numpy as np

# Load image
bgr = cv2.imread('drtrump.jpg')

# Make float and divide by 255 to give BGRdash
bgrdash = bgr.astype(np.float)/255.

# Calculate K as (1 - whatever is biggest out of Rdash, Gdash, Bdash)
K = 1 - np.max(bgrdash, axis=2)

# Calculate C
C = (1-bgrdash[...,2] - K)/(1-K)

# Calculate M
M = (1-bgrdash[...,1] - K)/(1-K)

# Calculate Y
Y = (1-bgrdash[...,0] - K)/(1-K)

# Combine 4 channels into single image and re-scale back up to uint8
CMYK = (np.dstack((C,M,Y,K)) * 255).astype(np.uint8)

If you want to check your results, you need to be aware of a few things.如果你想检查你的结果,你需要注意一些事情。 Not all image formats can save CMYK, that's why I saved as TIFF.并非所有图像格式都可以保存 CMYK,这就是我保存为 TIFF 的原因。 Secondly, your formula leaves all your values as floats in the range 0..1, so you probably want scale back up by multiplying by 255 and converting to uint8.其次,您的公式将所有值保留为 0..1 范围内的浮点数,因此您可能希望通过乘以 255 并转换为 uint8 来扩大规模。

Finally, you can be assured of what the correct result is by simply using ImageMagick in the Terminal:最后,只需在终端中使用ImageMagick ,您就可以确定正确的结果是什么:

magick drtrump.jpg -colorspace CMYK result.tif

You don't need to do CMYK = C + M + Y + K .你不需要做CMYK = C + M + Y + K

I don't know how to convert the 1 channel resulted image to 4 channel.我不知道如何将 1 通道结果图像转换为 4 通道。

For ndim arrays you can use numpy.dstack .对于ndim数组,您可以使用numpy.dstack Documentation link .文档链接

Edit编辑

The incorrect results are caused due to int division.不正确的结果是由于int除法造成的。 You need to perform float division.您需要执行浮点除法。 One method to achieve that is to convert array B , G , and R to float实现这一点的一种方法是将数组BGR转换为float

B = img[:, :, 0].astype(float) # float conversion, maybe we can do better. But this results in correct answer
G = img[:, :, 1].astype(float) #
R = img[:, :, 2].astype(float) #

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM