Bootstrap

徘徊检测,c++判断点是否在区域内

参考: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);
						 }
;