21 views (last 30 days)

Show older comments

I have some images that all overlap each other by a known amount (e.g. 15% of the pixels on along a side). No registration should be needed since I know exactly the overlap amout, i.e. placement. My method of merging them into a single image is by taking the ratio of the mean values of the images' overlapping regions and then correcting one of the images by that ratio. For example:

ratioAB = mean(matA_ovlap(:))/mean(matB_ovlap(:));

matB_new = matB*ratioAB;

This is better than simply piecing them together, but still clearly leaves a lot to be desired. See result below. Any recommendations for a more sophisticated blending?

DGM
on 14 Sep 2021

Edited: DGM
on 14 Sep 2021

This is a simple approach to doing edge-interpolation. This could also be done using interpolation tools in fewer lines, but right now I don't have the brain cells to spare in any effort to make this elegant. Just bear in mind that there's plenty of room for improvement. Anyone is free to post something better.

For this example, I'm going to use RGB color images. That might not be what you're using.

tiling = [3 3]; % image tiling [nup nacross]

overlap = [64 64]; % in pixels [rows cols]

% generate colored test images as a 4D RGB frame stack

% some of this uses MIMT; ignore that.

nframes = prod(tiling);

inpict = imread('cameraman.tif'); % raw single-channel source

A = zeros([imsize(inpict,2) 3 nframes]);

A(:,:,:,1) = repmat(im2double(inpict),[1 1 3]).*permute([1 0.3 0.8],[1 3 2]);

for f = 2:nframes

A(:,:,:,f) = imtweak(A(:,:,:,1),'lchab',[1 1 (f-1)/nframes]); % rotate hue

end

% do setup

overlap = round(overlap/2)*2; % make sure it's even

s0 = [size(inpict,1) size(inpict,2)]; % source frame geometry

st = 2*(s0-overlap) + (s0-2*overlap).*(tiling-2) + overlap.*(tiling-1); % output image geometry

myn = repmat(linspace(1,0,overlap(1)).',[1 s0(2)]); % transition masks

mys = repmat(linspace(0,1,overlap(1)).',[1 s0(2)]);

mxw = repmat(linspace(1,0,overlap(2)),[st(1) 1]);

mxe = repmat(linspace(0,1,overlap(2)),[st(1) 1]);

colpict = zeros([st(1) s0(2) size(A,3) tiling(2)]); % preallocate

outpict = zeros([st size(A,3)]);

% assemble the frames into columns

f = 1;

for n = 1:tiling(2)

for m = 1:tiling(1)

if m == 1

sr = s0(1)-overlap(1);

ry = 1:sr;

colpict(ry,:,:,n) = A(1:sr,:,:,f);

elseif m == tiling(1)

sr = s0(1)-overlap(1);

ry = ry(end)+1:ry(end)+sr;

colpict(ry,:,:,n) = A(overlap(1)+1:end,:,:,f);

else

sr = s0(1)-2*overlap(1);

ry = ry(end)+1:ry(end)+sr;

colpict(ry,:,:,n) = A(overlap(1)+1:overlap(1)+sr,:,:,f);

end

% insert transition

if m ~= tiling(1)

ry = ry(end)+1:ry(end)+overlap(1);

colpict(ry,:,:,n) = A(end-overlap(1)+1:end,:,:,f).*myn ...

+ A(1:overlap(1),:,:,f+1).*mys;

end

f = f+1;

end

end

% assemble the columns into an image

for n = 1:tiling(2)

if n == 1

sr = s0(2)-overlap(2);

rx = 1:sr;

outpict(:,rx,:) = colpict(:,1:sr,:,n);

elseif n == tiling(2)

sr = s0(2)-overlap(2);

rx = rx(end)+1:rx(end)+sr;

outpict(:,rx,:) = colpict(:,overlap(2)+1:end,:,n);

else

sr = s0(2)-2*overlap(2);

rx = rx(end)+1:rx(end)+sr;

outpict(:,rx,:) = colpict(:,overlap(2)+1:overlap(2)+sr,:,n);

end

% insert transition

if n ~= tiling(2)

rx = rx(end)+1:rx(end)+overlap(2);

outpict(:,rx,:) = colpict(:,end-overlap(2)+1:end,:,n).*mxw ...

+ colpict(:,1:overlap(2),:,n+1).*mxe;

end

end

clear colpict

In this example, each supercolumn of the image is assembled from single-source blocks and transition blocks betwen them. This takes up a lot of space with indexing, but the interpolation needs to be applied to the minimum number of pixels. The interpolation itself is a simple linear transition implemented with multiplicative composition using precalculated masks.

The supercolumns are assembled into the final image in a similar fashion.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!