Хобрук: Ваш путь к мастерству в программировании

Matlab: Алгоритм построения диаграммы Вороного эллипсов

Существуют ли алгоритмы реализации диаграммы Вороного, ограничивающей эллипсы? Схема будет выглядеть как на картинках здесь диаграмма вороных эллипсов

http://www.loria.fr/~tzoumas/vorell/vorell01.png

Может ли кто-нибудь поделиться некоторыми ссылками, учебниками, кодами и т. Д., Связанными с этим?

Заранее спасибо.


Ответы:


1

Вот алгоритм, который использует преобразование расстояния вместе с < алгоритм href="http://www.mathworks.com/help/toolbox/images/ref/watershed.html" rel="nofollow noreferrer">водораздела для построения диаграммы Вороного для эллипсов.

%# first, define some ellipses (for simplicity, I use 0/90 orientation)
ellipses = [10,20,5,10;30,10,10,7;40,40,8,3];

%# put the ellipses into an image (few pixels, therefore pixelated)
img = false(50);
[xx,yy]=ndgrid(1:50,1:50);
for e = 1:size(ellipses,1),img = img | (xx-ellipses(e,1)).^2/ellipses(e,3)^2 + (yy-ellipses(e,2)).^2/ellipses(e,4)^2 <= 1;end

введите здесь описание изображения

%# perform the distance transform
dt = bwdist(img);

введите здесь описание изображения

%# apply the watershed algorithm. 
%# ws==0 are the lines for the Voronoi diagram
ws = watershed(dt);

%# create a RGB image and display
%# note: for yellow lines, replace the last
%# "ws==0" by "zeros(size(ws))", so that you
%# only put ws into the red and green channel (=yellow)
rgb = cat(3,ws==0,ws==0,ws==0)); 
%# add the ellipses into the red channel
rgb(:,:,1) = rgb(:,:,1) | img;
imshow(rgb)

введите здесь описание изображения

