簡體   English   中英

如何在 Python 中使用 OpenCV2 去飽和圖像中的一種顏色?

[英]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 顏色空間中工作。

  • 讀取輸入
  • 轉換為 HSV 和單獨的通道
  • 去飽和 S 通道
  • 與原始 H 和 V 通道合並
  • 轉換回 BGR
  • 創建一個一維 LUT 圖像,除了白色的綠色外,其他地方都是黑色的
  • 將 LUT 應用到 H 通道並保存為 0 到 1 范圍內的蒙版
  • 創建一個混合圖像,即蒙版為白色(對應於綠色)的去飽和圖像和蒙版為黑色(綠色除外)的原始圖像
  • 保存為結果

輸入:

在此處輸入圖片說明

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM