2015-03-19 2 views
2

Здесь тип изображений я работаю с:Использование Matlab для сканирования из указанной строки в изображении, чтобы обнаружить новую область на основе изменения интенсивности

enter image description here

Вы можете увидеть розовый линия Айв график, используя код ниже:

A=imread('b20.bmp'); 
AR=A(:,:,1); 
[rows, columns] = size(AR); 
y1 = 200; 
y2 = 315; 
row1 = AR(y1, :); % Extract this line of gray levels from the image. 
figure, image(AR,'CDataMapping','scaled'); colormap('gray'); 
title('Input Image in Grayscale') 
hold on; 
plot([0, columns], [y2, y2], 'm'); 

Im ищет для сканирования вверх от выделенной строки (315) в первой строке изображения в попытке обнаружить темную область, как только что обнаружена область I» m смотрит на график другой линии в середине точки da rk, аналогично первому (весь путь по изображению).

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

+0

Можете ли вы предоставить оригинал вместо снимка экрана? –

+1

Почему бы вам просто не суммировать (или усреднить) по размеру 2, а затем найти большие изменения в профиле интенсивности? Кроме того, если вы просто хотите дать каждому региону среднее значение, вы можете посмотреть анизотропную диффузию, которая будет «гомогенизировать» регионы, оставив края неповрежденными. – Jonas

ответ

0

Jonas в значительной степени сказал вам, как его решить. Однако, поскольку мне нравится играть с изображениями, я решил написать ответ. То, что я сделал бы, - это извлечь суб-изображение, которое идет от строк 1 до 315, тогда я бы независимо нашел среднее значение для каждой строки . Это даст вам вектор элементов 315 ... тогда из этого результата любое местоположение дает нам огромный всплеск, вероятно, там, где начинается подразделение. Вот искусственный пример. Я попробовал воссоздать ваш код с минимальным кодом. Я собираюсь создать черно-белое изображение, где верхняя половина черная, а нижняя половина - белая. Как только я это сделаю, я добавлю к нему случайный гауссовский шум с амплитудой 10, средним значением 0 и стандартным отклонением 1. После этого я нормализую изображение так, чтобы оно находилось между [0,1] с точки зрения динамического диапазона :

%// Set random seed generator 
rng(123); 

%// Create black and white image. First 250 rows is black, next 250 rows is gray 
im = [zeros(250, 256); 128*ones(250,256)]; 

%// Add Gaussian random noise of amplitude 10, mean 0, std.dev = 1 
im_noise = im + 10*randn(size(im)); 

%// Normalize image so it's between [0,1] 
AR = (im_noise - min(im_noise(:)))/(max(im_noise(:)) - min(im_noise(:))); 

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

enter image description here

Теперь вот где начинается волшебство. Найдем среднее значение каждой строки между строками 1 и 315:

avgs = mean(AR(1:315,:), 2); 

Параметр 2 означает действовать по столбцам, а это значит, что мы найдем среднее значение каждой строки. Это означает, что мы получим вектор элемента 315, где каждый элемент равен в среднем строки .... так что первым элементом является среднее значение строки 1, второй элемент - это среднее значение строки 2 и т. Д. Если мы наносим эти средние на обычном участке, где номер строки является горизонтальной осью, а средняя интенсивность по вертикальной оси, это то, что мы получаем:

plot(1:315, avgs); 

enter image description here

Как вы можете видеть , есть ясный всплеск на 250, и в изображении, который я разработал, прямо в строке 250, где я сделал серый квадрат. Мы можем определить , где этот всплеск появляется, делая diff в сочетании с max, где мы вычисляем попарные расстояния между элементами массива. diff работает, где первым выходом является второй элемент минус первый, затем второй элемент - третья пара минус вторая и т. Д.В этом случае, поскольку мы переходим от низкого к высокому, это означает, что любое местоположение дает нам наивысшую разницу, означает, что мы взяли число справа (или самое высокое значение края) влево (или самое низкое значение . края Поэтому мы находим попарные расстояния и определить точку, где мы имеем попарное расстояние, которое является максимально возможным Таким образом, сделать что-то вроде:.

[~,ind] = max(diff(avgs)); 

что приятно о max здесь является то, что если есть несколько значений, которые видны в данных, которые имеют один и тот же максимум, мы возвращаем только значение. Это приятно, потому что, как только мы обнаружим наш всплеск в сюжете, мы найдем этот результат imme ственно. Если вы сделали это правильно, ind должно быть 250.

Одна вещь, которую я хотел бы отметить, заключается в том, что приведенный выше синтаксис предполагает, что вы переходите с черного на белый. Если у вас есть напротив поведения, вы либо захотите изучить min, либо если вы хотите, чтобы это было агностиком типа градиента, который вы испытываете, используйте max в сочетании с abs. Таким образом, когда мы находим самую большую разницу, это будет либо большое положительное число, если оно идет от черного до белого или большого отрицательного числа, если оно идет от белого к черному. Если мы удалим все отрицательные значения с abs, это означает, что независимо от того, что это за знак, мы увидим это как большое положительное значение, и поэтому мы сможем обнаружить скачок независимо. Поэтому то, что вы должны сделать, это:

[~,ind] = max(abs(diff(avgs))); 

Теперь, все, что вам нужно сделать, это показать это изображение, а затем построить линию, где это место находится по адресу:

figure; 
imshow(AR); 
hold on; 
plot([1 size(AR,2)], [ind ind], 'r', 'LineWidth', 2); 

Я сделал толщина линии 2 пикселя, чтобы вы могли четко видеть линию, и я сделал ее красным цветом. Это то, что мы получаем:

enter image description here


Поэтому, если вы хотите скопировать и вставить это в MATLAB для вас работать, вот код:

avgs = mean(AR(1:315,:), 2); 
[~,ind] = max(abs(diff(avgs)));  
figure; 
imshow(AR); 
hold on; 
plot([1 size(AR,2)], [ind ind], 'r', 'LineWidth', 2); 
+0

WOW! @rayryeng спасибо за помощь, это очень ценится! впечатляющий материал. –

+0

@ SeánMcNeill - проблем нет. Ta :) Продолжайте задавать вопросы и заботиться! – rayryeng

+0

@ SeánMcNeill - Я сделал код более простым для копирования и вставки в MATLAB. Я поместил весь код в один кусок в нижней части моего сообщения для вас. – rayryeng