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
, так что вы можете скопировать и вставить то, что я собираюсь попробовать следующий. Для полноты картины, это то, что изображение выглядит следующим образом:
Теперь вот где начинается волшебство. Найдем среднее значение каждой строки между строками 1 и 315:
avgs = mean(AR(1:315,:), 2);
Параметр 2
означает действовать по столбцам, а это значит, что мы найдем среднее значение каждой строки. Это означает, что мы получим вектор элемента 315, где каждый элемент равен в среднем строки .... так что первым элементом является среднее значение строки 1, второй элемент - это среднее значение строки 2 и т. Д. Если мы наносим эти средние на обычном участке, где номер строки является горизонтальной осью, а средняя интенсивность по вертикальной оси, это то, что мы получаем:
plot(1:315, avgs);
Как вы можете видеть , есть ясный всплеск на 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 пикселя, чтобы вы могли четко видеть линию, и я сделал ее красным цветом. Это то, что мы получаем:
Поэтому, если вы хотите скопировать и вставить это в 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);
Можете ли вы предоставить оригинал вместо снимка экрана? –
Почему бы вам просто не суммировать (или усреднить) по размеру 2, а затем найти большие изменения в профиле интенсивности? Кроме того, если вы просто хотите дать каждому региону среднее значение, вы можете посмотреть анизотропную диффузию, которая будет «гомогенизировать» регионы, оставив края неповрежденными. – Jonas