2012-12-26 1 views
0

Я использовал стандартные преобразования hough для получения прямых линий в изображении с использованием OpenCV. Теперь мне нужно найти координаты x и y точки пересечения большей части линий на изображении. Моя идея состояла в том, чтобы разделить изображение на несколько сегментов 8 * 8 пикселей (я еще не определился с размером), а затем поиск в области для строк. Но я не уверен, как я рассчитываю линии в сегментах. Я поражен этим. Таким образом, вещи, которые я не могу сделать (используя openCV), это 1. Разместите изображение в сегменты 8 * 8 пикселей (я не знаю, есть ли функция для него, и если нет, то что мне делать) 2.Count количество строк в каждом сегменте. Любой материал для чтения или подсказки для кода будут действительно полезными.Меня поразило обнаружение точки пересечения большинства линий на изображении.

+1

Вы можете поделиться своим выходным изображением с нами? – G453

+0

Не забудьте проголосовать или принять (нажмите V рядом с ответом) Aditya ... –

ответ

1

Ваш способ обнаружения точек пересечения совершенно неправильно. Для этого есть простая математическая формула. Я даю вам пример кода в простом С:

// This is a point 
typedef struct{ 
    int x,y; 
} MYintPOINT; 

// This is line 
typedef struct { 
    MYintPOINT pStart; 
    MYintPOINT pEnd; 
} MyLine; 

#define PointMinusPoint(P,Q,R)  {(P).x = (Q).x - (R).x; (P).y = (Q).y - (R).y;} 
#define PointCross(P,Q)    (((P).x*(Q).y)-((P).y*(Q).x)) 
#define SIGN(X)    (((X)>=0)? 1:-1) 
#define ABS(a)    ((a) >= 0 ? (a) : (-(a))) 
#define ROUND(a)   ((SIGN(a)) * ((int)(ABS(a) + 0.5))) 

// Given 2 line segments, find their intersection point 
// rerurns [Px,Py] point in 'res' or FALSE if parallel. Uses vector cross product technique. 
int findLinesIntersectionPoint(const MyLine*l1, const MyLine*l2, MYintPOINT *res){ 
    MYintPOINT p = l1->pStart; 
    MYintPOINT dp; 
    MYintPOINT q = l2->pStart; 
    MYintPOINT dq; 
    MYintPOINT qmp;   // q-p 
    int   dpdq_cross;  // 2 cross products 
    int   qpdq_cross;  // dp with dq, q-p with dq 
    float  a; 

    PointMinusPoint(dp,l1->pEnd,l1->pStart); 
    PointMinusPoint(dq,l2->pEnd,l2->pStart); 
    PointMinusPoint(qmp,q,p); 

    dpdq_cross = PointCross(dp,dq); 
    if (!dpdq_cross){ 
     // Perpendicular Lines 
     return 0; 
    } 

    qpdq_cross = PointCross(qmp,dq); 
    a = (qpdq_cross*1.0f/dpdq_cross); 

    res->x = ROUND(p.x+a*dp.x); 
    res->y = ROUND(p.y+a*dp.y); 
    return 1; 
} 
+0

Большое спасибо. Я использовал тот же метод, и он работал как шарм. –

+0

Да. Я тоже это использовал. Примите мой ответ, чтобы другие люди знали, что нужно скопировать код. Я пытался документировать его как можно больше :-) – DanielHsH

+2

При реализации любого алгоритма, который включает в себя геометрию - даже если это кажется простым математически - вы должны рассмотреть возможность проверки GeometricTools.com, который имеет обзоры математики, решения проблем могут возникать при реализации алгоритмов, а также пример кода. Это отличная рекомендация. http://www.geometrictools.com/ – Rethunk

0

Я могу помочь вам делить изображение на сегменты 8 * 8 пикселей.

Функции rowRange() и colRange() в OpenCV полезны для этого. (documentation here) Вот пример:

cv::Mat img = cv::imread("myImage.png"); 
cv::Mat region = img.rowRange(0,7).colRange(0,7); //upper-left 8x8 image region 
0

Обратите внимание, что из-за шума, большинство линий не может пересекаться в одной точке все, кроме этого, попробуйте следующее:

create black_image 
for each line 
    create temporary_black_image 
    draw a line to temporary_black_image, use cvScalar(1) as a color for the line 
    cvAdd both temporary_black_image to black_image 
apply cvSmooth to black_image 
CvPoint minLoc; CvPoint maxLoc; 
double minVal; double maxVal; 
cvMinMaxLoc(black_image, &minVal, &maxVal, &minLoc, &maxLoc); 

maxLoc->x and maxLoc-> y will be your estimate 

Вы можете попробовать немного настроить параметры путем изменения параметров функции cvSmooth