Seamless Cloning
This tutorial demonstrates how to use OpenCV seamless cloning module.
- Normal Cloning
- Mixed Cloning
- Monochrome Transfer
- Color Change
- Illumination change
- Texture Flattening
The program takes as input a source and a destination image (for first three methods) and outputs the cloned image.
Test images are downloaded from opencv_extra on Github.
Sources:
Contents
Test images
download required test images from Github
dirRoot = fullfile(mexopencv.root(), 'test', 'cloning'); dirs = { 'Normal_Cloning' 'Mixed_Cloning' 'Monochrome_Transfer' 'color_change' 'Illumination_Change' 'Texture_Flattening' }; imgs = { 'source1.png' 'mask.png' 'destination1.png' }; if ~isdir(dirRoot) mkdir(dirRoot); disp('Downloading images...') baseURL = 'https://cdn.rawgit.com/opencv/opencv_extra/3.2.0/testdata/cv/cloning/'; for i=1:numel(dirs) d = fullfile(dirRoot, dirs{i}); if ~isdir(d) mkdir(d); N = numel(imgs); if i > 3, N = N - 1; end for j=1:N f = fullfile(d, imgs{j}); if exist(f, 'file') ~= 2 url = [baseURL, dirs{i}, '/', imgs{j}] urlwrite(url, f); end end end end end
some options
opts = {'FlipChannels',true};
showPoint = @(I,p) cv.drawMarker(I, p, 'Color',[0 255 0], ...
'MarkerType','x', 'MarkerSize',30, 'Thickness',2, 'LineType','AA');Normal Cloning
src = imread(fullfile(dirRoot, dirs{1}, imgs{1}));
dst = imread(fullfile(dirRoot, dirs{1}, imgs{3}));
mask = imread(fullfile(dirRoot, dirs{1}, imgs{2}));
p = [400 100];
result = cv.seamlessClone(src, dst, mask, p, 'Method','NormalClone', opts{:});
figure('Name','Normal Cloning')
subplot(221), imshow(src), title('source')
subplot(222), imshow(showPoint(dst,p)), title('destination')
subplot(223), imshow(mask), title('mask')
subplot(224), imshow(result), title('cloned')
Mixed Cloning
src = imread(fullfile(dirRoot, dirs{2}, imgs{1}));
dst = imread(fullfile(dirRoot, dirs{2}, imgs{3}));
mask = imread(fullfile(dirRoot, dirs{2}, imgs{2}));
p = [size(dst,2) size(dst,1)]/2;
result = cv.seamlessClone(src, dst, mask, p, 'Method','MixedClone', opts{:});
figure('Name','Mixed Cloning')
subplot(221), imshow(src), title('source')
subplot(222), imshow(showPoint(dst,p)), title('destination')
subplot(223), imshow(mask), title('mask')
subplot(224), imshow(result), title('cloned')
Monochrome Transfer
src = imread(fullfile(dirRoot, dirs{3}, imgs{1}));
dst = imread(fullfile(dirRoot, dirs{3}, imgs{3}));
mask = imread(fullfile(dirRoot, dirs{3}, imgs{2}));
p = [size(dst,2) size(dst,1)]/2;
result = cv.seamlessClone(src, dst, mask, p, ...
'Method','MonochromeTransfer', opts{:});
figure('Name','Monochrome Transfer')
subplot(221), imshow(src), title('source')
subplot(222), imshow(showPoint(dst,p)), title('destination')
subplot(223), imshow(mask), title('mask')
subplot(224), imshow(result), title('cloned')
Color Change
src = imread(fullfile(dirRoot, dirs{4}, imgs{1}));
mask = imread(fullfile(dirRoot, dirs{4}, imgs{2}));
result = cv.colorChange(src, mask, 'R',1.5, 'G',0.5, 'B',0.5, opts{:});
figure('Name','Color Change')
subplot(221), imshow(src), title('source')
subplot(223), imshow(mask), title('mask')
subplot(224), imshow(result), title('cloned')
Illumination change
src = imread(fullfile(dirRoot, dirs{5}, imgs{1}));
mask = imread(fullfile(dirRoot, dirs{5}, imgs{2}));
result = cv.illuminationChange(src, mask, 'Alpha',0.2, 'Beta',0.4, opts{:});
figure('Name','Illumination change')
subplot(221), imshow(src), title('source')
subplot(223), imshow(mask), title('mask')
subplot(224), imshow(result), title('cloned')
Texture Flattening
src = imread(fullfile(dirRoot, dirs{6}, imgs{1}));
mask = imread(fullfile(dirRoot, dirs{6}, imgs{2}));
result = cv.textureFlattening(src, mask, ...
'LowThreshold',30, 'HighThreshold',45, 'KernelSize',3, opts{:});
figure('Name','Texture Flattening')
subplot(221), imshow(src), title('source')
subplot(223), imshow(mask), title('mask')
subplot(224), imshow(result), title('cloned')