Filter löschen
Filter löschen

Unable to get the output image for color transfer.

1 Ansicht (letzte 30 Tage)
N/A
N/A am 20 Mär. 2022
Kommentiert: DGM am 20 Mär. 2022
img_source = imread('boltr1.jpg');
img_target = imread('spring.jpg');
figure, imshow(img_source);
figure, imshow(img_target);
img_source_lab = rgb2lab(img_source);
img_target_lab = rgb2lab(img_target);
img_source_lab=padarray(img_source_lab,[1,1]);
img_target_lab=padarray(img_target_lab,[1,1]);
for i=1:209
for j = 2:315
for c= 1:3
temp = img_source_lab(:,:,c);
mean_source = mean(temp(i,[j,j+2]));
sd_source = std(temp(i,[j,j+2]));
temp = img_target_lab(:,:,c);
mean_target = mean(temp(i,[j,j+2]));
sd_target = std(temp(i,[j,j+2]));
img_source_lab(:,j+1,c) = (sd_target/sd_source)*(img_source_lab(:,j+1,c) - mean_source) + mean_target;
end
end
end
img_result = lab2rgb(img_source_lab);
figure, imshow(img_result,[]);

Antworten (1)

DGM
DGM am 20 Mär. 2022
Bearbeitet: DGM am 20 Mär. 2022
Again, you still haven't actually said what you are trying to do. I don't have your images either, so I can only guess how the dimensions relate.
Here's a guess.
img_source = imread('peppers.png');
img_target = fliplr(img_source);
figure, imshow(img_source);
figure, imshow(img_target);
img_source_lab = rgb2lab(img_source);
img_target_lab = rgb2lab(img_target);
img_source_lab=padarray(img_source_lab,[1,1]);
img_target_lab=padarray(img_target_lab,[1,1]);
sz = size(img_source);
for c = 1:sz(3) % process one channel at a time
% get the temporary copies once instead of tens of thousands of times
sourcechan = img_source_lab(:,:,c);
targetchan = img_target_lab(:,:,c);
for j = 2:sz(2)
% you were calculating mean,std elementwise,
% but assigning columnwise based on elementwise conditions
% i'm assuming this was a mistake and that
% elementwise conditions apply only locally
% in that case, this can be vectorized
sourcestripe = sourcechan(:,[j,j+2]);
targetstripe = targetchan(:,[j,j+2]);
mean_source = mean(sourcestripe,2);
sd_source = std(sourcestripe,0,2);
mean_target = mean(targetstripe,2);
sd_target = std(targetstripe,0,2);
img_source_lab(:,j+1,c) = (sd_target./sd_source).*(img_source_lab(:,j+1,c) - mean_source) + mean_target;
end
end
img_result = lab2rgb(img_source_lab);
img_result = im2uint8(img_result(2:end-1,2:end-1,:));
figure; imshow(img_result);
I don't know if that's what you want. The original indexing didn't seem plausible.
Why is it full of holes? That's what happens when sd_source is zero.
Can this be simplified further? Depends on if it's even doing what it's supposed to do.
  3 Kommentare
DGM
DGM am 20 Mär. 2022
Bearbeitet: DGM am 20 Mär. 2022
If this doesn't need recursion, then it simplifies:
img_source = imread('peppers.png');
img_target = fliplr(img_source);
figure, imshow(img_source);
figure, imshow(img_target);
img_source_lab = rgb2lab(img_source);
img_target_lab = rgb2lab(img_target);
img_source_lab = padarray(img_source_lab,[0,1]);
img_target_lab = padarray(img_target_lab,[0,1]);
sz = size(img_source);
output_lab = zeros(sz);
for j = 1:sz(2)
sourcestripe = img_source_lab(:,[j,j+2],:);
targetstripe = img_target_lab(:,[j,j+2],:);
mean_source = mean(sourcestripe,2);
sd_source = std(sourcestripe,0,2);
mean_target = mean(targetstripe,2);
sd_target = std(targetstripe,0,2);
output_lab(:,j,:) = (sd_target./sd_source).*(img_source_lab(:,j+1,:) - mean_source) + mean_target;
end
img_result = lab2rgb(output_lab);
figure; imshow(img_result);
This is basically a sliding window filter using a 1x3 filter window. This could also be done with nlfilter, though this is probably faster.
I don't see how the given formula will produce a transfer of color palette. You could think of the first term as the ratio of local contrast metrics. This is going to be a bunch of huge numbers from -Inf to Inf.
(sd_target./sd_source)
The second term is a pixels deviation from the local mean. This is going to be roughly within [-0.5 0.5] (projected back to RGB). The attached image is offset by 0.5 for viewing purposes.
(img_source_lab(:,j+1,:) - mean_source)
... and this is just the local mean in the same area of the target image.
mean_target
So you have the ratio of local contrasts (which is a wildly variable number) multiplied by the source deviation from its local mean (which is a generally small number with zero mean) and then you add the local mean of the target image (which is a very slightly blurred copy of the target). One would expect the result to essentially be a slightly blurred version of the target with erratic instances of huge/infinite values scattered about, and that's what we get.
If a process were to recolor an image based on another, it would need to discern some global color characteristics of the source image. Instead, this filter only operates on local information. It can't know anything about either image's color palette if it's only looking at three pixels.
DGM
DGM am 20 Mär. 2022
As an aside, MIMT has a crude recoloring tool, but I don't know that it's what you want.
ref = imread('peppers.png');
target = imread('llama.jpg');
montage({ref,target})
outpict = imrecolor(ref,target,'colormodel','hsly');
imshow(outpict)
And the opposite direction:
Image Analyst linked to a description of a far better method in his answer here:

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Image Processing Toolbox finden Sie in Help Center und File Exchange

Produkte


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by