Обнаружение центральной точки пересечения с использованием Matlab - PullRequest
9 голосов
/ 11 февраля 2010

alt text

Здравствуйте, у меня есть изображение, как показано выше. Могу ли я определить центральную точку креста и вывести результат с помощью Matlab? Спасибо.

Ответы [ 6 ]

7 голосов
/ 11 февраля 2010

Вот, пожалуйста. Я предполагаю, что у вас есть набор инструментов для изображений, потому что если вы этого не сделаете, вам, вероятно, не стоит пытаться делать подобные вещи. Тем не менее, я полагаю, что все эти функции могут быть реализованы с помощью сверток. Я проделал этот процесс на изображении, которое вы представили выше, и получил точку (139 286), где 138 - строка, а 268 - столбец.

1. Преобразовать изображение в двоичное изображение:

bw = bw2im(img, .25);

где img - исходное изображение. В зависимости от изображения вам может потребоваться настроить вторые параметры (в диапазоне от 0 до 1), чтобы получить только крестик. Не беспокойтесь о том, что крест не полностью связан, потому что мы исправим это на следующем шаге.

2. Расширьте изображение, чтобы соединить части. Я должен был сделать это дважды, потому что мне пришлось установить пороговое значение так низко при преобразовании двоичного изображения (некоторые части вашего изображения были довольно темными). Расширение, по сути, просто добавляет пиксели вокруг существующих белых пикселей (я также буду инвертировать двоичное изображение, когда отправляю его в bwmorph, потому что операции выполняются для воздействия на белые пиксели, которые имеют значение 1).

bw2 = bwmorph(~bw, 'dilate', 2);

Последний параметр указывает, сколько раз нужно выполнить операцию расширения.

3.Сжать изображение до точки.

bw3 = bwmorph(bw2, 'shrink',Inf);

Опять же, последний параметр говорит, сколько раз выполнить операцию. В этом случае я вставляю Inf, который сжимается до тех пор, пока не останется только один пиксель белого цвета (другими словами, 1).

4.Найдите пиксель, который все еще равен 1.

[i,j] = find(bw3);

Здесь i - строка, а j - столбец пикселя в bw3, так что bw3 (i, j) равно 1. Все остальные пиксели должны быть 0 в bw3.

Могут быть и другие способы сделать это с помощью bwmorph, но я думаю, что этот способ работает довольно хорошо. Возможно, вам придется настроить его в зависимости от изображения. При желании я могу включить изображения каждого шага.

1 голос
/ 05 января 2019

Я только что столкнулся с такой же проблемой и нашел другие решения, которыми хотел бы поделиться:

Предположим, имя файла изображения pict1.jpg.

1.Считайте входное изображение, обрежьте соответствующую часть и преобразуйте в оттенки серого:

origI = imread('pict1.jpg'); %Read input image

I = origI(32:304, 83:532, :); %Crop relevant part
I = im2double(rgb2gray(I)); %Covert to Grayscale and to double (set pixel range [0, 1]).

2. Преобразование изображения в двоичное изображение в надежном подходе:

%Subtract from each pixel the median of its 21x21 neighbors
%Emphasize pixels that are deviated from surrounding neighbors
medD = abs(I - medfilt2(I, [21, 21], 'symmetric'));

%Set threshold to 5 sigma of medD
thresh = std2(medD(:))*5;

%Convert image to binary image using above threshold
BW = im2bw(medD, thresh);

BW Image:

BW Image

3. Теперь я предлагаю два подхода к поиску центра:

  • Найти центр тяжести (найти центр масс белого скопления)
  • Найдите две линии, используя преобразование Хафа, и найдите точку пересечения

Оба решения возвращают субпиксельный результат.

3.1. Найти центр пересечения с помощью regionprops (найти центр тяжести):

%Find centroid of the cross (centroid of the cluster)
s = regionprops(BW, 'centroid');
centroids = cat(1, s.Centroid);

figure;imshow(BW);
hold on, plot(centroids(:,1), centroids(:,2), 'b*', 'MarkerSize', 15), hold off

%Display cross center in original image
figure;imshow(origI), hold on, plot(82+centroids(:,1), 31+centroids(:,2), 'b*', 'MarkerSize', 15), hold off

Результат центроида (изображение BW):

Centroid result BW

Результат центроида (исходное изображение):

Centroid result (original image)

3.2 Найти центр пересечения путем пересечения двух линий (используя преобразование Хафа ):

%Create the Hough transform using the binary image.
[H,T,R] = hough(BW);

%ind peaks in the Hough transform of the image.
P  = houghpeaks(H,2,'threshold',ceil(0.3*max(H(:))));
x = T(P(:,2)); y = R(P(:,1));

%Find lines and plot them.
lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7);
figure, imshow(BW), hold on
L = cell(1, length(lines));
for k = 1:length(lines)
    xy = [lines(k).point1; lines(k).point2];
    plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');

    % Plot beginnings and ends of lines
    plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
    plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');

    %http://robotics.stanford.edu/~birch/projective/node4.html
    %Find lines in homogeneous coordinates (using cross product):
    L{k} = cross([xy(1,1); xy(1,2); 1], [xy(2,1); xy(2,2); 1]);
end

%https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
%Lines intersection in homogeneous coordinates (using cross product):
p = cross(L{1}, L{2});

%Convert from homogeneous coordinate to euclidean coordinate (divide by last element).
p = p./p(end);
plot(p(1), p(2), 'x', 'LineWidth', 1, 'Color', 'white', 'MarkerSize', 15)

Результат преобразования Hough:

* *

Hough transform result* 1057 1058 *

1 голос
/ 06 сентября 2011

Как насчет этого;

а) преобразовать в двоичный файл только для ускорения алгоритма.

б) Выполнить поиск по результирующему массиву

в) выберите элемент, который имеет самый низкий / самый высокий индекс строки / столбца (тогда у вас будет четыре пункта для выбора

d) теперь продолжайте искать соседей

  • имеет глобальный критерий поиска: если поиск не приводит к более чем нескольким итерациям, выбранная точка имеет значение false и выбирает другую крайнюю точку

e) проходя по соседним точкам, вы окажетесь в точке, где у вас есть три возможных соседа. Это ваше пересечение

1 голос
/ 28 сентября 2010

Мне просто нравятся эти дискуссии о том, как найти что-то, не определяя сначала, что это такое! Но, если бы мне пришлось угадывать, я бы предложил центр масс исходного изображения в оттенках серого.

1 голос
/ 11 февраля 2010

Я думаю, что есть гораздо более простой способ решения этой проблемы. Линии, которые образуют перекрестие, имеют одинаковую длину. Поэтому оно будет симметричным во всех ориентациях. Так что, если мы делаем простое сканирование линий по горизонтали и по вертикали, чтобы найти конечности линий, образующих перекрестие. медиана этих значений даст координаты x и y центра. Простая геометрия.

0 голосов
/ 11 февраля 2010

Я бы начал с использования карты изображений в градациях серого. Самые темные точки находятся на пересечении, поэтому различие по самым высоким значениям является отправной точкой. После различения установите все нижние точки на белые и оставьте остальные как есть. Это увеличило бы контраст между точками на кресте и точками на изображении. Далее следует создать фильтр для определения позиции с самыми высокими средними значениями. Я бы шагал по всему изображению с массивом NxM и принимал среднее значение в центральной точке. Создайте новый массив этих средств, и вы должны иметь самое высокое среднее значение на пересечении. Мне любопытно посмотреть, как кто-то еще может попробовать это!

...