프로젝트

나도 메이커! 메이커스 여러분들의 작품/프로젝트를 공유하는 공간입니다.

얼굴 추적 카메라

2014-08-25 13:20:41

개요

개요

웹캠으로 얼굴을 인식하여 얼굴을 따라다니는 카메라를 구현해보자.
이 프로젝트를 진행하기 위해서 필요한 환경설정으로 OpenCV와 Processing이 필요하다. 
OpenCV는 컴퓨터상에서 프로세싱이 얼굴을 인식할때 필요한 대표적인 라이브러리이며 프로세싱뿐만 아니라 C나 Java에서도 쓰인다.
이번 프로젝트에서는 프로세싱이 아두이노와 호환성이 좋으며 개발하기 쉬운 언어이기 때문에 OpenCV를 사용하기 위한 개발툴로 쓰였다.
물론 굳이 프로세싱이 아니더라도 다른 언어로도 아두이노와 시리얼통신이 가능하며 OpenCV라이브러리를 사용할 수 있다면 얼마든지 개발 가능하다. 

기본적으로 영상처리쪽은 사람얼굴이 셀 수 없이 다양하여, 제대로 인식하여 자료로 사용하기 위해서는 다양한 표본의 데이터베이스가 필요하고, 빛의 반사, 위치, 주위 환경에 따라 똑같은 사물이라도 다양한 모습으로 비춰질 수 있어 결과값에 대한 불확실성이 매우 크기 때문에 상당히 어려운 분야에 속한다.




하지만 이 프로젝트에 사용하는 얼굴인식의 경우에는 OpenCV안에 기본 예제소스로 주어져 있기 때문에 예제소스를 프로세싱내에서 구동할 수 있게 환경설정을 해줄 수만 있다면 어렵지는 않게 구현이 가능한 프로젝트이다. 예제소스로 주어져 있는 만큼 정밀한 인식은 어렵고 얼굴인식에 대한 소스코드 수정이 OpenCV에 대한 전문적인 지식이 없는 한 거의 불가능하다. 그래도 정면으로 카메라를 바라본다면 대부분의 얼굴은 인식할만큼 괜찮은 성능을 나타낸다.

얼굴인식카메라는 주위 환경에서 CCTV분야에 많이 쓰이며 최근에는 웹캠도 개발되었다. 최근에는 얼굴뿐만 아니라 소리에 따라 소리를 추적하는 카메라까지 개발되고 있다.




아두이노 서보모터를 활용하여 카메라를 얼굴추적카메라를 만들어서 사용하면 응용하여 얼굴을 추적하여 자동으로 캡쳐해주는 카메라나 CCTV의 구현이 가능하다. 어려우면서도 쉬운 얼굴추적카메라를 만들어 보자.

동영상



필요한 사전지식

서보 모터
시리얼 통신
프로세싱
OpenCV

부품 목록

NO 부품명 수량 상세정보
1 아두이노 보드 1 UNO, Mega2560, MegaADK
2 브레드 보드 1  
3 서보 모터 2  
4 웹캠 1  
5 케이블 6~10  



부품명 아두이노 보드 브레드 보드 서보 모터 2개 웹캠 케이블
부품 사진


※서보 모터 선택 사항

위 프로젝트를 진행할 때에는 서보 모터 하나는 수직으로 움직이고 다른 하나는 수평으로만 움직이게 하여 상하좌우를 움직일 수 있게 한다. 이때 서보 모터2개를 조합해서 만들어야 하는데 이때 서보모터를 브라켓이 달린것으로 구매하면 좀 더 수월하게 작업 할 수 있다.

하드웨어 making

브레드보드


전자회로도



소프트웨어 coding

이번 프로젝트는 코딩을 하기전에 환경설정이 복잡하지만 많이 필요하다.
일단 프로세싱이 있어야 하고 OpenCV라는 것을 받아서 설치해 주어야 한다.

프로세싱 설치하기  <- 링크

OpenCV에는 다양한 버전이 있지만 여기에서는 프로세싱과 사용할 것이기 때문에, 프로세싱과 관련된 OpenCV를 받아야 한다.

OpenCV받기 <- 링크

설치를 하다가 이런창이 뜨게 되면 체크박스에 체크하고 설치를 계속해 준다. 
(체크를 안 할 경우나 나중에 제대로 실행이 안 될 경우에는 다음과 같은 방법을 실행한다.
컴퓨터-속성-고급 시스템 설정-고급-환경변수에서 시스템변수 Path에 편집버튼을 눌러 OpenCV가 설치된 공간의 디렉토리 주소를 입력한다.
ex) OpenCV가 Program Files에 설치됐을 경우 -> C:\Program Files\OpenCV\bin;    
bin폴더까지 입력해 주어야 한다. Path에서 디렉토리 구분은 ;세미콜론으로 한다)




