Detect repetitive pixel patterns in an image and remove them using matlab

冷暖自知 提交于 2019-12-06 14:46:35

Two methods are proposed, one using cross correlation the other using brightness. They work with both grayscale and multiband images. You should play with the settings a bit to improve the result.

Important: fillmissing requires Matlab 2016b or newer

Method A) Using cross correlation

This works by extracting a single occurrence of the pattern and finding the location on the images where the correlation is very high. While it provides better results than Method B, it is also more complicated and needs a bit more knowledge about what you are doing:

I = double(yourimage);
% Show image
imagesc(I)
% You have to select a part of single occurrence of the pattern (a template) on the image! See below image.
rect = round(getrect);
% In case it is a multiband image make grayscale image
if size(I,3)>1
    BW = rgb2gray(I);
else
    BW = I;
end
% Extract template from BW
template = BW(rect(2):rect(2)+rect(4),rect(1):rect(1)+rect(3),:);
% Show template - this is the extent you selected during "getrect"
imagesc(template)

% Calculate how much said template correlates on each pixel in the image
C = normxcorr2(template,BW);
% Remove padded borders from correlation
pad = floor(size(template)./2);
center = size(I);
C = C([false(1,pad(1)) true(1,center(1))], ...
        [false(1,pad(2)) true(1,center(2))]);
% Plot the correlation
figure, surf(C), shading flat

Correlation of the template on the image. Note that it both highly correlates with the bright yellow patterns and the light blue pattern bellow.

% Get all indexes where the correlation is high. Value read from previous figure.
% The lower the cut-off value, the more pixels will be altered
idx = C>0.5;
% Dilate the idx because else masked area is too small
idx = imdilate(idx,strel('disk',1));
% Replicate them if multiband image. Does nothing if only grayscale image
idx = repmat(idx,1,1,size(I,3));
% Replace pattern pixels with NaN
I(idx) = NaN;
% Fill Nan values with 4x4 median filter
I = fillmissing(I,'movmedian',[4 4]);
% Display new image
figure; imagesc(I)

It catches both the yellow and light blue pattern but also some false positives. You have to experiment with different templates, cut-off values, dilation radii and median filter sizes to improve the result.

Method B) Using brightness of image

A bit offtopic because no pattern recognition is used but instead that the yellow patterns are just very bright. But since the result isn't too bad and a lot simpler I felt it might be useful. A lot easier to avoid finding false positives.

% I = your image
I = double(I);

% get indexes where very bright in red channel
idx = cdata(:,:,1)>157; % 157 = brightest non-pattern pixel in your image

% From now on same as end from method A)!
% dilate the idx to also get the adjacent pixels because else too few pixels will be erased
idx = imdilate(idx,strel('disk',1));
% replacate them if multiband image. Does nothing if only grayscale image
idx = repmat(idx,1,1,size(I,3));
% replace pattern pixels with NaN
I(idx) = NaN;
% fill Nan values using 50x50 median filter
I = fillmissing(I,'movmedian',[50 50]);
% display new image
figure; imagesc(I)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!