25.10.2011
  • Что я могу сделать с кодами для управления цветом линий и эллипсов? 25.10.2011
  • @Айви: rgb = repmat(ws==0,1,1,3);rgb(:,:,1) = rgb(:,:,1) | img;imshow(rgb) 25.10.2011
  • Как я могу одновременно отображать эллипсы и линии на изображении? Поскольку я imshow(dt), отображаются только многоточия, если я imshow(ws), только линии. и я попробовал rgb, была ошибка для «repmat»: слишком много входных аргументов. Что я мог сделать? 25.10.2011
  • @Ivy: извините, опечатка. Должно быть rgb=repmat(ws==0,[1 1 3]);. 25.10.2011
  • : извините, я до сих пор не знаю, как отобразить изображение, используя imshow (???)'. Предположим, что фон черный, цвет эллипса красный, цвет линии желтый. Не могли бы вы добавить некоторые коды в деталях? Большое спасибо. 27.10.2011

  • 2

    На всякий случай вот пример из справочной системы Mathematica:

    (*Generate ellipses*)
    p= Rasterize@Graphics@Table[
              Rotate[
                  Disk[RandomReal[10, 2],          (*Rnd position*)
                       RandomReal[{.3, 1.5}, 2]],  (*Rnd radii*)
              RandomReal[Pi]], {i, 10}]            (*Rnd rotation*)
    
    (*Compute Voronoi*)
    
    LaplacianGaussianFilter[DistanceTransform[p], 2] // ImageAdjust
    

    введите здесь описание изображения

    Это не точный расчет, но достаточно справедливый для практического использования.

    26.10.2011

    3

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

    Для этого конкретного вопроса, как показал @Jonas, решение состоит в том, чтобы использовать преобразование расстояния вместе с алгоритмом водораздела.

    Я подумал, что продолжу свой предыдущий пример и дополню его идеей Джонаса, чтобы продемонстрировать весь процесс. Надеюсь, вы найдете ее полезной..

    В коде используется функция calculateEllipse для вычисления координат точек, составляющих эллипс, а также функцию imoverlay для установки заданных пикселей изображение в выбранный цвет.

    %# color image (canvas to draw on)
    I = imread('pears.png');
    sz = size(I);
    
    %# random ellipses
    num = 20;
    centers = bsxfun(@times, rand(num,2), sz([2 1]));   %# center x/y-coords
    radii = bsxfun(@times, rand(num,2), [300 50])+10;   %# major/minor axis length
    angles = rand(num,1) .* 360;                        %# angle of rotation
    ex = cell(num,1);                                   %# vertices x-coords
    ey = cell(num,1);                                   %# vertices y-coords
    
    %# label image, used to hold rasterized ellipses
    L = zeros(sz(1),sz(2));
    
    %# randomly place ellipses one-at-a-time, skip if overlaps previous ones
    flag = false(num,1);
    for i=1:num
        %# ellipse we would like to draw directly on image matrix
        [ex{i},ey{i}] = calculateEllipse(centers(i,1),centers(i,2), ...
            radii(i,1),radii(i,2), angles(i), 100);
    
        %# create mask for image pixels inside the ellipse polygon
        mask = poly2mask(ex{i},ey{i}, sz(1),sz(2));
    
        %# check if there is no existing overlapping ellipse
        if all( L(mask)==0 )
            %# use the mask to place the ellipse in the label image
            L(mask) = sum(flag)+1;    %# assign value using an increasing counter
            flag(i) = true;
        end
    end
    
    %# filter ellipses to only those that made through the overlap test
    num = sum(flag);
    centers = centers(flag,:);
    radii = radii(flag,:);
    angles = angles(flag);
    ex = ex(flag);
    ey = ey(flag);
    
    %# rasterized voroni diagram of the ellipses [Jonas]
    E = (L ~= 0);                             %# ellipses as binary image
    WS = watershed( bwdist(E) );              %# distance transform + watershed
    WS = (WS == 0);                           %# WS==0 corresponds voronoi diagram
    WS = bwmorph(WS, 'thicken',1);            %# thicken the lines
    
    %# set pixels corresponding to voronoi diagram to white
    II = I;
    II = imoverlay(II, WS, [1 1 1]);          %# you can customize the color here
    
    %# set pixels corresponding to ellipses using specified colors
    clr = hsv(num);                           %# color of each ellipse
    for i=1:num
        mask = bwperim(L==i,8);               %# get perimeter of the ellipse mask
        mask = bwmorph(mask, 'thicken',1);    %# thicken the ellipse perimeter
        II = imoverlay(II, mask, clr(i,:));   %# set those pixels with RGB color
    end
    
    %# show final rasterized image (image + ellipses + voronoi diagram)
    figure, imshow(II, 'InitialMagnification',100, 'Border','tight')
    

    скриншот

    28.10.2011
  • Я попытался нарисовать сплошной эллипс, поэтому я удалил строку 'mask = bwperim(L==i,8);', которая должна получить периметр эллипса, но на выходе получился только один сплошной эллипс. Почему это случилось? Это какая-то логическая ошибка? 30.10.2011
  • @Ivy: если вы хотите нарисовать сплошные эллипсы, вы также должны удалить линию сразу после нее (утолщать периметр), таким образом, у вас будет только: mask = (L==i); 30.10.2011
  • Да, после удаления двух строк измените 'II = imoverlay(II, mask, clr(i,:));' на 'II = imoverlay(II, L, clr(i,:));' тоже будет работать. Кстати, если у меня I = нули (500 500,3), как изменить цвет фона с черного на (предположим) голубой [1 0 1]? Должен ли я снова применить imoverlay? или есть быстрый способ? 30.10.2011
  • @Ivy: Если быть точным, это должно быть: II = imoverlay(II, L==i, clr(i,:));. Теперь, если вы начали с черного изображения I(:) = 0;, вы можете использовать I = imoverlay(I,true(sz(1),sz(2)),[1 0 1]);, чтобы изменить цвет фона на голубой. 30.10.2011
  • Я не могу понять часть проверки перекрывающихся эллипсов, особенно эту строку if all( L(mask)==0 ). что это означает? 10.11.2011
  • @Ivy: в основном на предыдущем шаге мы строим mask, содержащую логическую матрицу (истина/ложь), которая указывает внутреннюю часть эллипса. Теперь, прежде чем поместить его в матрицу меток, мы проверяем, не перекрывает ли он какие-либо существующие эллипсы. Это делается путем проверки того, что все истинные пиксели, указанные маской, имеют нулевые значения в матрице меток (если хотя бы один пиксель был отличен от нуля, это означает, что мы уже разместили эллипс, проходящий через это место, и, таким образом, мы пропускаем текущий) 10.11.2011
  • : Спасибо. Что, если многоточия просто соприкасаются, как я могу проверить это и пропустить последнее? Потому что, когда я увеличиваю num примерно до 50, в то время как я устанавливаю все радиусы на одно и то же значение [10 6], касание происходит в течение нескольких тривалов. И после bwdist и водораздела будут обработаны два соприкасающихся эллипса. как один и, таким образом, заключаются (два эллипса в ячейке). Это не то, что я ожидаю. 10.11.2011
  • @Ivy: а, я вижу вашу проблему.. Одна из возможностей - утолщать эллипс на 1 непосредственно перед выполнением теста на перекрытие (точнее, его копию), таким образом, мы дополнительно проверяем периметр толщиной в один пиксель вокруг его окрестности, тем самым избегая едва касающегося случая. Поэтому внесите следующие изменения: mask2 = bwmorph(mask, 'thicken',1); затем выполните тест с этой измененной маской: if all( L(mask2)==0 ) ... 10.11.2011
  • @Ivy: сравните результат на этом примере: до и после 10.11.2011

  • 4

    Я не знаю, что вы имеете в виду под «эллипсами». Но есть реализация диаграмм Вороного на C++ от Stephan Fortune / Shane O'Sullivan,

    http://www.skynet.ie/~sos/mapviewer/voronoi.php

    24.10.2011
  • Эллипсы занимают место «точек» (x, y), которые ограничены линиями. 24.10.2011
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..