OpenCV가 설치되었으면 재부팅을 하고 이제는 OpenCV라이브러리를 받아야 한다.

OpenCV라이브러리 <- 내려받기 링크 
OpenCV라이브러리를 내려받았으면 프로세싱2가 설치된 위치\modes\java\libraries\  에 OpenCV라이브러리폴더를 옮긴다.

OpenCV라이브러리 예제 안에도 FaceDetection이 있지만 아마 제대로 실행되지 않을 것이다.
FaceDetection예제를 실행하기 위해서는 GSvideo라는 라이브러리가 필요하다.

GSVideo라이브러리 <- 내려받기 링크

GSVideo라이브러리를 내려받았으면 아래 위치에 붙여넣기 한다. (이 프로젝트는 프로세싱2, Win7 32bit를 기준으로 한다.)
프로세싱2가 설치된 위치\modes\java\libraries\  에 GSVideo를 넣으면 라이브러리 설치도 완료된다. 




라이브러리가 제대로 설치됐는지 알아보기 위해 프로세싱을 켜고 예제를 실행해 보자.


예제소스에 GSVideo가 보이면 일단 라이브러리설치는 성공적으로 완료된 것이다.
웹캠이나 노트북안에 내장캠이 존재한다면 GSVideo안의 FaceDetection을 불러서 실행해보자.




불러서 실행시키면 haarcascade_frontalface_alt.xml이 없다는 메시지가 뜰지도 모른다. 
위와 같은 오류 메시지가 뜨게 되면 OpenCV가 설치된 위치에서 data\haarcascades안에 있는 그 파일을 가져와서 
ex) C:\Program Files\OpenCV\data\haarcascades

예제소스가 존재하는 디렉토리안의 data폴더에 붙여넣기 하면 오류는 뜨지 않고 제대로 실행 될 것이다.
ex) C:\Users\유저이름\Desktop\processing-2.2.1\modes\java\libraries\GSVideo\examples\OpenCV\FaceDetection\data

실행시켰을때 제대로 얼굴을 인식하고 얼굴을 빨간색 사각형으로 인식한다면 환경설정은 끝난것이다.



프로세싱 코드

import processing.serial.*;

// Combining GSVideo capture with the OpenCV library for face detection
// http://ubaa.net/shared/processing/opencv/
import hypermedia.video.*;
import java.awt.Rectangle;
import codeanticode.gsvideo.*;

OpenCV opencv;
GSCapture cam;

// 대비, 밝기 조절 변수
int contrast_value    = 0;
int brightness_value  = 0;

