Color transfer of the source image according to the target image

3 views (last 30 days)
I want to color the white part of the `flare pattern` image, according to the color in `gt_000025.png`, because white balance needs to be considered, so the color transfer code used comes from color-transfer.
Now the problem is, I only want to color the white part in the `flare pattern`, the black background remains the same. And the picture I get when I run his code is `color pattern`. How would I go about coloring only the white parts? Any help would be greatly appreciated.

Accepted Answer

DGM
DGM on 14 Apr 2023
Edited: DGM on 14 Apr 2023
I am not familiar with the code in question, but if you want the output to have the same brightness as the input, then force it to be so.
uncolored = imread('flare pattern.png');
recolored = imread('color pattern.png');
% why does this image have extraneous padding?
recolored = recolored(2:end,2:end,:);
% do basic luma correction the hard way
ucycc = rgb2ycbcr(uncolored);
rcycc = rgb2ycbcr(recolored);
rcycc(:,:,1) = ucycc(:,:,1);
outpict = ycbcr2rgb(rcycc);
imshow([uncolored outpict],'border','tight')
Of course, it's not perfect due to the truncation raising black regions, but that's what you'll get with these tools. If you were doing chroma truncation, you'd get this instead:
Of course, it's basically impossible to see the difference against this awful white webpage.
As to why there's extraneous padding on your output image, if you're using saveas()/print()/exportgraphics()/getframe() to save images, dont. Save the actual image data with imwrite() instead of saving a screenshot with a bunch of random uncontrollable things being done to it in the process
  2 Comments
zzzj1208
zzzj1208 on 17 Apr 2023
Thank you very much for your reply. You cleared up my confusion to a large extent.
There is an emerging problem that I want to place the `color pattern` based on the position of the light source in `gt_000025.png`. The problem that arises is that when I add the two images, there is a clear boundary as indicated by the red box.
input_img = imread('gt_000025.png');
merge_img = 0.6*im2double(color_pattern) + im2double(input_img);
merge_img(merge_img<0) = 0;
merge_img(merge_img>1) = 1;
figure;
imshow(merge_img);
axis equal tight;
title('merge pattern');
So, in your solution, is it possible to set the background to black in the resulting `color pattern`? Or is there any operation to remove background of `color pattern`?
DGM
DGM on 17 Apr 2023
I'm not sure how accurate the results need to be here. I'm going to assume that this is more for visual purposes than anything strictly technical.
I see two basic approaches. You could either try to adjust the contrast to shift that background color toward black, or you can apply a soft vingette to the image so that its edges approach black.
I'm going to use MIMT tools for these examples, though this isn't necessary.
uncolored = imread('flare pattern.png'); % same images as before
recolored = imread('color pattern.png');
recolored = recolored(2:end,2:end,:); % trim padding
% do basic luma correction the easy way
% this is identical to the prior example
outpict = imblend(uncolored,recolored,1,'luma');
% generate a mask that selects the image edges
w = 10;
mk = zeros(size(uncolored,1:2)-2*w);
mk = padarray(mk,[w w],1,'both');
% find average color in the mask region
outpict = im2double(outpict);
meanedgecolor = sum(outpict.*mk,1:2)/nnz(mk);
meanedgecolor = max(meanedgecolor); % channelwise max
% rescale so that average color is black
outpict = imadjust(outpict,[meanedgecolor 1]);
imshow(outpict)
% create blended composite image
bg = imread('gt_000025.png');
ST = imstacker({outpict,bg},'padding',0,'offset',[15 -135; 0 0],'size','last');
blended = mergedown(ST,1,'lineardodge'); % 'linear dodge' is addition
imshow(blended)
Alternatively, you could apply vingetting to hide the transition while retaining central features.
% ...
% generate a soft mask
mk = radgrad(size(outpict),[0.5 0.5],1/(2*sqrt(2)),[255; 0],'linear');
mk = imadjust(mk,[0 0.5],[0 1],0.5); % adjust ease curve
% generate the output image by image blending
outpict = imblend(mk,outpict,1,'multiply');
% ...
As before, it's basically impossible to see the difference in edge effects against this white webpage, but the blended images do show that the transition isn't obvious anymore.
Note that the first example takes the average along an annular region, but the primary flare extends across this annulus. You can expect that the primary flare will still be nonzero at the edge. It may be worthwhile to employ both techniques (contrast adjustment followed by vingetting).
The vingetting could also be done in compositing instead of by applying it to the color channels of the overlaid image. I felt it was just easier this way.
imblend(), imstacker(), mergedown(), and radgrad() are from MIMT on the File Exchange. You're already doing the tasks that I did here with imstacker() and mergedown(), so you already know how to avoid those. The luma correction can be done without imblend() as shown prior. The soft mask can be generated any number of ways, either by creating a radial gradient, or by blurring a hard mask.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 17 Apr 2023
The best algorithm for gamut transfer is this:
Sorry, I don't have code for it.

Community Treasure Hunt

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

Start Hunting!