나는 아시아에서 태어난 황인종이다. 즉, 나의 피부를 검출하려면 황색을 검출한다고 할 수가 있다.
그렇다면 황색의 Cb, Cr 값은 얼마일까?
Cb: 77 ~ 127
Cr: 133 ~ 173
(사실 나도 떠돌아다니는 블로그에서 주워들음)
그렇다면 이 값들을 이용하기 위해 해당 이미지가 담겨있는 Mat형 변수를 OpenCV에 있는 함수인 cv::cvtColor에서
YCrCb로 바꿔줘야한다.
그렇다면 이제 황인 전용 값들 만을 찾을 수 있도록 해줘야하는데 cv::inRange()함수를 사용하면 된다.
소스 코드에서 알아서 이해하자 :)
저번 소스에서 재활용한 소스 코드라서 변수가 들쑥날쑥하다.
알아서 좀 더 깔끔하게 짜도록 하자 :)
[그림 2]는 내가 따로 [그림 1]의 frame을 가져와 frame을 제외한 것들은 검은색으로 표현시킨 것이다.
깜깜한 방안에서 노트북 화면 밝기로 촬영한 것이라 조금 잡음이 심하다.
밝은 곳에서 하면 잘 될 듯 하다.
#include <iostream>
#include <opencv2\opencv.hpp>
int main()
{
cv::Mat frame, tmpImg;
cv::Mat handImg;
cv::VideoCapture video(0);
cv::namedWindow("change_image", CV_WINDOW_AUTOSIZE);
cv::namedWindow("original_image", CV_WINDOW_AUTOSIZE);
while (true)
{
video >> tmpImg;
//손 색깔을 검출하기 위해서 YCbCr 컬러 모델 사용. 잡음에 강하다고..
//Y는 휘도 성분, Cb, Cr은 색차 성분
//피부색이 가지는 Cb,Cr의 영역은
//Cb: 77 ~ 127
//Cr: 133 ~ 173
cv::cvtColor(tmpImg, frame, CV_BGR2YCrCb);
cv::inRange(frame, cv::Scalar(0, 133, 77), cv::Scalar(255, 173, 127), frame);
handImg = (frame.size(), CV_8UC3, cv::Scalar(0));
cv::add(tmpImg, cv::Scalar(0), handImg, frame);
cv::imshow("change_image", frame);
cv::imshow("original_image", handImg);
if (cv::waitKey(27) == 27) {
break;
}
}
video.release();
tmpImg.release();
frame.release();
handImg.release();
cv::destroyAllWindows();
return 0;
}
[그림 1: 피부 검출]
[그림 2: 피부만 검출]
반응형