C++ 使用OpenCV检测停车位
我正在尝试使用opencv自动查找和定位空停车场中的所有停车位 目前,我有一个代码,可以对图像进行阈值设置,应用canny边缘检测,然后使用概率hough线找到标记每个停车位的线 然后,程序绘制线条和组成线条的点 代码如下:C++ 使用OpenCV检测停车位,c++,image-processing,opencv,vision,C++,Image Processing,Opencv,Vision,我正在尝试使用opencv自动查找和定位空停车场中的所有停车位 目前,我有一个代码,可以对图像进行阈值设置,应用canny边缘检测,然后使用概率hough线找到标记每个停车位的线 然后,程序绘制线条和组成线条的点 代码如下: #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; using names
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int threshold_value = 150;
int threshold_type = 0;;
int const max_value = 255;
int const max_type = 4;
int const max_BINARY_value = 255;
int houghthresh = 50;
char* trackbar_value = "Value";
char* window_name = "Find Lines";
int main(int argc, char** argv)
{
const char* filename = argc >= 2 ? argv[1] : "pic1.jpg";
VideoCapture cap(0);
Mat src, dst, cdst, tdst, bgrdst;
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
createTrackbar( trackbar_value,
window_name, &threshold_value,
max_value);
while(1)
{
cap >> src;
cvtColor(src, dst, CV_RGB2GRAY);
threshold( dst, tdst, threshold_value, max_BINARY_value,threshold_type );
Canny(tdst, cdst, 50, 200, 3);
cvtColor(tdst, bgrdst, CV_GRAY2BGR);
vector<Vec4i> lines;
HoughLinesP(cdst, lines, 1, CV_PI/180, houghthresh, 50, 10 );
for( size_t i = 0; i < lines.size(); i++ )
{
Vec4i l = lines[i];
line( bgrdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,255,0), 2, CV_AA);
circle( bgrdst,
Point(l[0], l[1]),
5,
Scalar( 0, 0, 255 ),
-1,
8 );
circle( bgrdst,
Point(l[2], l[3]),
5,
Scalar( 0, 0, 255 ),
-1,
8 );
}
imshow("source", src);
imshow(window_name, bgrdst);
waitKey(1);
}
return 0;
}
#包括“opencv2/highgui/highgui.hpp”
#包括“opencv2/imgproc/imgproc.hpp”
#包括
使用名称空间cv;
使用名称空间std;
int阈值_值=150;
int threshold_type=0;;
int const max_值=255;
int const max_type=4;
int const最大二进制值=255;
int houghthresh=50;
char*trackbar_value=“value”;
char*window_name=“查找行”;
int main(int argc,字符**argv)
{
const char*filename=argc>=2?argv[1]:“pic1.jpg”;
视频捕获上限(0);
Mat src、dst、cdst、tdst、bgrdst;
namedWindow(窗口名称、CV窗口自动大小);
createTrackbar(轨迹栏_值,
窗口名称和阈值,
最大值);
而(1)
{
cap>>src;
CVT颜色(src、dst、CV_rgb2灰色);
阈值(dst、tdst、阈值、最大二进制值、阈值类型);
Canny(tdst,cdst,50,200,3);
CVT颜色(tdst、bgrdst、CV_GRAY2BGR);
矢量线;
HoughLinesP(cdst,lines,1,CV_PI/180,houghthresh,50,10);
对于(size_t i=0;i
目前,我的主要问题是如何推断线路数据以找到每个停车位的位置。我的目标是让opencv找到停车位,并在每个停车位上画出矩形,用数字标记停车位
我认为我目前使用的方法存在一些主要问题,因为如输出图像所示,opencv正在检测线上的多个点,而不是2个端点。这可能会使使用opencv连接两个相邻端点变得非常困难
我读了一些关于使用凸包的书,但我不确定它是做什么的,以及它是如何工作的
任何帮助都将不胜感激。
以下是我的程序的输出图像:
考虑细化二值图像,然后检测端点和分支点。这里是基于所提供的图像的一个这样的结果;端点为红色,分支点为蓝色
现在你可以找到停车位的位置了。一对蓝点总是通过一条边连接在一起。每个蓝点连接到两个或三个红点。然后有几种方法可以找到由两个蓝点和两个红点组成的停车位,最简单的方法是沿着直线:找到最近的一对红点,其中一个点连接到某个蓝点,另一个红点连接到另一个蓝点。这一步还可以通过检查边缘与平行线的距离来补充。是否可以在不进行任何处理的情况下包含输入?对于检测到比你所追求的更多的线/点的问题,RANSAC可能比依靠Hough更擅长解决这类问题。我想到的一件事是首先对图像进行处理,使线看起来更细。那么,opencv可能只会检测每行的2个端点。@TomKnapen您将膨胀与侵蚀混为一谈。在这些示例中,线条是明亮的,因此放大会使线条变大。因此,让我们将您的建议替换为侵蚀。现在你可以打破细线了。但实际上这一切都无关紧要,他使用的是Canny,它给出了一个粗宽的边缘。@mmgp输入是右侧的窗口。这是从我的网络摄像头拍摄的停车场图像。我将对ransac做一些研究,看看如何实现它。因此,目前我正在使用Canny,但我认为可能有更好的方法,因为标记停车位的每个相邻四边形可以共享一条边。我是不是应该用腐蚀使线条变细,以便在canny中只检测到一条线条?@TianYao也许我的请求不够清晰,我只是要求你在不进行任何处理的情况下包含图像。这里包含的图像是截图,我的建议是包含一些实际的帧(不是它们的截图,或者其他任何东西)。要使线条变细,正确的方法需要一个细化算法,该算法可以使用命中或未命中变换(opencv中不可用)实现,但也有其他方法可以实现。但是,为了给出更准确的建议(而不仅仅是猜测),我们需要您使用的实际数据。好的,非常感谢。您是否使用腐蚀来细化阈值图像?明天早上我会尝试一下,看看结果如何。原则上是的,请参阅经典的二值形态学骨架构造。我目前正忙于获取二值图像的骨架。我基本上是在这里使用优化的代码:,除了不做腐蚀和扩张,我用morphologyEx做一个开放的形态学。最后,我将skel转换成一个全局Mat,用于Canny边缘检测。问题是程序在我运行时挂起。窗口显示,但不显示图像。我已经将问题隔离到do while循环中,但我不确定到底是什么导致了它。所以在一些测试之后,我注意到countNonZero永远不会变为0,这意味着do while循环将无限继续。我会试着把每个阶段的图片放出来,看看是否有任何变化发生。我意识到我在循环结束时复制到了错误的垫子上,这意味着