Wie konvertiert man ein Graustufenbild in OpenCV (Python) in RGB?

72

Ich lerne Bildverarbeitung mit OpenCV für eine Echtzeitanwendung. Ich habe ein Bild mit einem Schwellenwert versehen und möchte die Konturen grün beschriften, aber sie werden nicht grün angezeigt, da mein Bild schwarzweiß ist.

Zu Beginn des Programms habe ich gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)von RGB in Graustufen konvertiert, aber um zurück zu gehen, bin ich verwirrt und die Funktion backtorgb = cv2.cvtColor(gray,cv2.CV_GRAY2RGB)gibt:

AttributeError: Das Objekt 'module' hat kein Attribut 'CV_GRAY2RGB'.

Der folgende Code scheint keine Konturen in Grün zu zeichnen. Liegt das daran, dass es sich um ein Graustufenbild handelt? Wenn ja, kann ich das Graustufenbild wieder in RGB konvertieren, um die Konturen in Grün anzuzeigen?

import numpy as np
import cv2
import time

cap = cv2.VideoCapture(0)
while(cap.isOpened()):

    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    ret, gb = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)

    gb = cv2.bitwise_not(gb)

    contour,hier = cv2.findContours(gb,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contour:
        cv2.drawContours(gb,[cnt],0,255,-1)
    gray = cv2.bitwise_not(gb)

    cv2.drawContours(gray,contour,-1,(0,255,0),3)

    cv2.imshow('test', gray)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
user391339
quelle
3
Sie könnten den ursprünglichen 'Rahmen' selbst zeichnen, anstatt ein graues Bild zu verwenden
Anoop K. Prabhu
Das habe ich letztendlich getan. Danke für den Vorschlag.
user391339

Antworten:

124

Ich bewerbe meinen Kommentar zu einer Antwort:

Der einfache Weg ist:

Sie können den ursprünglichen "Rahmen" selbst zeichnen, anstatt ein graues Bild zu verwenden.

Der harte Weg (Methode, die Sie implementieren wollten):

backtorgb = cv2.cvtColor(gray,cv2.COLOR_GRAY2RGB) ist die richtige Syntax.

Anoop K. Prabhu
quelle
3
Ich denke, das funktioniert nicht wirklich, weil Sie nicht zurück in RGB konvertieren können. Sie erhalten damit ein Array mit 3 Steckplätzen, aber die RGB-Werte entsprechen denen im Graustufenbild.
Megha
7
Ja. Das stimmt. Aber der Autor der Frage war nicht daran interessiert, die Originalfarben zu verwenden
Anoop K. Prabhu
1
Aber sehen Sie wirklich grüne Konturen, wie der Autor sehen möchte? Mein Bild erscheint auch nach der Coversion COLOR_GRAY2RGB noch grau. Ich denke, das Endergebnis wird immer noch ein graues Bild sein, obwohl Sie RGB-Kanäle definiert haben
Megha
2
Zeichnen Sie die Kontur, nachdem Sie die
Farbkonvertierung durchgeführt haben
10

Versuche dies:

import cv2
import cv

color_img = cv2.cvtColor(gray_img, cv.CV_GRAY2RGB)

Bei der Verwendung von opencv habe ich festgestellt, dass einige der Konstanten im cv2-Modul und andere im cv-Modul definiert sind.

Delicasso
quelle
1
oder cv2.cv.CV_GRAY2RGB
fast_cen
Hat bei mir nicht funktioniert. Vielleicht, weil ich OpenCV 3.6 verwende?
Mannyglover
8

Wenn Sie Ihr Bild in Graustufen konvertieren, können Sie es nicht zurückerhalten. Sie sind von drei Kanälen zu einem gewechselt. Wenn Sie versuchen, zurück zu gehen, sind alle drei Nummern gleich. Die kurze Antwort lautet also nein, Sie können nicht zurückgehen. Der Grund, warum Ihr Backtorgb diesen Fehler auslöst, ist, dass er das folgende Format haben muss:

CvtColor(input, output, CV_GRAY2BGR)

OpenCV verwendet BGR und nicht RGB. Wenn Sie also die Reihenfolge festlegen, sollte dies funktionieren, obwohl Ihr Bild immer noch grau ist.

Grromrell
quelle
das hat eigentlich nicht funktioniert. Ich habe mehrere Referenzen im Internet gesehen, die darauf hinweisen, dass das oben Genannte möglich ist, aber nicht in meinen Händen. Die automatische Vervollständigung auf meinem Pydev-Ide listet CV_BGR2GRAY auf, aber nicht GREY2BGR. verwirrt. Vielen Dank!
user391339
In der Tat ist Ihre Antwort wahr und ich stand vor dem gleichen Problem
Megha
7

Alternativ cv2.merge()kann eine einkanalige binäre Maskenebene in ein dreikanaliges Farbbild umgewandelt werden, indem dieselbe Ebene mit den blauen, grünen und roten Ebenen des neuen Bildes zusammengeführt wird. Wir übergeben eine Liste der drei Farbkanalebenen - in diesem Fall alle gleich - und die Funktion gibt ein einzelnes Bild mit diesen Farbkanälen zurück. Dies transformiert effektiv ein Graustufenbild der Form(height, width, 1) in um(height, width, 3)

Um Ihr Problem anzugehen

Ich habe ein Bild mit einem Schwellenwert versehen und möchte die Konturen grün beschriften, aber sie werden nicht grün angezeigt, da mein Bild schwarzweiß ist.

Dies liegt daran, dass Sie versuchen, drei Kanäle auf einem einzelnen Kanalbild anzuzeigen. Um dies zu beheben, können Sie einfach die drei einzelnen Kanäle zusammenführen

image = cv2.imread('image.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_three = cv2.merge([gray,gray,gray])

Beispiel

Wir erstellen ein Farbbild mit Abmessungen (200,200,3)

Geben Sie hier die Bildbeschreibung ein

image = (np.random.standard_normal([200,200,3]) * 255).astype(np.uint8)

Als nächstes konvertieren wir es in Graustufen und erstellen ein weiteres Bild cv2.merge()mit drei grauen Kanälen

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_three = cv2.merge([gray,gray,gray])

Wir zeichnen nun eine gefüllte Kontur auf das einkanalige Graustufenbild (links) mit Form (200,200,1)und das dreikanalige Graustufenbild mit Form (200,200,3)(rechts). Das linke Bild zeigt das Problem, das auftritt, wenn Sie versuchen, drei Kanäle auf einem einzelnen Kanalbild anzuzeigen. Nachdem Sie das Graustufenbild in drei Kanäle zusammengeführt haben, können Sie nun Farbe auf das Bild anwenden

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

contour = np.array([[10,10], [190, 10], [190, 80], [10, 80]])
cv2.fillPoly(gray, [contour], [36,255,12])
cv2.fillPoly(gray_three, [contour], [36,255,12])

Vollständiger Code

import cv2
import numpy as np

# Create random color image
image = (np.random.standard_normal([200,200,3]) * 255).astype(np.uint8)

# Convert to grayscale (1 channel)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Merge channels to create color image (3 channels)
gray_three = cv2.merge([gray,gray,gray])

# Fill a contour on both the single channel and three channel image
contour = np.array([[10,10], [190, 10], [190, 80], [10, 80]])
cv2.fillPoly(gray, [contour], [36,255,12])
cv2.fillPoly(gray_three, [contour], [36,255,12])

cv2.imshow('image', image)
cv2.imshow('gray', gray)
cv2.imshow('gray_three', gray_three)
cv2.waitKey()
nathancy
quelle