공학왕이될거야

'졸업작품'에 해당되는 글 3건

  1. face tracking 아두이노 코드 1
  2. face tracking C 코드 3
  3. Face-tracking Robot 졸업작품 18

face tracking 아두이노 코드

전공/Opencv
#include <Servo.h>
Servo myservo1;
Servo myservo2;
int pos1 =90;
int pos2 =90;
void setup(){
Serial.begin(9600);
myservo1.attach(9);
myservo2.attach(10);
}
void loop(){
if(Serial.available());
{
int a=(int)Serial.read();
if(a=='1')
{
pos1 = pos1 - 1;
pos2 = pos2 + 1;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='4')
{
pos1 = pos1;
pos2 = pos2 + 1;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='7')
{
pos1 = pos1 + 1;
pos2 = pos2 + 1;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='2')
{
pos1 = pos1 - 1;
pos2 = pos2;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='5')
{
pos1 = pos1;
pos2 = pos2;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='8')
{
pos1 = pos1 + 1;
pos2 = pos2;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='3')
{
pos1 = pos1 - 1 ;
pos2 = pos2 - 0.8;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='6')
{
pos1 = pos1;
pos2 = pos2 - 0.8;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
else if(a=='9')
{
pos1 = pos1 + 1;
pos2 = pos2 - 0.8;
myservo1.write(pos1);
myservo2.write(pos2);
Serial.println(a);
delay(10);
}
}
}

'전공 > Opencv' 카테고리의 다른 글

face tracking C 코드  (3) 2019.10.31
Face-tracking Robot 졸업작품  (18) 2018.01.29
저장된 사진 띄우기  (0) 2017.07.24
ubuntu 16.04 opencv 3.2.0 설치  (2) 2017.07.21
노트북 카메라 연동 얼굴 인식  (0) 2017.07.14

face tracking C 코드

전공/Opencv
#include "C:/Users/user/Desktop/opencv/build/include/opencv2/objdetect.hpp"
#include "C:/Users/user/Desktop/opencv/build/include/opencv2/videoio.hpp"
#include "C:/Users/user/Desktop/opencv/build/include/opencv2/highgui.hpp"
#include "C:/Users/user/Desktop/opencv/build/include/opencv2/imgproc.hpp"
#include "C:/Users/user/Desktop/opencv/build/include/opencv2/video/video.hpp"
#include "C:/Users/user/Desktop/opencv/build/include/opencv2/core/core.hpp"
#include "C:/Users/user/Desktop/opencv/build/include/opencv2/highgui/highgui.hpp"
#include <vector>
#include <iostream>
#include <stdio.h>
#include <string>
#include "serialcomm.h"
#include "Windows.h"
using namespace std;
using namespace cv;
/* Function Headers */
//void detectAndDisplay(Mat frame);
/* Global variables */
String window_name = "Capture - Face detection";
CSerialComm serialComm; //SerialComm 객체 생성
char detectStatus = '0';
char temp = '0';
int i;
/* @function main */
int main(int argc, char *argv[])
{
 cv::namedWindow("video", 1);
 cv::VideoCapture cap(0);
 if (!cap.isOpened())
 {
  std::cerr << "Could not open camera" << std::endl;
  return 0;
 }
 char buffer;
 if (!serialComm.connect("COM3")) //COM25번의 포트를 오픈한다. 실패할 경우 -1을 반환한다.
 {
  cout << "connect faliled" << endl;
  return -1;
 }
 else
  cout << "connect successed" << endl;
 const char* windowName = "Fingertip detection";
 while (true)
 {
  bool frame_valid = true;
  cv::Mat frame;
  try {
   cap >> frame;
  }
  catch (cv::Exception& e) {
   std::cerr << "Exception occurred. Ignoring frame... " << e.err << std::endl; frame_valid = false;
  }
  if (frame_valid) {
   try { // convert captured frame to gray scale & equalize
    //컬러 공간 변환 BGR->YCrCb
    //cv::Mat hsv;
    cv::Mat YCrCb;
    cvtColor(frame, YCrCb, CV_BGR2YCrCb);
    //각 채널별로 분리
    std::vector<cv::Mat> planes;
    cv::split(YCrCb, planes);
    cv::Mat mask = (128 < planes[1]) & (planes[1] < 170) & (73 < planes[2]) & (planes[2] < 158);
    erode(mask, mask, cv::Mat(3, 3, CV_8U, cv::Scalar(1)), cv::Point(-1, -1), 2);
    double radius;
    cv::Mat dst;
    distanceTransform(mask, dst, CV_DIST_L2, 5);
    //거리 변환 행렬에서 값(거리)이 가장 큰 픽셀의 좌표와, 값을 얻어온다.
    int maxIdx[2];
    minMaxIdx(dst, NULL, &radius, NULL, maxIdx, mask);
    cv::Point center = cv::Point(maxIdx[1], maxIdx[0]);
    cout << "중심점 좌표:" << center << ", 반지름:" << radius << endl;
    //손바닥 중심점 그리기
    cv::circle(frame, center, 2, cv::Scalar(0, 255, 0), -1);
    //손바닥 영역 그리기
    //cv::circle(frame, center, (int)(radius + 0.5), cv::Scalar(255, 0, 0), 2);
    //cv::imshow("windowName2", frame);
    //cv::Mat threshold_output;
    if (temp == '0') {
     //cout << "detect!!" << endl;
     if ((center.x > 0) && (center.x < 240))
     {
      
      for (int i = 0; i < 100000000; i++)
      {
      }
      if ((center.y > 0) && (center.y < 190))
      {
       serialComm.sendCommand('1');
      }
      else if ((center.y > 190) && (center.y < 310))
      {
       serialComm.sendCommand('4');
      }
      else if ((center.y > 310) && (center.y < 500))
      {
       serialComm.sendCommand('7');
      }
      
     }
     if ((center.x > 240) && (center.x < 360))
     {
      for (int i = 0; i < 100000000; i++)
      {
      }
      if ((center.y > 0) && (center.y < 190))
      {
       serialComm.sendCommand('2');
      }
      else if ((center.y > 190) && (center.y < 310))
      {
       serialComm.sendCommand('5');
      }
      else if ((center.y > 310) && (center.y < 500))
      {
       serialComm.sendCommand('8');
      }
      
     }
     if ((center.x > 360) && (center.x < 600))
     {
      for (int i = 0; i < 100000000; i++)
      {
      }
 if ((center.y > 0) && (center.y < 190))
      {
       serialComm.sendCommand('3');
      }
      else if ((center.y > 190) && (center.y < 310))
      {
       serialComm.sendCommand('6');
      }
      else if ((center.y > 310) && (center.y < 500))
      {
       serialComm.sendCommand('9');
      }
      
     }
    }
    else {
     detectStatus = '0';
     if (temp == '1') {
      //cout << "Unknown" << endl;
      serialComm.sendCommand('0');
      temp = '0';
     }
    }
    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i> hierarchy;
    cv::findContours(mask, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
    size_t largestContour = 0;
    for (size_t i = 1; i < contours.size(); i++)
    {
     if (cv::contourArea(contours[i]) > cv::contourArea(contours[largestContour]))
      largestContour = i;
    }
    cv::drawContours(frame, contours, largestContour, cv::Scalar(0, 0, 255), 1);
    // Convex hull
    if (!contours.empty())
    {
     std::vector<std::vector<cv::Point> > hull(1);
     cv::convexHull(cv::Mat(contours[largestContour]), hull[0], false);
     cv::drawContours(frame, hull, 0, cv::Scalar(0, 255, 0), 3);
    }
    cv::imshow("humancamera", mask);
    cv::imshow(windowName, frame);
   }
   catch (cv::Exception& e)
   {
    std::cerr << "Exception occurred. Ignoring frame... " << e.err << std::endl;
   }
  }
  if (cv::waitKey(30) >= 0) break;
 }
 // VideoCapture automatically deallocate camera object 
 return 0;
}

졸업 시즌마다 코드 전문을 원하시는 분들이 계셔서 올려봅니다
팀원들과 공유했던 메일에 남아있던 코드이고 다시 돌려보진 않았어요
영상처리 오픈소스 서너 개를 짜깁이 해서 완성한 코드이기 때문에 사용된 함수들을 구글링하면 더 좋은 자료들 참고하실 수 있을 거예요
2017년 자료이니 그대로 배끼기보단 응용 시에 참고가 되길 바랍니다

'전공 > Opencv' 카테고리의 다른 글

face tracking 아두이노 코드  (1) 2019.11.07
Face-tracking Robot 졸업작품  (18) 2018.01.29
저장된 사진 띄우기  (0) 2017.07.24
ubuntu 16.04 opencv 3.2.0 설치  (2) 2017.07.21
노트북 카메라 연동 얼굴 인식  (0) 2017.07.14

Face-tracking Robot 졸업작품

전공/Opencv

졸업작품으로 아두이노와 웹캠을 활용한 얼굴추적로봇을 만들었어요.

 

MCU : Arduino UNO R3

Servo motor : MG996

Web Cam : Logitec

Interface : Visual Studio C++ 와 Arduino 시리얼통신 (Baud Rate 9600)

 

Hardware : 과학상자

 

 

 

 

 

영상처리는 OpenCV 3.1.0 버전을 사용하였고,

얼굴추적방식은 처음에는 Haar-Cascade 방식을 사용하였으나 좋은 사양의 컴퓨터를 사용하지 못하다보니까 버퍼링과 딜레이 문제가 발생해서 피부색인식 방식으로 수정하였어요.

 

1. 얼굴 후보영역(mask) 검출

2. 윤곽선 얻기

3. 얼굴영역 찾기

4. 얼굴 중심점 검출

 

 

이렇게 크게 4가지 순서로 진행됩니다.

 

그 후에 웹캠에서 얼굴이 인식되면 얼굴 중심점의 좌표에 따라 9개의 영역으로 분할하여 제어기로 전송합니다.

 

제어기에서는 9개의 영역마다 지정된 제어를 반복하여 얼굴 중심점이 화면의 중앙 영역인 5번 영역으로 들어오도록 합니다.

 

 

Visual Studio C++ 코드는 다음과 같습니다.

OpenCV Library 불러오기

Webcam 불러오기

ArduinoSerial 통신

피부색 mask 따기

mask contour 따기

ConvexHull 그리기

중심점 그리기

아두이노와 통신하는 제어기 알고리즘

 

Arduino 코드는 다음과 같습니다.

 

 

마지막으로 완성된 동영상입니다.

 

 

 

 

'전공 > Opencv' 카테고리의 다른 글

face tracking 아두이노 코드  (1) 2019.11.07
face tracking C 코드  (3) 2019.10.31
저장된 사진 띄우기  (0) 2017.07.24
ubuntu 16.04 opencv 3.2.0 설치  (2) 2017.07.21
노트북 카메라 연동 얼굴 인식  (0) 2017.07.14