簡體   English   中英

為什么從RGB到HSV的顏色轉換會產生損壞的圖像?

[英]Why does the color conversion from RGB to HSV produce corrupt images?

我正在過濾掉某些顏色的圖像,但是在使用hsv / hsl顏色空間時卻陷入困境。 如果我嘗試使用cv2.Color(image, cv2.COLOR_RGB2HSV)將使用matplotlib讀取的圖像轉換為HSV cv2.Color(image, cv2.COLOR_RGB2HSV)則結果圖像會像這樣弄亂顏色: 圖片

據我了解,圖片應與原始圖片一樣顯示 圖片

這是正確的還是錯誤在於我對色彩空間的有限理解?

我也嘗試過使用opencv讀取圖像,然后將BGR轉換為HSV,這帶來了不同但仍然有缺陷的圖像。 我也使用image = (image * 255).round().astype(np.uint8)將圖像轉換為uint8,仍然無法正常工作

import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import cv2
import numpy as np
image = mpimg.imread("Screenshots/vlcsnap-2019-07-22-08h42m14s251.png")
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
hls = cv2.cvtColor(image, cv2.COLOR_RGB2HLS)
plt.figure()
plt.imshow(hls)
plt.figure()
plt.imshow(hsv)

除了im之外,在運行代碼時還得到以下警告:“將輸入數據剪切為有效范圍以顯示具有RGB數據的imshow(浮點數為[0..1],整數為[0..255])。”

通過imshow文檔

(M,N):具有標量數據的圖像。 數據使用顏色圖可視化。

(M,N,3):具有RGB值(0-1浮點或0-255整數)的圖像。

(M,N,4):具有RGBA值(0-1浮點或0-255整數)的圖像,即包括透明度。

這已經告訴您,無論您給它提供3個通道的矩陣(例如HSV),都將作為RGB圖像。 這意味着,無論H中的數字是多少,都將作為R,依此類推。 因此,色相值將是紅色,飽和度值將是綠色,色度值將是藍色。

您提到的警告引起了我的注意,我決定進行測試,因為通常不使用matplotlib加載/顯示圖像。 我注意到的第一件事是圖像使用的是float32類型,使用時從0-1開始:

image = mpimg.imread("imagePath.png")

沒關系,對於OpenCV float32映像也是如此。

現在,如果您閱讀cvtColor的文檔並檢查顏色轉換,您將看到當圖像類型為float32時,范圍是:

H :[0-360]
S :[0-1.]
V :[0-1.]

因此,這意味着圖像的第一個通道的大多數值都將高於1.,然后它將超出函數imshow(0-1)的浮動范圍,該功能將對其進行裁剪,然后為1。

如我之前所說,該圖像將被解釋為RGB。 因此,“色相”通道將是“紅色”通道,並且大多數值都是最大值,因此您的大多數圖像將變成紅色調。 綠色區域歸因於飽和度大(接近最大值)。 但是,由於它是白色的地方,我想說的是您正在顯示HLS,並且它是最大的L通道。

現在談到這個問題,您期望得到什么結果? HSV色彩空間將始終為您顯示與原始圖像完全不同的事物,一切都取決於顏色,但是細微的變化(例如或多或少的飽和度)將為您提供更綠色的圖像。

無論如何,如果您想顯示更合理的內容,請將第一個通道除以360,將其縮放為0-1。 作為其他2個頻道 但是,綠色部分不會消失,但看起來會少一些紅色。

重要的結果是,色相(H)通道是一個連續的色環,在可視化HSV轉換時應牢記。 即使當您由於不將0-360 H通道重新縮放為0.0-1.0以便使用matplotlib繪制為float32而修復裁剪時,這種阻塞也是不可避免的。

與“飽和度”(S)和“值”(V)通道的線性比例不同,H通道的最小值和最大值實際上是色環上紅色的相鄰值。 由於0到255或1.0之間的急劇過渡,實際上是原始圖像的類似紅色部分,因此在代表H的任何通道中,您通常都會看到粗糙,塊狀的區域。

您實際上尚未發布原始圖像,但是看起來像是matplotlib圖中的屏幕截圖,因此我無法完全重現您的效果。 但是,要查看效果,請僅將H通道與原始圖像一起查看,我想您會明白我的意思:

H, S, V = cv2.split(hsv)
# here's the opencv way to see it
cv2.imshow('H', H)
cv2.waitKey(0)

請注意,即使原始圖像中存在平滑的紅色變化,但非常亮和非常暗的區域彼此相鄰的塊狀過渡。

您使用的是matplotlib,它需要RGB圖像。 因此,色相顯示為紅色,飽和度顯示為綠色,值顯示為藍色。 在所有看到非紅色塊的地方,Hue都接近最小0.0;在看到正常(對於HSV)的地方,橙色/黃色/白色/等處,這是Hue接近最大1.0的地方。 由於未將0-360 H通道標准化為0.0-1.0而導致的削波加劇了問題,但在解決此問題后仍然存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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