opencv实践项目-停车位检测

1. 步骤

1.1 selector选择器

  • 我们可以选择摄网络摄像头提供的第一帧,在该图像上选择停车位。为此,保存并使用该图像选择停车位。
  • 使用selectROIs函数标记停车位。ROI被定义为感兴趣的区域,代表图像的一部分,我们将在其上应用不同的函数以及滤波器来获取结果
/*
@param windowName 选择窗口显示的名称
@param img 输入的image
@param boundingBoxes 选择的框
@param showCrosshair 如果为true显示选取内部的中心线,否则不显示
@param fromCenter 如果为真,选择中心将匹配初始鼠标位置。在相反的情况下,选择矩形的一个角将对应于鼠标的初始位置,是一个非常重要的参数,因为如果将其设置为True,则正确的选择会困难得多
*/
void selectROIs(const String& windowName, InputArray img,
                             CV_OUT std::vector<Rect>& boundingBoxes, bool showCrosshair = true, bool fromCenter = false);

选择所有停车位之后,可以将它们写入.csv文件里,就不用每次都要去手动选择车位框了。

1.2 detector探测器

现在我们已经选择了停车位,是时候进行一些图像处理了。解决这个问题的方法如
下:

  1. 从.csv文件获取坐标。
  2. 从中构建新图像。
  3. 应用OpenCV中可用的Canny函数。
  4. 计算新图像内的白色像素。
  5. 建立一个点内的像素范围将被占用。
  6. 在实时供稿上绘制一个红色或绿色矩形。

2. 代码


void drawRectangle(cv::Mat& img, cv::Rect rect, int lowThreshold, int highThreshold, int minPix, int maxPix, int &spots_loc)
{
    
    
	cv::Mat sub_img = img(rect);
	cv::Mat edges;
	cv::Canny(sub_img, edges, lowThreshold, highThreshold);
	int pix = cv::countNonZero(edges);

	if (pix >= minPix && pix <= maxPix)
	{
    
    
		cv::rectangle(img, rect, cv::Scalar(0, 255, 0), 3);
		spots_loc++;
	}
	else
	{
    
    
		cv::rectangle(img, rect, cv::Scalar(0, 0, 255), 3);
	}
}

int main()
{
    
    
	char* path = "E:\\code\\Yolov5_Tensorrt_Win10-master\\pictures\\1.png";
	Mat src = imread(path);
	if (src.empty()) {
    
    
		return -1;
	}
	std::vector<cv::Rect> result_pots;
	cv::selectROIs("roi", src, result_pots, false, false);

	cv::namedWindow("parameters");
	int val1 = 186, val2 = 122, val3 = 100, val4 = 800;
	cv::createTrackbar("Threshold1", "parameters", &val1, 700);
	cv::createTrackbar("Threshold2", "parameters", &val2, 700);
	cv::createTrackbar("Min pixels", "parameters", &val3, 1500);
	cv::createTrackbar("Max pixels", "parameters", &val4, 1500);

	while (true)
	{
    
    
		int spots_loc = 0;
		int min = cv::getTrackbarPos("Min pixels", "parameters");
		int max = cv::getTrackbarPos("Max pixels", "parameters");
		int lowThreshold = cv::getTrackbarPos("Threshold1", "parameters");
		int highThreshold = cv::getTrackbarPos("Threshold2", "parameters");

		for (const auto& rect : result_pots)
		{
    
    
			drawRectangle(src, rect, lowThreshold, highThreshold, min, max, spots_loc);
		}

		std::string text = cv::format("Available spots:%d", spots_loc);
		cv::putText(src, text, {
    
     20, 30 }, cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0,255,0), 2);
		cv::imshow("src", src);

		if ((cv::waitKey(1) & 0xFF) == 'q')
			break;
	}

	return 0;
}

3. 效果图

在这里插入图片描述
注意:

  • 为实时调整参数,构建一些轨迹栏,通过调整参数可以正确识别空闲停车位
  • 显示中的Available spots:数字有叠加,因为没有视频,是靠一张图片循环的
  • 这里的select 框并没有存文件,每次需要手动选择

猜你喜欢

转载自blog.csdn.net/wyw0000/article/details/131119575
今日推荐