//수직, 수평으로 움직이는 서보모터를 구별하기 위한 변수 char verticalSignal = 0; char horizonSignal = 1;
//서보모터 각도의 초기값 지정 char servoHPosition = 90; char servoVPosition = 90; //얼굴 중앙값 초기화 int midFaceY=0; int midFaceX=0;
//화면의 중심좌표값 지정 int midScreenY = (480/2); int midScreenX = (640/2); int midScreenWindow = 10; //화면 중앙에서 어느정도 위치안에 얼굴의 중앙위치점가 들어올 경우
//스크린에서 중앙으로 들어왔다고 인식할 것인지 오차범위 지정 int stepSize=1; //모터 이동값 지정 Serial port; void setup() { size(640, 480); cam = new GSCapture(this, 640, 480); cam.start(); //OpenCV사용 초기화 opencv = new OpenCV(this); opencv.allocate(640,480); // "haarcascade_frontalface_alt.xml"을 불러와서 얼굴의 앞을 인식한다 opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT ); println(Serial.list()); println(midScreenX); println(midScreenY);
//시리얼통신을 위한 포트 생성 port = new Serial(this, Serial.list()[0], 57600); //메시지 프린트 println("Drag mouse on X-axis inside this sketch window to change contrast"); println("Drag mouse on Y-axis inside this sketch window to change brightness");
//서보모터 초기각도 전송 port.write(horizonSignal); port.write(servoHPosition); port.write(verticalSignal); port.write(servoVPosition); } void captureEvent(GSCapture c) { c.read(); } public void stop() { opencv.stop(); super.stop(); } void draw() { opencv.copy(cam); opencv.convert(GRAY); opencv.contrast(contrast_value); opencv.brightness(brightness_value); //OpenCV라이브러리를 이용하여 사람의 얼굴 앞면을 인식한다. Rectangle[] faces = opencv.detect(1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40); //캠에서 인식하는 이미지를 화면에 출력하여 영상으로 만든다 image(cam, 0, 0); //인식한 얼굴의 테두리에 사각형을 그린다. noFill(); stroke(0, 255, 0); strokeWeight(5); for(int i = 0; i < faces.length; i++) { rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); }
//얼굴의 길이가 0보다 클 경우(사람의 얼굴을 인식하고 있을 경우) if(faces.length > 0){
//현재 인식하고 있는 얼굴의 중앙 점을 구하여 midFaceX와 midFaceY에 저장
midFaceX = faces[0].x + (faces[0].width/2); midFaceY = faces[0].y + (faces[0].height/2);
//현재 얼굴의 위치가 스크린의 중앙보다 아래에 위치할 경우 수직으로 움직이는 서보모터의 각도를 1도씩 감소시킨다 if(midFaceY < (midScreenY - midScreenWindow)){ if(servoVPosition >= 5) servoVPosition -= stepSize; }
//현재 얼굴의 위치가 스크린의 중앙보다 위에 위치할 경우 수직으로 움직이는 서보모터의 각도를 1도씩 증가시킨다 else if(midFaceY > (midScreenY + midScreenWindow)){ if(servoVPosition <= 175) servoVPosition +=stepSize; }
//현재 얼굴의 위치가 스크린의 중앙보다 왼쪽에 위치할 경우 수평으로 움직이는 서보모터의 각도를 1도씩 감소시킨다 if(midFaceX < (midScreenX - midScreenWindow)){ if(servoHPosition >= 5) servoHPosition -= stepSize; }
//현재 얼굴의 위치가 스크린의 중앙보다 아래에 위치할 경우 수평으로 움직이는 서보모터의 각도를 1도씩 증가시킨다 else if(midFaceX > midScreenX + midScreenWindow){ if(servoHPosition <= 175) servoHPosition +=stepSize; } }
//각자 서보모터의 각도를 시리얼통신을 통해 전송 port.write(horizonSignal); port.write(servoHPosition); port.write(verticalSignal); port.write(servoVPosition); delay(1); } //밝기 대조값 변경 void mouseDragged() { contrast_value = int(map(mouseX, 0, width, -128, 128)); brightness_value = int(map(mouseY, 0, width, -128, 128)); }

얼굴인식을 하기 위한 프로세싱코드로 OpenCV라이브러리를 통한 소스가 반정도 존재한다.

얼굴인식을 하여 서보모터를 움직이게 하기 위해서는 사실상 2개의 점만 알고 있으면 된다. 
화면중앙점의 좌표값과 현재 인식하고 있는 얼굴의 중앙좌표값을 알고 있으면 서보모터를 움직일 수 있다. 계속적으로 두점을 비교하여 서보모터에 달린 카메라를 움직여서 궁극적으로는 화면의 중앙 좌표값과 현재 얼굴의 중앙좌표값을 비스무리하게(오차범위안으로) 맞출 수만 있다면 얼굴을 추적하는 카메라를 만들 수 있다.

//수직, 수평으로 움직이는 서보모터를 구별하기 위한 변수
char verticalSignal = 0;
char horizonSignal = 1;

//서보모터 각도의 초기값 지정 char servoHPosition = 90; char servoVPosition = 90; //얼굴 중앙값 초기화 int midFaceY=0; int midFaceX=0;
//화면의 중심좌표값 지정 int midScreenY = (480/2); int midScreenX = (640/2); int midScreenWindow = 10; //화면 중앙에서 어느정도 위치안에 얼굴의 중앙위치점가 들어올 경우
//스크린에서 중앙으로 들어왔다고 인식할 것인지 오차범위 지정
서보모터를 사용하는데 아두이노 에서는 프로세싱에서 전송한 값이 서보모터 두개 중 어느 모터에 전송하는 값인지 구별할 방법이 없다. 따라서 프로세싱에서는 모터의 각도값을 전송하기 전에 어느모터에게 전송하는 것인지 일종의 시그널을 보낸다. 
0을 보내고 그 다음 오는 값은 수직으로 움직이는 모터를 움직이는 값으로 약속을 하고 
1을 보내고 그 다음 오는 값은 수평으로 움직이는 모터를 움직이는 값으로 약속을 하는 것이다. 이런 방법을 사용하면 각 모터마다 제대로 된 값을 보낼 수 가 있다. 화면의 중앙 좌표값은 스크린의 너비와 높이를 /2해 주면 중앙 좌표값을 구할 수 있다. 

 //OpenCV라이브러리를 이용하여 사람의 얼굴 앞면을 인식한다.
  Rectangle[] faces = opencv.detect(1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40);

  //캠에서 인식하는 이미지를 화면에 출력하여 영상으로 만든다
  image(cam, 0, 0);

  //인식한 얼굴의 테두리에 사각형을 그린다.
  noFill(); //채우기 없음
  stroke(0, 255, 0); //R:0, G:255, B:0 녹색의 사각형을 그린다.
  strokeWeight(5);  //사각형의 테두리는 5로 지정한다
  for(int i = 0; i < faces.length; i++) {
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); 
  }
