web-dev-qa-db-fra.com

pourquoi cv2.imwrite () change la couleur des photos?

J'ai le morceau de code suivant:

imgs = glob.glob('/home/chipin/heart/tray.png')
current_img = io.imread(imgs[0])
cv2.imwrite('/home/chipin/heart/01.png', current_img[0:511,0:511])  

La taille de l'image est de 512 * 512, après avoir été enregistrée, une image bleue devient jaune. Il semble qu'un canal soit abandonné. Je ne sais vraiment pas pourquoi.

Voici la valeur de current_img:

value of current_img

19
StalkerMuse

Votre problème vient du fait que skimage.io.imread charge l'image en RGB (ou RGBA), mais OpenCV suppose que l'image est BGR ou BGRA (BGR est le format de couleur OpenCV par défaut). Cela signifie que les avions bleu et rouge sont inversés.


Images 3 canaux

Essayons cela avec l'image de test simple suivante:

Input image


Essayons d'abord votre algorithme d'origine:

import skimage.io
import cv2

img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_1.png', img)

On obtient le résultat suivant:

Result 1

Comme vous pouvez le voir, les canaux rouges et bleus sont visiblement échangés.


La première approche, en supposant que vous souhaitez toujours utiliser skimage pour lire et cv2 pour écrire, consiste à utiliser cv2.cvtColor pour convertir de RVB à BGR.

Étant donné que les nouveaux documents OpenCV ne mentionnent pas Python, dans ce cas, vous pouvez également utiliser la référence appropriée pour 2.4.x .

import skimage.io
import cv2

img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_2.png', cv2.cvtColor(img, cv2.COLOR_RGB2BGR))    

Nous obtenons maintenant la sortie suivante:

Result 2


Une alternative est d'utiliser simplement OpenCV - utilisez cv2.imread pour charger l'image. Dans ce cas, nous travaillons uniquement avec des images BGR.

NB: Ne fournir aucun indicateur signifie cv2.IMREAD_COLOR est utilisé par défaut - c'est-à-dire que l'image est toujours chargée en tant qu'image à 3 canaux (en supprimant tous les canaux alpha potentiels).

import cv2

img = cv2.imread('sample.png')
cv2.imwrite('sample_out_3.png', img)

Result 3


Images 4 canaux

De votre capture d'écran, il apparaît que vous avez une image à 4 canaux. Cela signifierait RGBA dans skimage et BGRA dans OpenCV. Les principes seraient similaires.

  • Utilisez le code de conversion des couleurs cv2.COLOR_RGBA2BGRA
  • Ou utiliser cv2.imread avec indicateur cv2.IMREAD_UNCHANGED
47
Dan Mašek