Я использовал стандартные преобразования hough для получения прямых линий в изображении с использованием OpenCV. Теперь мне нужно найти координаты x и y точки пересечения большей части линий на изображении. Моя идея состояла в том, чтобы разделить изображение на несколько сегментов 8 * 8 пикселей (я еще не определился с размером), а затем поиск в области для строк. Но я не уверен, как я рассчитываю линии в сегментах. Я поражен этим. Таким образом, вещи, которые я не могу сделать (используя openCV), это 1. Разместите изображение в сегменты 8 * 8 пикселей (я не знаю, есть ли функция для него, и если нет, то что мне делать) 2.Count количество строк в каждом сегменте. Любой материал для чтения или подсказки для кода будут действительно полезными.Меня поразило обнаружение точки пересечения большинства линий на изображении.
ответ
Ваш способ обнаружения точек пересечения совершенно неправильно. Для этого есть простая математическая формула. Я даю вам пример кода в простом С:
// 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;
}
Большое спасибо. Я использовал тот же метод, и он работал как шарм. –
Да. Я тоже это использовал. Примите мой ответ, чтобы другие люди знали, что нужно скопировать код. Я пытался документировать его как можно больше :-) – DanielHsH
При реализации любого алгоритма, который включает в себя геометрию - даже если это кажется простым математически - вы должны рассмотреть возможность проверки GeometricTools.com, который имеет обзоры математики, решения проблем могут возникать при реализации алгоритмов, а также пример кода. Это отличная рекомендация. http://www.geometrictools.com/ – Rethunk
Я могу помочь вам делить изображение на сегменты 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
Обратите внимание, что из-за шума, большинство линий не может пересекаться в одной точке все, кроме этого, попробуйте следующее:
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
Вы можете поделиться своим выходным изображением с нами? – G453
Не забудьте проголосовать или принять (нажмите V рядом с ответом) Aditya ... –