위 소스는 사람 얼굴을 인식하고 얼굴에 사각형 테두리를 치는 부분을 나타내는 소스이다. 얼굴인식은 OpenCV에서 haar_cascades에서 담당한다.
사용자는 영상처리분야나 컴퓨터 공각이 전공이 아닌이상 라이브러리를 분석하고 자세하게 알 필요는 없다.
detect함수를 통해 얼굴을 인식하면 프로세싱 함수를 통해 사각형을 그린다.
stroke()를 통해 사각형의 색을 지정하고, strokeWeight()을 통해 사각형의 두께를 지정한다.
for문을 통하여 인식된 얼굴 좌표에서 구한 너비와 높이만큼 사각형을 그리게 된다.

if(faces.length > 0){
//현재 인식하고 있는 얼굴의 중앙 점을 구하여 midFaceX와 midFaceY에 저장
midFaceX = faces[0].x + (faces[0].width/2); midFaceY = faces[0].y + (faces[0].height/2);
//현재 얼굴의 위치가 스크린의 중앙보다 아래에 위치할 경우 수직으로 움직이는 서보모터의 각도를 1도씩 감소시킨다 if(midFaceY < (midScreenY - midScreenWindow)){ if(servoVPosition >= 5) servoVPosition -= stepSize; }
//현재 얼굴의 위치가 스크린의 중앙보다 위에 위치할 경우 수직으로 움직이는 서보모터의 각도를 1도씩 증가시킨다 else if(midFaceY > (midScreenY + midScreenWindow)){ if(servoVPosition <= 175) servoVPosition +=stepSize; }
//현재 얼굴의 위치가 스크린의 중앙보다 왼쪽에 위치할 경우 수평으로 움직이는 서보모터의 각도를 1도씩 감소시킨다 if(midFaceX < (midScreenX - midScreenWindow)){ if(servoHPosition >= 5) servoHPosition -= stepSize; }
//현재 얼굴의 위치가 스크린의 중앙보다 아래에 위치할 경우 수평으로 움직이는 서보모터의 각도를 1도씩 증가시킨다 else if(midFaceX > midScreenX + midScreenWindow){ if(servoHPosition <= 175) servoHPosition +=stepSize; } }
카메라가 얼굴을 인식하고 있을 경우 화면의 중앙좌표값과 현재 인식하고 있는 얼굴의 중앙좌표값을 비교하는데 4가지의 경우를 비교하게 된다.

얼굴이 화면의 중앙에서 아래에 위치 할 경우
얼굴이 화면의 중앙에서 위에 위치 할 경우
얼굴이 화면의 중앙에서 왼쪽에 위치 할 경우
얼굴이 화면의 중앙에서 오르녹에 위치 할 경우

각 경우에 따라 if문을 통해 서보모터의 각도를 제어하게 된다. 사실 루프 한번당 서보모터 하나만 움직이지만 루프가 빠르게 돌기 때문에 서보모터 두개가 동시에 움직이는 것처럼 보이게 된다.
서보모터는 0~180도까지 움직이게 되는데 서보모터의 안정성을 위하여 각도를 최소 5도 최대 175도로 제한하였다.
위에 4가지 경우에 따라 
예를 들어 얼굴이 화면의 중앙에서 아래에 위치 할 경우 카메라가 아래로 내려가야 얼굴이 카메라 중심으로 오는 것처럼 보이기 때문에 수직으로 움직이는 서보모터의 각도값을 설치한 방법에 따라 +나 -하여 서보모터를 아래로 내린다.
각도값의 제어는 stepSize를 통해 1도씩 제어한다. 1도씩 제어한다해도 루프가 빠르게 돌기 때문에 서보모터는 실제로 휙휙 돈다.

이 같은 방법으로 나머지 3가지 경우도 제어하여 그 값을 시리얼통신을 통해 아두이노로 전송한다. 

아두이노 코드

#include <Servo.h> //서보모터 라이브러리 사용
//수직, 수평으로 움직이는 서보모터를 구별하기 위한 변수
char verticalSignal=0, horizonSignal=1; Servo servoV, servoH; //서보모터 객체 생성 char serialChar=0; 
//서보모터의 핀번호를 설정하고, 시리얼통신을 초기화하며 모터의 초기각도를 지정한다. void setup(){ servoV.attach(9); servoH.attach(10); servoV.write(90); servoH.write(90); Serial.begin(57600); } void loop(){ while(Serial.available() <=0); //시리얼통신을 통해 데이터를 받을때까지 대기한다 serialChar = Serial.read(); //데이터를 받았을 경우 if(serialChar == verticalSignal){ //수직모터를 움직이라는 신호를 받았을 경우 while(Serial.available() <=0); //각도값을 받을 때까지 대기 servoV.write(Serial.read()); //각도값을 받았을 경우 모터를 전송받은 값만큼 움직인다 } else if(serialChar == horizonSignal){ //수평모터를 움직이라는 신호를 받았을 경우 while(Serial.available() <= 0); //각도값을 받을 때까지 대기 servoH.write(Serial.read()); //각도값을 받았을 경우 모터를 전송받은 값만큼 움직인다 } }
 
아두이노의 경우에는 프로세싱보다 소스가 간단하다. 
아두이노는 프로세싱에서 시리얼통신을 통해 전송한 값을 각 모터로 전송하는 역할을 담당한다.

void loop(){
  while(Serial.available() <=0); //시리얼통신을 통해 데이터를 받을때까지 대기한다
  serialChar = Serial.read(); //데이터를 받았을 경우
  if(serialChar == verticalSignal){  //수직모터를 움직이라는 신호를 받았을 경우
    while(Serial.available() <=0); //각도값을 받을 때까지 대기
    servoV.write(Serial.read()); //각도값을 받았을 경우 모터를 전송받은 값만큼 움직인다
  }
  else if(serialChar == horizonSignal){ //수평모터를 움직이라는 신호를 받았을 경우
    while(Serial.available() <= 0);  //각도값을 받을 때까지 대기
    servoH.write(Serial.read());  //각도값을 받았을 경우 모터를 전송받은 값만큼 움직인다
  }
}
루프에서는 시리얼통신을 통해 값이 전송될 때까지 while문을 통해 조건을 Serial.available() <=0을 주어 무한대기하게 하였다. 
값이 전송되면 그 값을 serialChar로 전송하여 어느 모터에 전송하는 값인지 일단 판별한다. 
먼저 보낸값이 0이면 수직으로 움직이는 모터를 제어하라는 명령이고 1일 경우에는 수평으로 움직이는 모터를 제어하라는 명령으로 판별한다.

0이나 1이 전송된 다음에는 선택된 모터를 움직일 각도값을 전송받는다. 
각도값을 전송받으면 그 전송한 값만큼 서보모터를 제어한다.

기술문서

  • 부품목록
  • 회로도
  • 브레드보드 레이아웃
  • 스케치

수박쨈

아두이노, 서보 모터, 시리얼 통신, OpenCV, 프로세싱
profile

파이리가 2014-11-09 22:26:19

안녕하세요. 얼굴추적을 공부하고 있는 학생인데

facedectection 을 실행하면 hypermedia가 없다고 

나오는데 어떻게 해야할지 모르겠네요 ㅜㅜ

profile

수박쨈 2014-11-10 09:35:42

프로세싱에서 제가 위에서 말한 GSVideo를 실행했을때 hypermedia가 없다고 뜨는건가요? "No library found for hypermedia.video" 이 에러가 맞는지 확인 부탁드릴게요.

profile

파이리가 2014-11-16 20:10:06

네 

 
No library found for hypermedia.video
Libraries must be installed in a folder named 'libraries' inside the 'sketchbook' folder
이렇게 나오는데 라이브러리가 폴더 안에 있어야 한다고 하는데 무슨 말인지 모르겠네요..ㅜㅜ

profile

수박쨈 2014-11-17 08:52:27

위 글에 Processing용 OpenCV라이브러리를 추가하여 수정하였습니다. (GSvideo라이브러리 위쪽에 OpenCV라이브러리 내려받기 링크 걸어놨습니다.) Hypermedia는 OpenCV라이브러리 폴더안에 존재하는 폴더이며 현재 사용하고 계신 프로세싱내에 OpenCV라이브러리가 존재하지 않기 때문에 생긴 오류인듯 합니다. 제가 위에 올려놓은 OpenCV라이브러리 폴더안에서 src/java로 들어가시면 Hypermedia폴더와 하위 폴더내에 Video라는 폴더를 보실 수 있습니다.

profile

파이리가 2014-11-23 21:37:56

이건 해결이 되었는데
이젠 또 다른 경고 문구가 뜨네요 ㅜ
A library used by this sketch is not installed properly
이렇게 떠요. ㅜㅜ 32비트에서 실행해야 한다고 하는데 제가 윈도우 64비트를 사용하고있어서 그런건지

\processing-2.2.1-windows64\processing-2.2.1\modes\java\libraries\OpenCV\library\OpenCV.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
 
A library relies on native code that's not available.
Or only works properly when the sketch is run as a 32-bit  application.
이렇게 뜨는데 32비트 버전 프로세싱을 설치해야 하는 건가요??

profile

파이리가 2014-11-23 21:59:23

32비트로 실행하니까 이번엔 64-bit 어플리케이션을 하라고 하네요 ㅜㅜ 뭐가 문제일까요??
자꾸 질문해서 죄송합니당 ㅜㅜ

profile

rudals2204 2014-11-23 22:26:13

지금 파일실행은 성공했거든요.. 그래서 조금이나마 도움이 되었으면해서 댓글달아요..ㅎ window 64bit이시면 processing 64bit로 다운받아 보세요 다운받으시고 컴퓨터 재시작하시구요.. 그리고 실행한번해보세요 그래도안되시면 32bit로 포맷하심이..... 제 생각엔 이게 window가 32bi일때만 돌아가는거같은데... 물론 아닐수도잇지만요.. 가장 확실한방법은 window 32bit로 포맷하고 위에 나온 방법으로 설치다시하면 될겁니다 그리고 꼭!! 컴퓨터 재부팅해주세요 .. 화이팅요..

profile

수박쨈 2014-11-24 10:15:37

제가 쓰고있는 컴퓨터의 환경이 Win7 32bit라 따로 Win7 64bit 환경에 따른 실행여부를 테스트해 보지 못했습니다. 아마 Win7 64bit를 쓰고계시다면 프로세싱 32bit로 설치하여도 똑같은 결과를 보일것이라고 생각합니다. OpenCV가 C기반으로 작동되는 라이브러리이기 때문에 Java기반으로 만든 Processing에서는 실행시키기에 제약사항이 많습니다.(위의 실행시킨 OpenCV의 버전도 현재 버전과는 많이 다른 오래된 버전인 1.0입니다) 외국사이트를 찾아본 결과 Java용 OpenCV인 JavaCV를 통해 Processing에서 OpenCV를 실행시킬 수 있다고(Win7 64Bit 포함) 하는데 JavaCV안의 SampleCode에는 FaceDetection이란 예제가 빠져있는듯 합니다. 일단은 32Bit에서만 위의 코드가 구동이 되는거 같고 64bit에서의 실행여부는 찾아보고 난 뒤 실행된다면 다시 글 올리겠습니다.

profile

수박쨈 2014-11-24 11:29:47

외국사이트를 통해 Win7 64Bit컴퓨터의 Processing에 JavaCV설치를 통해 OpenCV의 구동이 되는것을 예제로 확인하였습니다. 하지만 이 JavaCV라이브러리에 영상인식방법 중 하나인 Haar_cascade가 없는지 기존 FaceDetection예제에 Import위치를 JavaCV쪽으로 바꿔서 해도 Haar_cascade를 찾을 수 없다는 메시지 때문에 결국 얼굴인식은 하지 못하였습니다. Processing보다는 많이 번거롭지만(?!) Visual Studio를 사용하여 C와 OpenCV를 통해 충분히 얼굴인식을 할 수 있습니다. (예전 기억으로는 64bit컴퓨터에서 C를 통해 얼굴인식을 해본 기억이 있습니다) 시간이 된다면 C와 OpenCV를 사용하여 이 프로젝트를 다시 작성하여 올리겠습니다.

profile

파이리가 2014-11-28 13:43:15

32bit로 해서 실행을 잘 했는데

example로 해서 face-detecting을 실행 시켰습니다.

근데여기서 캠 화면은 뜨는데 사각 틀이 만들어지지 않네요 ㅜㅜ

어떡하죠 ?


profile

수박쨈 2014-11-28 16:43:44

프로세싱에서 Rectangle을 그려주는 구문은 아래와 같습니다.

noFill(); //채우기 없음
  stroke(0, 255, 0); //R:0, G:255, B:0 녹색의 사각형을 그린다.
  strokeWeight(5);  //사각형의 테두리는 5로 지정한다
  for(int i = 0; i < faces.length; i++) {
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); 
  }

