공학왕이될거야

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년 사용 vs 갤럭시 버즈 6개월 사용 비교

취미/후기
에어팟을 애지중지 옷도 여러벌 갈아입혀가면서 잘 써왔는데 어느 순간부터 끊김 현상이 너무 심해져서 바꿔야겠다 싶었다

노래 들을 때 아무 문제도 없는데 뚝! 끊기는 게 잦아져서...버즈는 아직까지는 그런 현상이 없다

히히 나의 두번째 무선이어폰 버즈

우선 에어팟은 딱딱해서 너무 불편했고 귀가 피로했는데 버즈는 실리콘으로 쌓여있어서 딱딱하지 않다.
그리고 에어팟은 넘 차갑다...ㅋㅋㅋ
근데 버즈는 그 대신 오래 끼면 습기가 찬다 커널형 이어폰은 다 그렇겠지만...ㅠㅠ
그래서 둘 다 오래 못 끼겠는 건 마찬가지이다.
버즈가 에어팟보다 좀 더 무거운데 이거 저거 다 따져도 그나마 버즈가 더 편한 것 같다.

장점 첫 번째는

무선충전이 되는 게 너무 편하다.
에어팟은 긴 케이블을 꺼내서 5V 1A 충전기에 꽂아서 충전하고 그런게 너무 귀찮았다ㅠㅠ.
고속충전이 안 되기 때문에 2A 고속충전기로 충전하면 오래 못 쓸 것 같아서 항상 1A 충전기로 충전했으니까...ㅠㅠ

버즈는 고속충전을 지원하고 in out이 2A여서 그냥 휴대폰 충전이 아무거나로 충전해도 된다!

근데 바닥에 내려놓는 충전기일 때가 더 편할 것 같다. 충전되는 위치가 휴대폰이랑 달라서 밑에 샤프를 놓고 올려야 충전됨.

장점 두 번째는

에어팟이랑 갤럭시 이용할 때는 호환되는 장점을 누리지 못했는데 버즈랑 갤럭시를 이용하니까 호환되는 게 너무 편하다!!
버즈 열어서 이어폰 꽂고 버즈 닫으면 블루투스가 켜있는 상태가 아니더라도 연결하겠냐고 뜸!
에어팟 쓸 때는 연결을 하려면 우선 블루투스는 내가 켜야했다 근데 버즈는 블루투스가 켜져있는 상태가 아니어도 위의 연결 화면이 뜨고 연결 누르면 블루투스 자동으로 켜지고 버즈랑 연결된다!!!
이건 정말 장점인듯

그리고 장점 세 번째는
스피커로 노래 재생 중에 이어폰이 딱 연결되면 바로 이어폰으로 노래가 재생된다
재생 멈춤 버튼 따로 안 눌러도 되고 짱 좋다

장점 네 번째는

버즈든 에어팟이든 톡톡 쳐서 음악 재생을 컨트롤 하는데 에어팟은 정말 말을 잘 안 들었음ㅡㅡ
근데 버즈는 말을 잘 듣는다
대신 너무 빠르게 치면 안되고 톡.톡. 이런 식으로 치면 말 잘 들음!!

그리고 다섯번째 장점은
방전된 충전기 안에 버즈를 3~4일 끼워놓아도 버즈 자체의 전력 소모는 거의 없다.
에어팟은 방전된 통에 넣어놓으면 에어팟도 같이 방전됐음ㅠㅠ.
근데 이거는 버즈도 1년 정도 쓰면 어떨지 모르겠당.

마지막 장점

외부 소리 듣기를 선택할 수 있는데 켜면 바깥쪽 마이크가 켜지는 것 같다 음질에는 크게 차이가 없는데 아무래도 공기소리나 움직일 때 나는 옷 소리 등이 들려서 잡음이 끼는 느낌이다 노래 소리가 클 땐 신경 하나도 안 쓰임!! 뭔가 노래 듣고 있는 척 남들 말 무시하고 싶은데 듣기는 들어야 할 때 켜면 좋다 ㅋㅋㅋ

물론 단점도 많다...

우선 첫 번째로
20평정도 되는 공간에서도 끊김 현상이 발생한다.
같은 공간에서 에어팟에서는 그런 적 없었기 때문에 더 크게 느껴졌다.
특히 한쪽만 끼고 있을 때 더 심한데 버즈끼리의 거리가 멀어지면 더 끊기는 것 같다.

그리고 두번째는

보관함 겸 충전기의 배터리 잔량을 한눈에 알 수 없다. 열었다 닫았다 할 때 불빛으로 알 수 있는데 이게 불편하다.
몇 퍼센트 남았는지 알고 싶음....

그리고 세번째로 통화중 품질이 에어팟보다 떨어지는 것 같다.

그리고 마지막으로
이어폰 모양이 둥글다보니까 귀에 꽂는 부분이 명확하지 않아서..?? 요리조리 돌려봐야 귀에 맞는다
에어팟은 방향이 명확해서 그냥 딱 꽂을 수 있었는데 버즈는 껴서 맞는 방향인지 꼭 돌려봐야한다.
내가 꼭 맞게 끼고 싶어서 그럴 수도 있는데 무선형은 아무래도 안 떨어뜨리려면 꼭 맞아야하니까...
이게 별 거 아닌 것 같아도 조금 불편하다ㅠㅠ