2017-11-08 22 views
1

ウェブカメラビデオから肌を適応的に検出するコードを構築しています。私はそれがほとんど働いている、しかし、ビデオを出力するとき、それはただ1つではなく "スキン"マスクの9画面を示します。私は単純なものを見逃しているようですが、私はそれを理解できません。cv2.imshowは1の代わりに9つの画面を表示します。

image shown here

以下のコード:

# 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

結果の形状を印刷しないのはなぜですか? – Silencer

+0

各変数の形状を追加するコードを編集しました(上記参照)。 predictMaskは307200(行* cols)で、サイズ変更後のimgLabelsは307200より大きい場合、(480,640,3)になります。多分、これはエラーを引き起こしていますか?ただし、imgLabelsをcvtColor BGRからGRAYに入力するには、3のカラーチャネルが必要です。 imgLabelsを(480,640,1)として出力するようにresizeを変更しようとしましたが、GRAYへの変換をコメントアウトしましたが、このエラーで終了します: "エラー:(-215)(mtype == CV_8U || mtype == CV_8S )&& _mask.sameSize(* psrc1)in function cv :: binary_op "何か助けてください! – Rachel

+0

私は分類器に何を供給するのか分かりません。しかし、あなたはconvertColorメソッドが間違っていると思います。そして、プログラムは完全ではないので、私はそれをデバッグすることはできません。 – Silencer

答えて

0

あなたはビットマップで作業しています。彼らが何を保持しているかを知るには、cv2.imshowを個別に入手してください。次に、データがどこに間違っているかを(文字通り)見てみましょう。


今、犯人はおそらく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 .


スケールビットマップ(=同じ視覚画像を保存するために努力しながらリサイズ)、OpenCV: Geometric Transformations of Imagesに従ってcv2.resize()を使用に。

+0

しかし、予測されたマスクを、グレースケールへのcvtColor変換によって除外された配列に整形するには、resizeが必要です。私はこの問題を解決するためにサイズ変更ラインを変更する方法についてはわかりません。 – Rachel

+0

@Rachel最後の段落を読んだか?おそらく処方が不明であったでしょう。 –

+0

ああ、私は最後の部分を誤解しています。ですから、私の次の質問は、cv2.resizeが1Dを2次元配列にサイズ変更して(行、列)配列を与えることができるということです。しかし、cvtColorをグレースケールに変換するには、(行、列、3)を得るためにカラーチャネルを追加する必要があります。そして、私はcv2.resizeでこれを行う方法を見ていません... – Rachel

関連する問題