위의 구문이 존재하는한 faces[]가 존재한다면 사각형은 필연적으로 그려지게 되는데
그려지지 않는다는 것은
Rectangle[] faces = opencv.detect(1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40);
여기서 OpenCV를 통해 얼굴을 인식하지 못한다는거와 같습니다.
GSVideo안의 OpenCV폴더에서 faceDetection을 실행하신게 맞으신지 
 haarcascade_frontalface_alt.xml파일을 저장된 프로세싱 경로에 있는 data폴더안에 넣어보셨는지
openCV를 설치하셨는지 확인 부탁드릴게요.

Ractangle을 그려주는 구문이 있음에도 컴파일 에러없이 소스가 실행되어 웹캠화면이 떴다면 OpenCV쪽에서 문제가 있다는 거니 OpenCV쪽 세팅과정에서 문제를 찾을 수 있을거라고 봐요.

profile

토레형 2015-04-29 01:17:59

저도 위에분이랑 똑같은 증상이네요...........미치겠네요 캠창은 떠서 얼굴은 나오는데 인식이 안되네요....

profile

최광진 2015-05-21 04:53:45

안녕하세요 수박쨈님이 공유해 주신 프로젝트에 흥미가 있어서 따라 해 보았는데요
아직 초보자라 그런지 문제점이 많아서 질문드립니다.
현재 웹캠을 화면에 띄운 후에 사각형이 나타나지 않네요 폴더의 경로도 확인해 보고
OpenCV설치 여부도 다시 한번 확인 해 봤는데 이상이 없는거 같아요.
마지막으로 OpenCV세팅을 다시 점검하려고 하는데 구체적인 세팅 내용을 알 수 있을까요?
환경변수에서 bin폴더 까지 입력 완료 했는데 다른 세팅이 있을까요?

