본문 바로가기

메이커 프로젝트/아두이노 +

젯슨나노 웹캠 이미지 받아오기

1. 웹캠 이미지를 받아오자.

### 웹캠.py

import cv2
print(cv2.__version__)

프레임너비 = 640
프레임높이 = 480

캡쳐 = cv2.VideoCapture(0)

while True :
    성공확인, 이미지 = 캡쳐.read()
    이미지 = cv2.resize(이미지, (프레임너비, 프레임높이))
    cv2.imshow(" 결과 ", 이미지)
    if cv2.waitKey(1) == ord('q') :
        break

- 실행화면

 

 

2.  웹캠에서 얼굴인식을 해보자!!

 

- 카메라 인식 모델을 받아오자. 여기서 이후 코드에 쓰일 xml 파일을 받아와야 한다.

https://github.com/opencv/opencv/tree/master/data/haarcascades

 

GitHub - opencv/opencv: Open Source Computer Vision Library

Open Source Computer Vision Library. Contribute to opencv/opencv development by creating an account on GitHub.

github.com

여기서 잠깐! xml 파일이란?

https://ko.omatomeloanhikaku.com/what-is-an-xml-file-and-how-do-i-open-one-12886

 

### 얼굴인식.py

import cv2
print(cv2.__version__)

def 얼굴찾기(웹캠화면, 검출분류기, 이미지스케일, 최대검출갯수) :
    
    웹캠복사 = 웹캠화면.copy()
    흑백이미지 = cv2.cvtColor(웹캠복사, cv2.COLOR_BGR2GRAY)
    검출된얼굴들 = 검출분류기.detectMultiScale(흑백이미지, 이미지스케일, 최대검출갯수) #검출된 얼굴들 -> (x, y, w, h) 값으로 출력
    얼굴출력 = []
    
    선두께 = 2
    선색깔 = (255, 0, 255)
    for (x,y,w,h) in 검출된얼굴들 :
        cv2.rectangle(웹캠복사, (x, y), (x+w, y+h), 선색깔, 선두께)
        얼굴출력.append([[x,y,w,h], w*h])

    얼굴출력 = sorted(얼굴출력, key = lambda x:x[1], reverse = True)
    
    return 웹캠복사, 얼굴출력


def main():
    프레임너비 = 640
    프레임높이 = 480
    검출분류기 = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    캡쳐 = cv2.VideoCapture(0)

    while True :
        _, 웹캠화면 = 캡쳐.read()
        웹캠화면 = cv2.resize(웹캠화면, (프레임너비, 프레임높이))    
        웹캠복사, 얼굴출력 = 얼굴찾기(웹캠화면, 검출분류기, 1.1, 4)

        cv2.imshow("결과창", 웹캠복사)   
        if cv2.waitKey(1) == ord('q') : 
            break


if __name__ == "__main__" :
    main()

- 동작 화면

 

 

3. 얼굴 트래킹

### 얼굴트랙킹.py

import 얼굴인식
import time
import cv2
import numpy as np

perrorLR, perrorUD = 0, 0
cnt = 0

def 중앙찾기(웹캠복사, 얼굴출력):
    엑스중앙좌표, 와이중앙좌표 = -1, -1
    선두께 = 2
    선색깔 = (0, 255, 0)

    if len(얼굴출력) != 0:
        x, y, w, h = 얼굴출력[0][0]
        엑스중앙좌표 = x + w//2
        와이중앙좌표 = y + h//2
        cv2.circle(웹캠복사, (엑스중앙좌표, 와이중앙좌표), 선두께, 선색깔, cv2.FILLED)

        프레임높이, 프레임너비, 컬러가지수 = 웹캠복사.shape   # print(웹캠복사.shape) -> (480, 640, 3)

        cv2.line(웹캠복사, (프레임너비//2, 와이중앙좌표), (엑스중앙좌표, 와이중앙좌표), 선색깔, 선두께//2)
        cv2.line(웹캠복사, (엑스중앙좌표, 프레임높이//2), (엑스중앙좌표, 와이중앙좌표), 선색깔, 선두께//2)


    return 엑스중앙좌표, 와이중앙좌표, 웹캠복사


def 얼굴추적(엑스중앙좌표, 와이중앙좌표, 너비, 높이) :

    global perrorLR, perrorUD, cnt

    KLR = [0.6, 0.1]
    KUD = [0.6, 0.1]

    
    if 엑스중앙좌표 != -1:
        # 좌우 편차 계산
        errorLR = 너비//2 - 엑스중앙좌표
        posX = KLR[0] * errorLR +KLR[1] * (errorLR-perrorLR)
        posX = int(np.interp(posX, [-너비//2, 너비//2], [20, 160]))
        perrorLR = errorLR
        

        # 위아래 편차 계산
        errorUD = 높이//2 - 와이중앙좌표
        posY = KUD[0] * errorUD +KUD[1] * (errorUD-perrorUD)
        posY = int(np.interp(posY, [-너비//2, 너비//2], [20, 160]))
        perrorUD = errorUD
        

        # 서보모터 X,Y 각도 확인 -> 정 가운데 -> X, Y = 90, 90
        if cnt == 10 : 
            print("y값 : ", posY)
            print("x값 : ", posX)
            cnt = 0
        else : 
            cnt+=1



def main():
    프레임너비 = 640
    프레임높이 = 480
    검출분류기 = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    캡쳐 = cv2.VideoCapture(0)

    while True :
        _, 웹캠화면 = 캡쳐.read()
        웹캠화면 = cv2.resize(웹캠화면, (프레임너비, 프레임높이))    
        웹캠복사, 얼굴출력 = 얼굴인식.얼굴찾기(웹캠화면, 검출분류기, 1.1, 4)

        엑스중앙좌표, 엑스와이좌표, 웹캠복사 = 중앙찾기(웹캠복사, 얼굴출력)

        얼굴추적(엑스중앙좌표, 엑스와이좌표, 프레임너비, 프레임높이)
        

        cv2.line(웹캠복사, (0, 프레임높이//2), (프레임너비, 프레임높이//2), (0, 0, 255), 2)
        cv2.line(웹캠복사, (프레임너비//2, 0), (프레임너비//2, 프레임높이), (0, 0, 255), 2)

        cv2.imshow("결과창", 웹캠복사)   
        if cv2.waitKey(1) == ord('q') : 
            break

if __name__ == "__main__" :
    main()