[英]How to desaturate one color in an image using OpenCV2 in Python?
所以我正在運行一些應該允許我去飽和然后使圖像飽和的代碼。 我有一個應該允許我這樣做的函數,但無論我如何更改代碼,它總是會改變顏色,因此它不會去飽和。
我的功能:
def desaturation(img,percent=.5):
imgGreen=img[:,:,1]
desatGreen=imgGreen*percent
desatImg=img[:,:,:]
desatImg[:,:,1]=desatGreen
return desatImg
每次運行它時,它都會將顏色變為洋紅色,而不是我期望的不飽和外觀。 我希望顏色范圍仍然保留在 BGR 中,而不是任何其他顏色范圍。 是否有任何代碼可以幫助我解決這個問題,原始而不是依賴另一個內置函數?
編輯:我設置了百分比變量,因此它永遠不會超過 1,也永遠不會低於 0。
編輯:我想降低整個圖像的飽和度。 我的代碼編寫方式有點誤導。
這是在 Python OpenCV 中降低綠色飽和度的一種簡單方法。 這樣做的方法是轉換為 CMYK,然后去飽和 C 和 Y 通道。 不幸的是,OpenCV 沒有內置的 BGR2CMYK 顏色轉換。 所以需要進行計算。 這種方法也會影響其他顏色。
輸入:
import cv2
import numpy as np
img = cv2.imread("barn.jpg")
scale = 255
percent = 0.5
#percent = 0.25
#percent = 0
# separate b,g,r
b,g,r = cv2.split(img)
b = b.astype(np.float32)
g = g.astype(np.float32)
r = r.astype(np.float32)
# convert to cmyk
# see
# https://stackoverflow.com/questions/14088375/how-can-i-convert-rgb-to-cmyk-and-vice-versa-in-python/41220097
# https://www.codeproject.com/Articles/4488/XCmyk-CMYK-to-RGB-Calculator-with-source-code
c = 1 - r / scale
m = 1 - g / scale
y = 1 - b / scale
k = cv2.min(cv2.min(c, m),y)
c = scale * (c - k) / (1 - k)
m = scale * (m - k) / (1 - k)
y = scale * (y - k) / (1 - k)
# desaturate neighbors of G which are C,Y
c = cv2.multiply(c, percent)
y = cv2.multiply(y, percent)
# convert back to bgr
r = scale * (1.0 - c / scale) * (1.0 - k)
g = scale * (1.0 - m / scale) * (1.0 - k)
b = scale * (1.0 - y / scale) * (1.0 - k)
r = r.clip(0,255).astype(np.uint8)
g = g.clip(0,255).astype(np.uint8)
b = b.clip(0,255).astype(np.uint8)
img_desat = cv2.merge([b,g,r])
# save result
cv2.imwrite('barn_desat_0p5.jpg', img_desat)
#cv2.imwrite('barn_desat_0p25.jpg', img_desat)
#cv2.imwrite('barn_desat_0.jpg', img_desat)
cv2.imshow('img', img)
cv2.imshow('img_desat', img_desat)
cv2.waitKey(0)
cv2.destroyAllWindows()
去飽和度到 50%:
去飽和度到 25%:
去飽和到 0:
在 Python OpenCV 中去飽和顏色(綠色)的正確方法是在 HSV 顏色空間中工作。
輸入:
import cv2
import numpy as np
img = cv2.imread("barn.jpg")
percent = 0.5
#percent = 0.25
#percent = 0
# convert to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)
# desaturate
s_desat = cv2.multiply(s, percent).astype(np.uint8)
hsv_new = cv2.merge([h,s_desat,v])
bgr_desat = cv2.cvtColor(hsv_new, cv2.COLOR_HSV2BGR)
# create 1D LUT for green
# (120 out of 360) = (60 out of 180) +- 25
lut = np.zeros((1,256), dtype=np.uint8)
white = np.full((1,50), 255, dtype=np.uint8)
lut[0:1, 35:85] = white
print(lut.shape, lut.dtype)
# apply lut to hue channel as mask
mask = cv2.LUT(h, lut)
mask = mask.astype(np.float32) / 255
mask = cv2.merge([mask,mask,mask])
# mask bgr_desat and img
result = mask * bgr_desat + (1 - mask)*img
result = result.clip(0,255).astype(np.uint8)
# save result
cv2.imwrite('barn_desat2_0p5.jpg', result)
#cv2.imwrite('barn_desat2_0p25.jpg', result)
#cv2.imwrite('barn_desat2_0.jpg', result)
cv2.imshow('img', img)
cv2.imshow('bgr_desat', bgr_desat)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
去飽和綠色 50%:
去飽和綠色 25%:
去飽和綠色 0:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.