profile

최광진 2015-05-21 04:55:21

현재 사용 중인 컴퓨터는 64bit입니다.

profile

수박쨈 2015-05-23 02:24:45

@최광진 위의 댓글을 읽어보시면 아시겠지만 32bit에서 실행시켜보았습니다. 64bit에서 실행시켜보니 OpenCV가 1.0버전이라 그런지 프로세싱에서 faceDetection이 제대로 실행되지 않네요...
진짜 64bit컴퓨터에서 사용하고 싶으시다면 아마 VisualStudio를 설치하셔서 C를 통해 최신버전 OpenCV를 가지고 사용하셔야 할 듯 합니다.
예전에 C에서 openCV를 가지고 아두이노와 연동해 본적이 있는데 그때는 64bit였던걸로 기억합니다.

profile

수박쨈 2015-05-23 02:25:06

@토레형 역시 64bit가 아닐까하는 생각이 듭니다...........ㅜ

profile

이재광 2015-05-28 15:54:51




안녕하세요 전기과학생입니다! 위에 올려주신 아두이노 소스로 모터도 돌렸고, 또 올려주신 프로세싱코드로 얼굴 인식하는 것 까지는 했습니다. 그런데 인식되는게 옮겨갈때마다 모터가 돌아가야하는데 아무런 반응이 없네요 ㅠㅠ
뭐가 잘못된걸까요?

