Недавно наводил порядок в архивах и наткнулся на папку с диссертацией. покопался немного в исходниках матлаба и решил проверить рабочее ли все?
Взор у меня пал на скрипт Circles.m. Скажу честно код совершенно нечитабелен. И если бы его когдато написал не я то наверно я черти с два понял что там написано.
сценарий таков:
1. Есть изображение черно белое, какой то слитной фигуры, например самолета. Вот пример
2. Делаем над ним двумерное преобразование Гильберта. В результате мы получим точки в местах перегибов контура фигуры - назовем их характерными точками
3. А теперь геометрия. Задача найти центр масс слитной фигуры, в данном случае самолета, и провести концентрические окружности с центом в центре масс фигуры. Представить эти окружности как радар, и предположить что если характерная точка в пределах видимости радара, то засветить её. Должно получиться что то типа вот этого:
проблема в том что характерные точки вовсе не обязательно будут лежать на концентрических окружностях радар. Необходимо сделать допущение что если характерная точка в непосредственной близости от радара, то она засветится, как то вот так
черным цветом обозначил светящиеся точки, не лучший вариант но тем не менее понятно вроде.
Теперь о реализации.
Писалось это очень давно и на скриптовом языке для научных вычислениях Matlab.
скрипт выглядит примерно так
for r = 10 : 10 : 130
%рассчет координат точек окружности радара - 100 точек с радиусом r и центром в xr,yr
circlePoints = calcCirclePoints(xr, yr, r, 100, 0);
hold on
plot(circlePoints(1,:), circlePoints(2,:), 'r-')
hold on
for i = 1 : length(arClasterData)
d = sqrt((arClasterData(i,1) - xr)^2 + (arClasterData(i,2) - yr)^2);
if d >= (r-1)
%уравнение прямой ax+b рассчитаем коэффициенты a и b для прямой проходящей от центра до характерной точки
[a, b] = calcLineKoef(xr, yr, arClasterData(i,1), arClasterData(i,2));
%а теперь рассчитаем расстояние от характерной точки до окружности радара
d = pointToCircleDist(arClasterData(i,1), arClasterData(i,2), xr, yr, r, a, b);
%если расстояние меньше 1 то засветим точку
if d <= 1
hold on
plot(arClasterData(i,1), arClasterData(i,2),'k*')
end
end
end
end
Самой интересной функцией тут является на мой взгляд расчет расстояния от точки до окружности. Как известно это можно сделать с помощью касательной к окружности, а именно нахождения координат точки соприкосновения касательной и окружности и расчета Евклидова расстояния от этой точки до характерной точки. Сделал я это так
function d = pointToCircleDist(xp, yp, xr, yr, r, a, b)
switch checkCircleSector(xr, yr, xp, yp)
case 1
y = yr + r * sin(abs(atan(a)));
x = xr + r * cos(abs(atan(a)));
case 2
y = yr + r * sin(pi - abs(atan(a)));
x = xr + r * cos(pi - abs(atan(a)));
case 3
y = yr + r * sin(pi + abs(atan(a)));
x = xr + r * cos(pi + abs(atan(a)));
case 4
y = yr + r * sin(2*pi - abs(atan(a)));
x = xr + r * cos(2*pi - abs(atan(a)));
end
d = sqrt((xp - x)^2 + (yp - y)^2);
В зависимости от того в каком квандранте находится характерная точка, координаты точки касания рассчитываются по разному
Как то так. На мой взгляд интересно.
Взор у меня пал на скрипт Circles.m. Скажу честно код совершенно нечитабелен. И если бы его когдато написал не я то наверно я черти с два понял что там написано.
сценарий таков:
1. Есть изображение черно белое, какой то слитной фигуры, например самолета. Вот пример
2. Делаем над ним двумерное преобразование Гильберта. В результате мы получим точки в местах перегибов контура фигуры - назовем их характерными точками
3. А теперь геометрия. Задача найти центр масс слитной фигуры, в данном случае самолета, и провести концентрические окружности с центом в центре масс фигуры. Представить эти окружности как радар, и предположить что если характерная точка в пределах видимости радара, то засветить её. Должно получиться что то типа вот этого:
проблема в том что характерные точки вовсе не обязательно будут лежать на концентрических окружностях радар. Необходимо сделать допущение что если характерная точка в непосредственной близости от радара, то она засветится, как то вот так
черным цветом обозначил светящиеся точки, не лучший вариант но тем не менее понятно вроде.
Теперь о реализации.
Писалось это очень давно и на скриптовом языке для научных вычислениях Matlab.
скрипт выглядит примерно так
for r = 10 : 10 : 130
%рассчет координат точек окружности радара - 100 точек с радиусом r и центром в xr,yr
circlePoints = calcCirclePoints(xr, yr, r, 100, 0);
hold on
plot(circlePoints(1,:), circlePoints(2,:), 'r-')
hold on
for i = 1 : length(arClasterData)
d = sqrt((arClasterData(i,1) - xr)^2 + (arClasterData(i,2) - yr)^2);
if d >= (r-1)
%уравнение прямой ax+b рассчитаем коэффициенты a и b для прямой проходящей от центра до характерной точки
[a, b] = calcLineKoef(xr, yr, arClasterData(i,1), arClasterData(i,2));
%а теперь рассчитаем расстояние от характерной точки до окружности радара
d = pointToCircleDist(arClasterData(i,1), arClasterData(i,2), xr, yr, r, a, b);
%если расстояние меньше 1 то засветим точку
if d <= 1
hold on
plot(arClasterData(i,1), arClasterData(i,2),'k*')
end
end
end
end
Самой интересной функцией тут является на мой взгляд расчет расстояния от точки до окружности. Как известно это можно сделать с помощью касательной к окружности, а именно нахождения координат точки соприкосновения касательной и окружности и расчета Евклидова расстояния от этой точки до характерной точки. Сделал я это так
function d = pointToCircleDist(xp, yp, xr, yr, r, a, b)
switch checkCircleSector(xr, yr, xp, yp)
case 1
y = yr + r * sin(abs(atan(a)));
x = xr + r * cos(abs(atan(a)));
case 2
y = yr + r * sin(pi - abs(atan(a)));
x = xr + r * cos(pi - abs(atan(a)));
case 3
y = yr + r * sin(pi + abs(atan(a)));
x = xr + r * cos(pi + abs(atan(a)));
case 4
y = yr + r * sin(2*pi - abs(atan(a)));
x = xr + r * cos(2*pi - abs(atan(a)));
end
d = sqrt((xp - x)^2 + (yp - y)^2);
В зависимости от того в каком квандранте находится характерная точка, координаты точки касания рассчитываются по разному
Как то так. На мой взгляд интересно.
No comments:
Post a Comment