공학왕이될거야

'아두이노'에 해당되는 글 3건

  1. face tracking 아두이노 코드 1
  2. face tracking C 코드 3
  3. 칼만필터 - (1)

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

칼만필터 - (1)

전공/Arduino

아두이노를 이용해서 가장 손쉽게 사용해볼 수 있는 센서는 초음파센서(HC-SR04)라고 생각합니다.

 

이 센서는 초음파를 보내고 받을 때 까지의 시간을 측정합니다.

따라서 이 센서의 기본적인 반환값은 측정물체에 의해 반사된 초음파가 다시 센서까지 도달하는데 걸리는 시간이라고 할 수 있습니다.

 

​그러므로 초음파 센서를 사용하여 물체까지 거리를 구하기 위해서는 반환값을 적절히 변형해야 합니다.

 

 

데이터 시트에서 제시한 초음파의 속도는 340m/s이므로 1cm이동하는데 대략 29.4microsec가 걸린다는 것을 알 수 있습니다.

 

그러므로 초음파센서의 기본 반환 값에  2cm이동​하는데 걸리는 시간을 나누어 주면(duration/(29.4*2)) 원하는 cm단위의 물체간의 거리를 구할 수 있다.
 

그렇다면 기본적인 반환값은 아두이노의 pulseIn이라는 함수를 사용할 수 있습니다.

 

이대로 인터넷에서 쉽게 구할 수 있는 예제를 돌려서 시리얼창으로 값을 확인해보면 갑자기 값이 변할 때 튀는 값이 발생하게 됩니다.

 

그런 값들을 없애주기 위하여 여러 필터들을 사용할 수 있습니다.

 

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

칼만필터 - (3)  (0) 2017.07.04
칼만필터 - (2)  (0) 2017.07.04