본문 바로가기
Project

수화 인식 프로젝트 - [7일차] 5일차 + convex Defects (openCV)

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

5일차를 합치는 이유 : 

 

배경 전체를 검사하고 인식하는 방법은 비효율적이고 배경의 영역이 더 클 경우 결과가 잘 나오지 않는 문제 발생.

이를 해결하기 위해, 손을 놔둘 부분만 잘라서 검사하고자 함.

Cv2. selectROI를 이용하여 특정 영역 지정.

 

5일차랑 합친 부분에 대한 결과물 : https://youtu.be/A_2Aeo579z8

 

YouTube

 

www.youtube.com

 

현 문제점 : 손가락을 접어도 손가락으로 인식이 됨. 손의 중심을 구해야함.

이를 해결하기 위해, convex Defects를 이용하고자 함.

 

이에 대한 결과물 : 

현재 수정한 코드 :

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()

#배경 영역 잘라주기
ret, img = cap.read()
rect = cv.selectROI('Select Window', img, fromCenter = False, showCrosshair = True)
cv.destroyWindow('Select Window')

while True:
    ret,frame = cap.read()
    
    if not ret:
        print('camera_error2')
        break
        
    #배경 제거하기
    #fgmask = mog.apply(frame)
    #cv.imshow('fgmask', fgmask)
    
    #배경 영역 잘라주기
    dst = frame.copy()
    x, y, w, h = rect
    cv.rectangle(img=frame, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2)
    dst = dst[y:y+h,  x:x+w]
    
    cv.imshow("frame", frame)

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

    # 손 윤곽선 따기
    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)
    
    # 윤곽선 중에서 제일 면적이 큰 윤곽선만 그리기
    if(contours != None):
        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(dst1, [max_contour], 0, (0, 0, 255), 3)
    
    # 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(dst1, [hull], 0, (0,255,0), 2)
        
    for point in points1:
        cv.circle(dst1, tuple(point), 15, [ 0, 0, 0], -1)
        
        
    #손가락 사이 찾기
    hull = cv.convexHull(max_contour, returnPoints = False)
    defects = cv.convexityDefects(max_contour, hull)
    
    for i in range(defects.shape[0]):
        s,e,f,d = defects[i,0]
        start = tuple(max_contour[s][0])
        end = tuple(max_contour[e][0])
        far = tuple(max_contour[f][0])
        cv.circle(dst1, far, 5, [0,255,255], 10)
    
    cv.imshow("dst1", dst1)
            
    if cv.waitKey(1) & 0xff == ord('q'):
        break


cap.release()
cv.destroyAllWindows()

 

다음에 해야할 부분 :

 

1. 손의 중심 찾기

2. 접힌 손가락 감지해서 배제하기

3. AR - 허공에 손가락을 통해서 그림 그리거나 글쓰는 것에 대해 고민해보기

 

<생각한 간단 코드>

#선 그리기
    line_point = []
    
    if(len(points1) == 1):
        line_point.append(tuple(points1[0])) 
        
    for point in line_point:
        cv.circle(dst1, tuple(point), 15, [ 255, 0,255], -1)

 

 

참고 사이트 : https://www.youtube.com/watch?v=j1OlFuFbRfE

https://m.blog.naver.com/PostView.nhn?blogId=jinhuk1313&logNo=220618953390&targetKeyword=&targetRecommendationCode=1

 

[OpenCV]Finger Keyboard - 사용자 손 검출

사용자 피부색 인식 영상에서 사용자의 손을 검출하기 위해 사용자 피부색을 저장한다. 이것은 히스토그램...

blog.naver.com

https://webnautes.tistory.com/1378

 

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

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

webnautes.tistory.com

 

반응형

댓글