2017-11-08 2 views
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보다 크면 (480640,3)가됩니다. 어쩌면 이것이 오류의 원인일까요? 그러나 imgLabels를 cvtColor BGR에 입력하기 위해서는 3의 색상 채널이 필요합니다. imgLabels 출력을 (480,640,1) 크기 조정 변경 시도하고 회색으로 변환 주석 다음이 오류가 끝납니다 : "오류 : (-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 변환에 의해 제외 된 배열로 형성하려면 크기 조정이 필요합니다. 이 문제를 해결하기 위해 크기 조정 줄을 변경하는 방법을 잘 모르겠습니다. – Rachel

+0

@Rachel 마지막 단락을 읽었습니까? 어쩌면 그 배합이 불분명했을지도 모른다. –

+0

아아, 나는 마지막 부분을 잘못 읽었다. 그래서 내 다음 질문은 cv2.resize가 1D를 2D 배열로 크기 조정하여 나에게 (행, 열) 배열을 줄 수 있다는 것입니다. 그러나 cvtColor를 회색 음영으로 변환하려면 (행, 열, 3)을 가져올 색상 채널을 추가해야하며 cv2.resize를 사용하여이 작업을 수행 할 방법이 보이지 않습니다. – Rachel

관련 문제