2013-02-01 181 views
7

我試圖使用opencv自動查找並找到空停車場中的所有停車位。使用OpenCV檢測停車位

目前,我有一個代碼閾值的圖像,應用Canny邊緣檢測,然後使用概率霍夫線找到標記每個停車位的線。

程序然後繪製組成線的線和點

下面是代碼:

#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; 
} 

目前,我的主要問題是搞清楚如何來推斷行數據發現每個停車位的位置。我的目標是讓opencv找到停車位,並在每個停車位上繪製矩形,並標註點。

我認爲我目前使用的方法存在一些主要問題,因爲如輸出圖像所示,opencv正在檢測2個端點以外的多個點。這可能使得使用opencv很難連接2個相鄰的端點。

我讀了一些關於使用凸包的內容,但我不完全確定它的功能和工作原理。

任何幫助將不勝感激。 下面是我的程序的輸出圖像: http://imageshack.us/photo/my-images/22/test1hl.png/

http://imageshack.us/photo/my-images/822/test2lw.png/

+0

您是否可以在沒有任何處理的情況下包含輸入?對於檢測更多線條/點的問題,RANSAC可能比依靠Hough更好地解決此類問題。 – mmgp

+0

我想到的一件事是首先[擴大](http://docs.opencv.org/modules/imgproc/doc/filtering.html#dilate)圖像以使線條顯得更細。然後,也許opencv將只檢測每行2個端點。 –

+0

@TomKnapen你正在混合擴張與侵蝕。在這些例子中,線條很亮,所以擴大會使它們變大。所以讓我們用你的建議來替代侵蝕。現在你可以打破細線。但事實上,這一切都是無關緊要的,他使用的是Canny,它可以產生一個粗寬的邊緣。 – mmgp

回答

2

考慮細化的二進制圖像,然後檢測端點和分支點。根據提供的圖像,這是一個這樣的結果;終點爲紅色,分支點爲藍色。

enter image description here

現在,你可以找到停車位的位置。一對藍點總是由一條邊連接。每個藍點連接到兩個或三個紅點。然後有幾種方法可以找到由兩個藍色圓點和兩個紅色圓點組成的停車位,最簡單的方法是沿着直線:找到最接近的一對紅色圓點,其中一個圓點連接到某個藍色圓點,另一個紅色圓點連接到另一個藍點。這一步也可以通過檢查平行線與邊緣的距離來補充。

+0

好的非常感謝。你是否使用侵蝕來減薄閾值圖像? 明天早上我會試試看看結果如何。 – tincan

+0

原則上是的,請參閱http://en.wikipedia.org/wiki/Morphological_skeleton古典二進制形態骨架構造。 – mmgp

+0

我目前被困在獲取二進制圖像的骨架。 我基本上使用優化的代碼從這裏:http://felix.abecassis.me/2011/09/opencv-morphological-skeleton/,除了做腐蝕和擴張,我正在使用morphologyEx做開放形態。最後,我將skel轉移到用於Canny邊緣檢測的全局Mat中。問題是程序在運行時會掛起。窗口出現,但沒有顯示圖像。我已經將問題隔離到了do while循環中,但我不確定究竟是什麼導致了它。 – tincan