Как найти наиболее плотные области изображения?
Рассмотрим черно-белое изображение, например this
![alt text]()
Я пытаюсь найти регион, где белые точки наиболее плотные. В этом случае имеется 20-21 таких плотных областей (т.е. Кластеры точек образуют плотную область).
Может ли кто-нибудь дать мне какой-нибудь намек на то, как это можно достичь?
Ответы
Ответ 1
Если у вас есть доступ к Image Processing Toolbox, вы можете воспользоваться рядом фильтрующих и морфологических операций, которые он содержит. Здесь вы можете подойти к своей проблеме, используя функции imfilter
, imclose
и imregionalmax
:
% Load and plot the image data:
imageData = imread('lattice_pic.jpg'); % Load the lattice image
subplot(221);
imshow(imageData);
title('Original image');
% Gaussian-filter the image:
gaussFilter = fspecial('gaussian', [31 31], 9); % Create the filter
filteredData = imfilter(imageData, gaussFilter);
subplot(222);
imshow(filteredData);
title('Gaussian-filtered image');
% Perform a morphological close operation:
closeElement = strel('disk', 31); % Create a disk-shaped structuring element
closedData = imclose(filteredData, closeElement);
subplot(223);
imshow(closedData);
title('Closed image');
% Find the regions where local maxima occur:
maxImage = imregionalmax(closedData);
maxImage = imdilate(maxImage, strel('disk', 5)); % Dilate the points to see
% them better on the plot
subplot(224);
imshow(maxImage);
title('Maxima locations');
И вот изображение, созданное кодом:
![введите описание изображения здесь]()
Чтобы все выглядело хорошо, я просто пытался попробовать несколько разных комбинаций параметров для фильтра Гаусса (созданного с помощью fspecial
) и структурирующий элемент (созданный с помощью strel
). Тем не менее, эта небольшая часть проб и ошибок дала очень хороший результат.
ПРИМЕЧАНИЕ. Изображение, возвращенное из imregionalmax
, не всегда имеет только один пиксель, установленный в 1 (для указания максимума). Выходное изображение часто содержит кластеры пикселей, поскольку соседние пиксели во входном изображении могут иметь одинаковые значения и поэтому считаются как максимальные. В приведенном выше коде я также расширил эти точки imdilate
, чтобы упростить их просмотр на изображении, что делает еще более крупный кластер пикселей с центром по максимумам. Если вы хотите уменьшить кластер пикселей до одного пикселя, вы должны удалить шаг дилатации и изменить изображение другими способами (добавьте шум к результату или отфильтруйте его, затем найдите новые максимумы и т.д.).
Ответ 2
если у вас есть панель инструментов обработки изображений, размыте ее с помощью гауссовского фильтра, а затем найдите пики/экстремумы.
изменяют размер гауссовского фильтра, чтобы получить количество "плотных" областей, которые вы хотите.
Ответ 3
Скользящее окно (простое, но медленное)
Вы можете создать скользящее окно (например, размер 10x10 пикселей), которое итератируется над изображением, и для каждой позиции вы подсчитываете количество белых пикселей в этом поле 10x10 и сохраняете позиции с наивысшим количеством отсчетов.
Весь этот процесс O (n * m), где n - количество пикселей изображения, а m - размер скользящего окна.
Другими словами, вы свернете изображение с означают фильтр (здесь фильтр коробки), а затем использовать экстремумы.
Скользящее окно (быстрое)
Сначала вычислите таблицу суммированных областей, которая может быть выполнена очень эффективно за один проход:
- создать 2D-массив
sat
с тем же размером, что и исходное изображение img
.
-
Итерации по каждому индексу и вычисления для каждого индекса x
и y
sat[x, y] = img[x, y] + sat[x-1, y] + sat[x, y-1] - sat[x-1, y-1]
Например, если изображение темное, а 1 - белое, это результат:
img sat
0 0 0 1 0 0 0 0 0 1 1 1
0 0 0 1 0 0 0 0 0 2 2 2
0 1 1 1 0 0 0 1 2 5 5 5
0 1 0 0 0 0 0 2 3 6 6 6
0 0 0 0 0 0 0 2 3 6 6 6
-
Теперь перебираем индексы таблицы суммированных областей с помощью скользящего окна и вычисляем количество белых пикселей в нем, используя углы A, B, C, D скользящего окна:
img sat window
0 0 0 1 0 0 0 0 0 1 1 1 0 A-----B 1
0 0 0 1 0 0 0 0 0 2 2 2 0 | 0 2 | 2
0 1 1 1 0 0 0 1 2 5 5 5 0 | 2 5 | 5
0 1 0 0 0 0 0 2 3 6 6 6 0 | 3 6 | 6
0 0 0 0 0 0 0 2 3 6 6 6 0 D-----C 6
Вычислить
density(x', y') = sat(A) + sat(C) - sat(B) - sat(D)
В приведенном выше примере
density(1, 0) = 0 + 6 - 1 - 2 = 3
Для этого процесса требуется временное изображение, но оно просто O (n), поэтому скорость не зависит от размера скользящего окна.
Ответ 4
Возможно наивный подход:
Вы определяете квадрат n * n, который является максимальным размером области, в которой вы измеряете плотность. Для каждой точки изображения вы рассматриваете точку как центр квадрата и подсчитываете количество черных (b) и белых (w) точек. Используя разницу b-w, вы можете определить, какой квадрат является самым белым.
Наиболее плотные области должны определяться нечетким образом. Если одна область имеет 600 белых точек и еще 599, то для человеческого глаза они имеют одинаковую плотность. 600 на 100% плотнее, а 599 - на 99% плотно и 1% не плотно. Используйте эпсилон для этого.
n может быть предопределен или основан на некоторой функции (т.е. в процентах от размера изображения).
Вы также можете использовать круг/эллипс вместо квадрата/прямоугольника. Выберите то, что лучше всего соответствует вашим потребностям