Убрать дыры в изображении по средним значениям окружающих пикселей

Серое изображение с отверстиями

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

3 ответа

Решение

Существует файл обмена файлами Matlab, - inpaint_nans, который делает именно то, что вы хотите. Автор объясняет, почему и в каких случаях это лучше, чем триангуляция Делоне.

Хороший способ сделать это - решить линейное уравнение теплопроводности. Что вы делаете, это фиксируете "температуру" (интенсивность) пикселей в хорошей области и позволяете тепловому потоку попадать в плохие пиксели. Сносно, но несколько медленно, было сделать это многократно усреднить изображение, а затем установить хорошие пиксели обратно к их первоначальному значению с помощью newImage(~badPixels) = myData(~badPixels);,

Я делаю следующие шаги:

  1. Найдите плохие пиксели, где изображение равно нулю, а затем увеличьте их, чтобы убедиться, что мы получили все
  2. Примените эффект размытия, чтобы мы начали быстрее
  3. Усредните изображение, затем установите хорошие пиксели обратно в исходное
  4. Повторите шаг 3
  5. дисплей

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

Код выглядит следующим образом:

numIterations = 30;
avgPrecisionSize = 16; % smaller is better, but takes longer

% Read in the image grayscale:
originalImage = double(rgb2gray(imread('c:\temp\testimage.jpg')));

% get the bad pixels where  = 0 and dilate to make sure they get everything:
badPixels = (originalImage == 0);
badPixels = imdilate(badPixels, ones(12));

%# Create a big gaussian and an averaging kernel to use:
G = fspecial('gaussian',[1 1]*100,50);
H = fspecial('average', [1,1]*avgPrecisionSize);

%# User a big filter to get started:
newImage = imfilter(originalImage,G,'same');
newImage(~badPixels) = originalImage(~badPixels);

% Now average to
for count = 1:numIterations
   newImage = imfilter(newImage, H, 'same');
   newImage(~badPixels) = originalImage(~badPixels);
end

%% Plot the results
figure(123);
clf;

% Display the mask:
subplot(1,2,1);
imagesc(badPixels);
axis image
title('Region Of the Bad Pixels');

% Display the result:
subplot(1,2,2);
imagesc(newImage);
axis image
set(gca,'clim', [0 255])
title('Infilled Image');

colormap gray

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

newImage2 = roifill(originalImage, badPixels);

figure(44);
clf;
imagesc(newImage2);
colormap gray

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

Чтобы заполнить одну черную область, сделайте следующее:

1) Определите субрегион, содержащий черную область: чем меньше, тем лучше. В лучшем случае это просто граничные точки черной дыры.

2) Создайте триангуляцию Делоне для не черных точек внутри субрегиона с помощью:

 tri = DelaunayTri(x,y); %# x, y (column vectors) are coordinates of the non-black points.

3) Определить черные точки треугольника Делоне по:

[t, bc] = pointLocation(tri, [x_b, y_b]); %# x_b, y_b (column vectors) are coordinates of the black points
tri = tri(t,:);

4) Интерполировать:

v_b = sum(v(tri).*bc,2); %# v contains the pixel values at the non-black points, and v_b are the interpolated values at the black points.
Другие вопросы по тегам