2017-11-08 1 views
1

Ich baue einen Code, um Haut von Webcam-Video adaptiv zu erkennen. Ich habe es fast funktioniert, aber bei der Ausgabe des Videos zeigt es 9 Bildschirme der "Haut" -Maske statt nur einer. Es scheint, als würde ich einfach etwas Einfaches vermissen, aber ich kann es nicht herausfinden.cv2.imshow zeigt 9 Bildschirme anstelle von 1

image shown here

-Code unten:

# first let's train the data 
data, labels = ReadData() 
classifier = TrainTree(data, labels) 

# get the webcam. The input is either a video file or the camera number 
# since using laptop webcam (only 1 cam), input is 0. A 2nd cam would be input 1 
camera = cv2.VideoCapture(0) 

while True: 
    # reads in the current frame 
    # .read() returns True if frame read correctly, and False otherwise 
    ret, frame = camera.read() # frame.shape: (480,640,3) 

    if ret: 
     # reshape the frame to follow format of training data (rows*col, 3) 
     data = np.reshape(frame, (frame.shape[0] * frame.shape[1], 3)) 
     bgr = np.reshape(data, (data.shape[0], 1, 3)) 
     hsv = cv2.cvtColor(np.uint8(bgr), cv2.COLOR_BGR2HSV) 
     # once we have converted to HSV, we reshape back to original shape of (245057,3) 
     data = np.reshape(hsv, (hsv.shape[0], 3)) 
     predictedLabels = classifier.predict(data) 

     # the AND operator applies the skinMask to the image 
     # predictedLabels consists of 1 (skin) and 2 (non-skin), needs to change to 0 (non-skin) and 255 (skin) 
     predictedMask = (-(predictedLabels - 1) + 1) * 255 # predictedMask.shape: (307200,) 

     # resize to match frame shape 
     imgLabels = np.resize(predictedMask, (frame.shape[0], frame.shape[1], 3)) # imgLabels.shape: (480,640,3) 
     # masks require 1 channel, not 3, so change from BGR to GRAYSCALE 
     imgLabels = cv2.cvtColor(np.uint8(imgLabels), cv2.COLOR_BGR2GRAY) # imgLabels.shape: (480,640) 

     # do bitwsie AND to pull out skin pixels. All skin pixels are anded with 255 and all others are 0 
     skin = cv2.bitwise_and(frame, frame, mask=imgLabels) # skin.shape: (480,640,3) 
     # show the skin in the image along with the mask, show images side-by-side 
     # **********THE BELOW LINE OUTPUTS 9 screens of the skin mask instead of just 1 **************** 
     cv2.imshow("images", np.hstack([frame, skin])) 

     # if the 'q' key is pressed, stop the loop 
     if cv2.waitKey(1) & 0xFF == ord("q"): 
      break 
    else: 
     break 

# release the video capture 
camera.release() 
cv2.destroyAllWindows() 
+0

warum nicht die Form des Ergebnisses drucken? – Silencer

+0

Ich habe meinen Code bearbeitet, um die Form jeder Variablen hinzuzufügen (siehe oben). Die vorhergesagteMask ist 307200 (was Zeilen * Spalten sind) und die ImgLabels, nachdem die Größenänderung größer als 307200 ist, wird sie (480,640,3). Vielleicht verursacht das den Fehler? Der Farbkanal von 3 wird jedoch benötigt, um die imgLabels in den cvtColor BGR zu GRAY einzugeben. Ich habe versucht, die Größe zu ändern, um imgLabels als (480,640,1) auszugeben, und dann die Umwandlung in GRAY auskommentieren, aber dann am Ende mit diesem Fehler: "Fehler: (-215) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize (* psrc1) in der Funktion cv :: binary_op "Jede Hilfe ist willkommen! – Rachel

+0

Ich weiß nicht, was den Klassifikator zu füttern. Aber ich denke, die Methode, die Sie ConvertColor tun, ist falsch. Und das Programm ist nicht vollständig, also kann ich es nicht debuggen. – Silencer

Antwort

0

Sie arbeiten mit Bitmaps. Um eine Idee zu bekommen, was sie halten, cv2.imshow sie einzeln. Dann werden Sie (wörtlich) sehen, wo die Daten falsch laufen.


Nun ist der Täter höchstwahrscheinlich np.resize():

np.resize(a, new_shape)

Return a new array with the specified shape.

If the new array is larger than the original array, then the new array is filled with repeated copies of a. Note that this behavior is different from a.resize(new_shape) which fills with zeros instead of repeated copies of a .


Um Skala eine Bitmap (= Größe ändern, während bestrebt, das gleiche visuelle Bild zu erhalten), verwenden cv2.resize() gemäß OpenCV: Geometric Transformations of Images .

+0

Ich sehe jedoch, dass ich die Größe ändern muss, um die vorhergesagteMask in ein Array zu formen, das von der cvtColor-Konvertierung in Graustufen ausgenommen ist. Ich bin mir nicht sicher, wie ich die Größe ändern kann, um dieses Problem zu lösen. – Rachel

+0

@Rachel hast du den letzten Absatz gelesen? Vielleicht war die Formulierung unklar. –

+0

Ah ich sehe, ich habe den letzten Teil falsch gelesen. Meine nächste Frage ist, dass cv2.resize die Größe eines 1D zu einem 2D Array ändern kann, was mir ein Array (Zeilen, Spalten) gibt. Allerdings, für cvtColor-Konvertierung in Graustufen, muss ich den Farbkanal hinzufügen (Zeilen, Spalten, 3), und ich sehe keine Möglichkeit, dies mit cv2.resize ... – Rachel

Verwandte Themen