profile

수박쨈 2015-06-01 08:34:37

@이재광 위의 소스를 그대로 사용하셨는데 안되는건가요?
각각의 독립적인 시스템이 작동하는데 두 시스템을 연동했을때 작동하지 않는다면 커뮤니케이션에 문제가 있을 확률이 높습니다.

profile

김민구 2015-06-17 03:15:15

32비트 환경에서 64비트 환경에서 작동한다는 에러는 최초 폴더명을 영문으로 바꾸었을때 해결이 되었습니다.
영상윈도우 창에 사각형 태두리가 나타나지 않는 현상은 xml 파일을 data 파일이 아닌 그 상위 폴더 내 저장했더니 해결하였습니다.

profile

최현규 2015-06-23 17:48:17




GSVideo version: 1.0.0

[opencv fatal error] library not loaded !
THIS VERSION OF OPENCV LIBRARY REQUIRE ADDITIONAL DEPENDENCIES.
READ THE INSTALLATION INSTRUCTIONS AT http://ubaa.net/shared/processing/opencv/

Verify that the '\path\to\OpenCV\bin' exists in your system PATH and the java.library.path property is correctly.

error message: C:\Users\eric\Desktop\processing-2.2.1-windows32\processing-2.2.1\modes\java\libraries\opencv\OpenCV\library\OpenCV.dll: Can't find dependent libraries

