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년 자료이니 그대로 배끼기보단 응용 시에 참고가 되길 바랍니다
#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 |