본문 바로가기
Project

수화 인식 프로젝트 - [6일차] 다시 정리하기 (openCV)

by 배애앰이 좋아 2020. 3. 6.
반응형

기존 코드 :

import numpy as np
import cv2
from PIL import Image

def backSubtraction():
    
    try:
        cap=cv2.VideoCapture(0)
    except:
        print('camera_errro1')
        return
    
    while True:
        ret, frame = cap.read()
        cv2.imshow("VideoFrame", frame)
        if not ret:
            print('camera_error2')
            break
            
        dst = frame.copy()
        test = cv2.cvtColor(frame, cv2.COLOR_BGR2YCrCb)
        mask_hand = cv2.inRange(test, np.array([0,133,77]),np.array([255,173,127]))
        median2 = cv2.medianBlur(mask_hand, 9) #이미지 블러 처리
        median = cv2.medianBlur(median2, 9) #이미지 블러 처리
        kernel = np.ones((6, 6), np.uint8)
        
        contours, hierachy=cv2.findContours(median, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
        
        points1 = []
        result_cx = []
        result_cy = []
        
        for i in contours:
            M = cv2.moments(i)
            if M["m00"] != 0:
                cx = int(M["m10"] / M["m00"])
                cy = int(M["m01"] / M["m00"])
            else:
                cX, cY = 0, 0
                
        for cnt in contours:
            cv2.drawContours(dst, [cnt], 0, (255, 0, 0), 3)
            approx = cv2.approxPolyDP(cnt,0.02*cv2.arcLength(cnt,True),True)
            hull = cv2.convexHull(approx)
            for point in hull:
                if cy > point[0][1]:
                      points1.append(tuple(point[0])) 
            cv2.drawContours(dst, [hull], 0, (0,0,255),2)
            
        for point in points1:
            #print(point[0])
            if point[0] != 0 and point[1] != 0:
                cv2.circle(dst, tuple(point), 15, [255, 0, 0], -1)
            
        cv2.imshow('dst', dst)
        #cv2.imshow('new_img', new_img)
        #cv2.imshow('fgmask', fgmask)
        #cv2.imshow('median', median) 
        #cv2.imshow('mask_hand', mask_hand) 
        #cv2.imshow('dilation ', dilation ) 

        if cv2.waitKey(10) & 0xff == ord('q'):
            break
            
    capture.release()
    cv2.destroyAllWindows()
    
backSubtraction()

새롭게 작성한 코드 : 

import cv2 as cv
import numpy as np
from PIL import Image
import os
import time

try:
    cap = cv.VideoCapture(0)
except:
    print('camera_errro1')
    
#배경 제거하기
mog = cv.bgsegm.createBackgroundSubtractorMOG()

while True:
    ret,frame = cap.read()
    
    if not ret:
        print('camera_error2')
        break
        
    #배경 제거하기
    fgmask = mog.apply(frame)
    cv.imshow('fgmask', fgmask)

    # 사진 살색 검출 흑백 처리
    dst = frame.copy()
    test = cv.cvtColor(frame, cv.COLOR_BGR2YCrCb)
    mask_hand = cv.inRange(test, np.array([0,133,77]),np.array([255,173,127])) #살색 범위
    median = cv.medianBlur(mask_hand, 9) #이미지 블러 처리

    # 손 윤곽선 따기
    contours, hierarchy = cv.findContours(median, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    
    for cnt in contours:
        cv.drawContours(dst, [cnt], 0, (255, 0, 0), 3)
    
    cv.imshow("dst", dst)
    
    # 윤곽선 중에서 제일 면적이 큰 윤곽선만 그리기
    max_contour = None
    max_area = -1

    for contour in contours:
        area = cv.contourArea(contour) #컨투어의 면적은 모멘트의 m00 값이고, cv2.contourArea() 함수로도 구할 수 있다.
        x,y,w,h = cv.boundingRect(contour) #컨투어를 둘러싸는 박스는 boundingRect 함수
        
        if (w*h)*0.4 > area:
            continue

        if w > h:
            continue

        if area > max_area:
            max_area = area
            max_contour = contour
            
    if max_area < 10000:
        max_area = -1
        
    cv.drawContours(frame, [max_contour], 0, (0, 0, 255), 3)
    cv.imshow("frame", frame)
    
    # convex hull 그리기
    points1 = []

    M = cv.moments(max_contour)
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])


    max_contour = cv.approxPolyDP(max_contour,0.02*cv.arcLength(max_contour,True),True)
    hull = cv.convexHull(max_contour)

    for point in hull:
        if cy > point[0][1]:
            points1.append(tuple(point[0])) 

    cv.drawContours(frame, [hull], 0, (0,255,0), 2)
    for point in points1:
        cv.circle(frame, tuple(point), 15, [ 0, 0, 0], -1)
            
    if cv.waitKey(1) & 0xff == ord('q'):
        break


cap.release()
cv.destroyAllWindows()

convex hull 그리는 부분에서 고민 중(기존 방법이 나을지, 새로운 방법이 나은지)

 

다음에 할 부분 : 5일차 웹캠 부분 자르는 코드 + 현재 코드 합쳐서 효율적인 인식 모델 만들기

 

참고한 사이트 : https://webnautes.tistory.com/1378

 

OpenCV를 사용하여 손 검출 및 인식하기(Hand Detection and Recognition using OpenCV)

OpenCV를 사용하여 손을 검출 및 인식하는 방법에 대해 다룹니다. 현재 두가지 방법으로 코드가 작성되었습니다. Background Subtraction을 사용한 방법과 HSV 공간에서 살색을 검출한 방법입니다. Background Sub..

webnautes.tistory.com

https://3months.tistory.com/154

 

머신러닝 - 수식 없이 이해하는 Gaussian Mixture Model (GMM)

수식없이 이해하는 Gaussian Mixture Model /* 2017.8.4 by. 3개월 */ 개요 머신러닝에서 자주 사용되는 Gaussian Mixture Model(GMM)을 알아보겠습니다. GMM은 머신러닝에서 Unsupervised Learning(클러스터링)에..

3months.tistory.com

 

반응형

댓글