Выбор данных в интересующей области в матрице (с Mathematica) - PullRequest
8 голосов
/ 13 июля 2011

У меня проблема (mathematica 8.0.1.0-), которую я не могу решить самостоятельно.У меня есть данные измерений в матрице, я хочу выбрать некоторые из них, а затем сложить их.

Чтобы лучше объяснить мою проблему, приведу простой пример.Данные могут быть получены с помощью матрицы S:

S = Table[ -Sin[i/2] - Sin[j/2], {i,20}, {j,20}];

Они могут быть красиво нанесены с помощью:

xmin = N[Min[S]]; 
xmax = N[Max[S]]; 
mycolorfun = Function[ Blend[{Blue,Cyan,Green,Yellow,Red},#] ];

и

MatrixPlot[S, PlotRange -> {All,All,All}, AspectRatio -> 1/1,
   ColorFunction -> (mycolorfun[ Rescale[ #1{xmin,xmax} ] ]&),
   ColorFunctionScaling -> False, MaxPlotPoints -> Automatic,
   FrameLabel -> {y,x} ]

Тогда нужно получитькартинка, подобная этой:

enter image description here

Теперь я хочу выбрать данные, которые находятся внутри коричневого нарисованного многоугольника.Эти данные должны быть добавлены в конце.

Как я могу это сделать?Хорошо, я мог бы использовать прямоугольники и построить подматрицу, выбрав / угадав хорошие начальные и конечные индексы.Тогда мне просто нужно построить сумму этой подматрицы.Но я бы предпочел многоугольники (точнее, если мы не будем спорить о небольших проблемах со значениями матрицы, которые пересекаются линией многоугольника).И мне бы очень понравилось, если бы я мог выбрать свою область интересов (ROI) напрямую, «нарисовав» многоугольник в матрице (больше не тратя времени на выбор / угадывание индексов матрицы).
Может ли кто-нибудь здесь помочь мне с моей проблемой?Если это не решаемо с mathematica, есть ли какая-нибудь другая программа, которую я мог бы использовать?

Я был бы очень рад некоторой помощи и подсказкам!

Ответы [ 3 ]

10 голосов
/ 14 июля 2011

Если выбор области интереса графически вручную не является проблемой, то вы можете:

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

S = Table[-Sin[i/50.] - Sin[j/50.], {i, 400}, {j, 400}];
img = ReliefImage@S

Затем с помощью интерфейсных графических инструментов нарисуйте многоугольник над интересующей вас областью (щелкните правой кнопкой мыши):

enter image description here

Затем получите маску, соответствующую вашему многоугольнику (опять же, кнопка правой кнопки мыши):

enter image description here

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

Total[S*ImageData@mask, Infinity]

Весь процесс выглядит так:

enter image description here

РЕДАКТИРОВАТЬ : Если вы хотите определить интересующую вас область с помощью контура свободной руки, используйте инструмент линии свободной руки вместо многоугольника. Удостоверьтесь, чтобы увеличить ширину обводки, чтобы было легко закрыть контур при рисовании. Вы можете сделать это, переместив ползунок Обводка> Толщина вправо.

Это будет выглядеть так:

enter image description here

Затем создайте маску, заполнив внутреннюю часть контура свободной руки, используя функцию FillingTransform, и продолжайте как раньше:

enter image description here

5 голосов
/ 13 июля 2011

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

Вы можете использовать функции обработки изображений:

Сначала Бинаризируйте изображение, используя соответствующий порог. Затем используйте MorphologicalComponents , который идентифицирует все связанные области. Наконец, вы можете извлечь данные изображения и использовать Pick, чтобы получить значения пикселей, соответствующие интересующему вас компоненту.

РЕДАКТИРОВАТЬ: Вот иллюстрация концепции:

enter image description here

5 голосов
/ 13 июля 2011

Возможно, это:

upl = 20;
s = Table[-Sin[i/2] - Sin[j/2], {i, upl}, {j, upl}];

xmin = N[Min[s]]; xmax = N[Max[s]]; mycolorfun = 
Function[Blend[{Blue, Cyan, Green, Yellow, Red}, #]];

mp = MatrixPlot[s, PlotRange -> {All, All, All}, AspectRatio -> 1/1, 
ColorFunction -> (mycolorfun[Rescale[#1, {xmin, xmax}]] &), 
ColorFunctionScaling -> False, MaxPlotPoints -> Automatic, 
FrameLabel -> {"y", "x"}];
Manipulate[
{{x1, y1}, {x2, y2}} = 
 Floor /@ {{p1[[1]], upl - p1[[2]]}, {p2[[1]], upl - p2[[2]]}};
    mp,
{{p1, {1, 1}}, Locator}, {{p2, {19, 19}}, Locator}]

Dynamic[{{x1, y1}, {x2, y2}}]
Dynamic[N@s[[y2 ;; y1, x1 ;; x2]] // MatrixForm]

, который производит такие вещи, как enter image description here с обновлением части матрицы в реальном времени при перемещении локаторов.

Чтобы создать вместо этого полигоны, просто добавьте ещелокаторы.Выбор части матрицы тогда более сложен, и это зависит от того, как вы хотите, чтобы вещи выводились.

...