A library relies on native code that's not available.
Or only works properly when the sketch is run as a 64-bit application.

저는 32비트 윈도우7을 사용중인데 이러한 내용이 나오네요 ;;;
opencv는 씨에 설치하여 경로성정을 했고 나머지도 전부 그대로 따라했는데 실행이 안되네요 ?ㅠㅠㅠ

profile

민병준 2015-09-05 18:26:49

질문이 있습니다. 비슷한 프로젝트를 생각중인 학생인데요.
캠을 아두이노에 연결해서 실시간으로 데이터를 컴퓨터로 전송해서 컴퓨터에서 스트리밍된 데이터로 얼굴인식을 해서 움직여 지는 정보를 받나요 아니면 캠은 pc에서 바로 연결되있고 (선만) 구성은 서보모터 위에 붙어있는건가요

profile

수박쨈 2015-09-07 13:36:08

캠은 피씨랑 연결돼 있고 컴퓨터의 설치된 OpenCV에서 얼굴 인식에 관련된 값을 계산합니다.
그 후 스크린의 중앙 좌표값과 비교하여 서보모터를 어디로 움직이라는 지시를 아두이노쪽으로 시리얼 통신을 통해 보내게 됩니다.
그러면 아두이노에서는 그 데이터를 받아 서보모터를 제어합니다.

위 프로젝트에서는 아두이노는 단지 들어오는 값에 따라 서보모터를 움직이기 위한 제어보드라고 생각하시면 됩니다.

profile

최광진 2015-10-18 16:22:35

얼굴인식 후 모터가 각도값에 따라 움직이는데
이때 모터 떨림현상이 생깁니다.
떨림현상을 제어하는 방법이 있을까요?

profile

수박쨈 2015-10-19 15:41:54

모터의 떨림 현상이 어떻게 일어나는지 모르겠네요.
애초에 서보모터는 자체적으로 떨림현상이 있기 때문에 이 떨림 현상을 말하시는 것이라면 사실 해결이 불가능한거 같습니다.
 
이게 아니라면 중앙을 잡고 있을때 흔들흔들 거리는것을 말하는 것을 같은데 그럴땐 인식할 수 있는 중앙의 범위를 늘려주시면 될거 같습니다.(중앙 범위가 좁으면 모터가 조금만 인식해도 중앙을 벗어나는 것으로 인식해 계속적으로 중앙에 들어오기 위해 움직이는 경우가 있습니다.)

profile

이세영 2015-10-19 18:28:15

잘 봤습니다.

profile

윤태웅 2015-11-20 00:57:49

예제를 돌려보면
GSVideo version: 1.0.0
Could not run the sketch (Target VM failed to initialize).
For more information, read revisions.txt and Help → Troubleshooting.
라고 뜨면서 실행화면에 아무것도 뜨지않고 응답없음이 뜹니다.
어떻게 해결방법없을까요?

profile

김수현 2016-01-26 03:36:23

와~ 신기하네요!

profile

장세현 2016-03-15 19:15:05

아. opencv는 pc에서 도는거군요.

profile

김기영 2016-03-28 21:48:56

웹캠에 있는 usb 포트를 아두이노보드에 연결할때는 어떤 방식으로 연결하나요?

profile

공민석 2016-04-25 15:15:57

잘 보고 갑니다^^

profile

김태민 2016-05-10 14:42:20

위에 윤태웅 님과 같은 오류가 뜨는데 어떻게 해야할지 모르겠습니다
도와주세요ㅠㅠ

profile

양수진 2016-07-18 21:29:36

안녕하세요! 저는 얼굴 인식뿐만 아니라 물체도 인식하고 싶은데 소스가 완전히 달라질까요?

profile

임명기 2016-09-28 19:10:12

좋은글 잘봤습니다

profile

윤동빈 2016-11-01 18:50:48

좋은 프로젝트네요ㅎ

profile

이학선 2017-01-15 13:45:24

얼굴이 화면의 정가운데 왔을때( 움직이고 있는 중의 경우포함) led를 1초 on후 off하고 싶은데
소스 코드는 어떻게하면 될까요?

profile

김영주 2017-02-10 15:30:56

물체인식도 얼굴인식처럼 xml이 있나요??