参考:https://www.freesion.com/article/50221187160/
方法一:用内置函数cv::pointPolygonTest
方法一:
bool pntInPolygon(const std::vector<cv::Point> &points,const cv::Point &point)
{
double value = cv::pointPolygonTest(points, point, false);
return value>0;
}
int main(int argc, char** argv) {
dlib::shape_predictor dlib_sp;
cv::CascadeClassifier casde;
try
{
casde.load("./haarcascade_frontalface_alt.xml");
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
// dlib 初始化
dlib::deserialize("face.dat") >> dlib_sp;
VideoCapture capture;
capture.open(0);
if (!capture.isOpened()) {
printf("could not load video data...\n");
return -1;
}
// UMat方式读取视频,转为灰度显示-自动启用GPU计算
// 如果显卡支持OpenCL
Mat frame, gray;
while (capture.read(frame)) {
if (frame.empty())
{
capture.set(CV_CAP_PROP_POS_FRAMES, 0);
continue;
}
cv::resize(frame, frame, cv::Size(frame.cols / 2, frame.rows / 2));
cvtColor(frame, gray, CV_RGB2GRAY);
std::vector<cv::Rect> faces;
casde.detectMultiScale(gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(200, 200));
//利用DLIB检人脸测特征点
dlib::array2d<dlib::rgb_pixel> dlib_img;
dlib::assign_image(dlib_img, dlib::cv_image<dlib::rgb_pixel>(frame));//格式转换
cv::Rect face = faces[0];
int lx = face.x;
int uy = face.y;
int rx = face.x + face.width;
int dy = face.y + face.height;
dlib::full_object_detection dlib_shape = dlib_sp(dlib_img, dlib::rectangle(lx, uy, rx, dy));
std::map<int, cv::Point> calc_points;
std::vector<cv::Point> tt_points;
std::vector<cv::Point> mm_points;
for (int i = 0; i < dlib_shape.num_parts(); i++) {
calc_points[i+1] = cv::Point(dlib_shape.part(i).x(), dlib_shape.part(i).y());
if (i < 17)
{
tt_points.push_back(cv::Point(dlib_shape.part(i).x(), dlib_shape.part(i).y()));
}
if (i >= 48)
{
mm_points.push_back(cv::Point(dlib_shape.part(i).x(), dlib_shape.part(i).y()));
}
cv::circle(frame, calc_points[i + 1], 3, cv::Scalar(0, 255, 255), -1);
}
std::clock_t s = clock();
cv::Rect face_rgb_roi = calcBindBox(tt_points);
int rgb_top = face_rgb_roi.y;
int rgb_left = face_rgb_roi.x;
int rgb_right = rgb_left+face_rgb_roi.width;
int rgb_bottom = rgb_top + face_rgb_roi.height;
for (int r = rgb_top; r < rgb_bottom; r++)
{
for (int c = rgb_left; c < rgb_right; c++)
{
if (pntInPolygon(tt_points, cv::Point(c, r)) && !pntInPolygon(mm_points,cv::Point(c,r)))
{
tmp.at<Vec3b>(cv::Point(c, r)) = Vec3b(0, 0, 255);
}
}
}
std::clock_t e = clock();
cv::imshow("ss", tmp);
cv::waitKey(1);
}
// 释放资源
capture.release();
return 0;
}
方法二:判断(0,0)与目标形成的直线,是否能与封闭区域的某一条边界线有交点,若有交点,即可判定目标在区域内。
https://blog.csdn.net/myf_666/article/details/124385438
struct Line_a {
double x1;
double y1;
double x2;
double y2;
};
// 快速排斥实验 Rapid rejection experiments
bool RapidRejExper(Line_a& l1, Line_a& l2) {
if ((l1.x1 > l1.x2 ? l1.x1 : l1.x2) < (l2.x1 < l2.x2 ? l2.x1 : l2.x2) ||
(l1.y1 > l1.y2 ? l1.y1 : l1.y2) < (l2.y1 < l2.y2 ? l2.y1 : l2.y2) ||
(l2.x1 > l2.x2 ? l2.x1 : l2.x2) < (l1.x1 < l1.x2 ? l1.x1 : l1.x2) ||
(l2.y1 > l2.y2 ? l2.y1 : l2.y2) < (l1.y1 < l1.y2 ? l1.y1 : l1.y2)) {
return false;
}
return true;
}
// 跨立实验
bool Cross(Line_a& l1, Line_a& l2) {
if ((((l1.x1 - l2.x1) * (l2.y2 - l2.y1) - (l1.y1 - l2.y1) * (l2.x2 - l2.x1)) *
((l1.x2 - l2.x1) * (l2.y2 - l2.y1) - (l1.y2 - l2.y1) * (l2.x2 - l2.x1))) > 0 ||
(((l2.x1 - l1.x1) * (l1.y2 - l1.y1) - (l2.y1 - l1.y1) * (l1.x2 - l1.x1)) *
((l2.x2 - l1.x1) * (l1.y2 - l1.y1) - (l2.y2 - l1.y1) * (l1.x2 - l1.x1))) > 0)
{
return false;
}
return true;
}
line_0.x1=0;
line_0.y1=0;
line_0.x2=track_list.track_rect.left+0.5*box.width;
line_0.y2=track_list.track_rect.bottom;
line_1.x1=500;
line_1.y1=450;
line_1.x2=1100;
line_1.y2=500;
line_2.x1=1100;
line_2.y1=500;
line_2.x2=1400;
line_2.y2=850;
line_3.x1=1400;
line_3.y1=850;
line_3.x2=700;
line_3.y2=850;
line_4.x1=700;
line_4.y1=850;
line_4.x2=500;
line_4.y2=450;
line_5.x1=0;
line_5.y1=500;
line_5.x2=700;
line_5.y2=500;
int a1=0, a2=0, a3=0, a4=0, a5=0;
if (RapidRejExper(line_0, line_1) && Cross(line_0, line_1)) {
a1=1;
}
if (RapidRejExper(line_0, line_2) && Cross(line_0, line_2)) {
a2=1;
}
if (RapidRejExper(line_0, line_3) && Cross(line_0, line_3)) {
a3=1;
}
if (RapidRejExper(line_0, line_4) && Cross(line_0, line_4)) {
a4=1;
}
if (RapidRejExper(line_0, line_5) && Cross(line_0, line_5)) {
a5=1;
}
if(a1 || a2 || a3 || a4)
{
cv::rectangle(image, cv::Point(track_list.track_rect.left, track_list.track_rect.top), cv::Point(track_list.track_rect.right, track_list.track_rect.bottom), cv::Scalar(0, 0, 255), 5);
}
else{
cv::rectangle(image, cv::Point(track_list.track_rect.left, track_list.track_rect.top), cv::Point(track_list.track_rect.right, track_list.track_rect.bottom), cv::Scalar(0, 255, 0), 5);
}