-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from TJCoding/master
Update to Address Issue #1
- Loading branch information
Showing
10 changed files
with
234 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
function [U_t,A_t] = MatchColumns(us,ut,at) | ||
% Ensures consistency between the target & source image rotation matrices. | ||
|
||
% This routine matches columns in the target image rotation matrix to those | ||
% in the source image rotation matrix. | ||
|
||
% Each rotation matrix is derived by undertaking a singular value | ||
% decomposition of the respective cross covariance matrices. The | ||
% outcome of the decomposition is ordered within the rotation matrix in | ||
% the order of the descending singular values. This often leads to | ||
% compatible rotation matrices but that is not guaranteed. Sometimes the | ||
% colour ordering of one rotation matrix may be different from the other. | ||
% | ||
% Additionally even when the matrices do correspond in orientation, they | ||
% need not correspond in direction. The direction axis rotation in one | ||
% matrix may be the negative of the rotation in the other. | ||
|
||
% Rotations of the individual colour axes are given by the columns of the | ||
% rotation matrices. In the following processing, all rearrangements are | ||
% considered of the columns in the target rotation matrix 'ut', to find | ||
% the arrangement that best matches the source rotation matrix 'us'. | ||
% Matching is measured by taking the vector dot products of the | ||
% corresponding matrix columns and finding the arrangement with the | ||
% largest sum of absolute dot product values. Absolute values are used | ||
% to accommodate axis pairs that have similar orientations but different | ||
% directions. | ||
% | ||
% Once the best match has been found this is taken as the correct target | ||
% image rotation matrix. Columns are negated where the vector cross | ||
% product has a negative value, to ensure direction compatibility. The | ||
% singular value matrix for the target image is reordered to match the | ||
% reordering of the rotation matrix. | ||
% | ||
% This processing method and routine copyright Dr T E Johnson 2020. | ||
% terence.johnson@gmail.com | ||
|
||
% All 6 permutations of the three columns need to be addressed. | ||
perm = perms([1 2 3]); | ||
|
||
max=0.0; | ||
|
||
for i=1:6 | ||
% Compute the sum of the absolute dot products for the matrix columns. | ||
sum=abs(ut(:,perm(i,1)).'*us(:,1)) + ... | ||
abs(ut(:,perm(i,2)).'*us(:,2)) + ... | ||
abs(ut(:,perm(i,3)).'*us(:,3)) ; | ||
|
||
if(sum>max) | ||
% Best aligned axes give the biggest sum. | ||
max=sum; | ||
bestperm=i; | ||
end | ||
end | ||
% Now recover the best permutation and implement it. | ||
b1=perm(bestperm,1); | ||
b2=perm(bestperm,2); | ||
b3=perm(bestperm,3); | ||
|
||
% Set the rotation matrix columns to the new order, changing the | ||
% direction of rotations if necessary by negating column values. | ||
U_t(:,1)=ut(:,b1)*sign(ut(:,b1).'*us(:,1)); | ||
U_t(:,2)=ut(:,b2)*sign(ut(:,b2).'*us(:,2)); | ||
U_t(:,3)=ut(:,b3)*sign(ut(:,b3).'*us(:,3)); | ||
|
||
% Similarly reorder the singular values. | ||
A_t(1,1)=at(b1,b1); | ||
A_t(2,2)=at(b2,b2); | ||
A_t(3,3)=at(b3,b3); | ||
end | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
function [U_t,A_t] = MatchColumns(us,ut,at) | ||
% Ensures consistency between the target & source image rotation matrices. | ||
|
||
% This routine matches columns in the target image rotation matrix to those | ||
% in the source image rotation matrix. | ||
|
||
% Each rotation matrix is derived by undertaking a singular value | ||
% decomposition of the respective cross covariance matrices. The | ||
% outcome of the decomposition is ordered within the rotation matrix in | ||
% the order of the descending singular values. This often leads to | ||
% compatible rotation matrices but that is not guaranteed. Sometimes the | ||
% colour ordering of one rotation matrix may be different from the other. | ||
% | ||
% Additionally even when the matrices do correspond in orientation, they | ||
% need not correspond in direction. The direction axis rotation in one | ||
% matrix may be the negative of the rotation in the other. | ||
|
||
% Rotations of the individual colour axes are given by the columns of the | ||
% rotation matrices. In the following processing, all rearrangements are | ||
% considered of the columns in the target rotation matrix 'ut', to find | ||
% the arrangement that best matches the source rotation matrix 'us'. | ||
% Matching is measured by taking the vector dot products of the | ||
% corresponding matrix columns and finding the arrangement with the | ||
% largest sum of absolute dot product values. Absolute values are used | ||
% to accommodate axis pairs that have similar orientations but different | ||
% directions. | ||
% | ||
% Once the best match has been found this is taken as the correct target | ||
% image rotation matrix. Columns are negated where the vector cross | ||
% product has a negative value, to ensure direction compatibility. The | ||
% singular value matrix for the target image is reordered to match the | ||
% reordering of the rotation matrix. | ||
% | ||
% This processing method and routine copyright Dr T E Johnson 2020. | ||
% terence.johnson@gmail.com | ||
|
||
% All 6 permutations of the three columns need to be addressed. | ||
perm = perms([1 2 3]); | ||
|
||
max=0.0; | ||
|
||
for i=1:6 | ||
% Compute the sum of the absolute dot products for the matrix columns. | ||
sum=abs(ut(:,perm(i,1)).'*us(:,1)) + ... | ||
abs(ut(:,perm(i,2)).'*us(:,2)) + ... | ||
abs(ut(:,perm(i,3)).'*us(:,3)) ; | ||
|
||
if(sum>max) | ||
% Best aligned axes give the biggest sum. | ||
max=sum; | ||
bestperm=i; | ||
end | ||
end | ||
% Now recover the best permutation and implement it. | ||
b1=perm(bestperm,1); | ||
b2=perm(bestperm,2); | ||
b3=perm(bestperm,3); | ||
|
||
% Set the rotation matrix columns to the new order, changing the | ||
% direction of rotations if necessary by negating column values. | ||
U_t(:,1)=ut(:,b1)*sign(ut(:,b1).'*us(:,1)); | ||
U_t(:,2)=ut(:,b2)*sign(ut(:,b2).'*us(:,2)); | ||
U_t(:,3)=ut(:,b3)*sign(ut(:,b3).'*us(:,3)); | ||
|
||
% Similarly reorder the singular values. | ||
A_t(1,1)=at(b1,b1); | ||
A_t(2,2)=at(b2,b2); | ||
A_t(3,3)=at(b3,b3); | ||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
function est_im = cf_Xiao06(source,target) | ||
%CF_XIAO computes Reinhard's image colour transfer | ||
% | ||
% CF_XIAO(SOURCE,TARGET) returns the colour transfered source | ||
% image SOURCE according to the target image TARGET. | ||
% | ||
|
||
% References: | ||
% Xiao, Xuezhong, and Lizhuang Ma. "Color transfer in correlated color | ||
% space." % In Proceedings of the 2006 ACM international conference on | ||
% Virtual reality continuum and its applications, pp. 305-309. ACM, 2006. | ||
|
||
% TODO: Swatch-based transfer is not implemented (but I think it is not | ||
% important) Anyone interested is welcome to contribute. :-) | ||
% -- Han Gong | ||
|
||
% Copyright 2015 Han Gong <gong@fedoraproject.org>, University of East | ||
% Anglia. | ||
|
||
rgb_s = reshape(im2double(source),[],3)'; | ||
rgb_t = reshape(im2double(target),[],3)'; | ||
|
||
% compute mean | ||
mean_s = mean(rgb_s,2); | ||
mean_t = mean(rgb_t,2); | ||
|
||
% compute covariance | ||
cov_s = cov(rgb_s'); | ||
cov_t = cov(rgb_t'); | ||
|
||
% decompose covariances | ||
[U_s,A_s,~] = svd(cov_s); | ||
[U_t,A_t,~] = svd(cov_t); | ||
|
||
%********************************************************** | ||
% Processing modification by T E Johnson. | ||
% Set true (default) to implement ruggedisation processing. | ||
% Set false for standard (original) processing. | ||
ruggedisation=true; | ||
|
||
if (ruggedisation) | ||
[U_t,A_t]=MatchColumns(U_s,U_t,A_t); | ||
end | ||
%********************************************************** | ||
|
||
rgbh_s = [rgb_s;ones(1,size(rgb_s,2))]; | ||
|
||
% compute transforms | ||
% translations | ||
T_t = eye(4); T_t(1:3,4) = mean_t; | ||
T_s = eye(4); T_s(1:3,4) = -mean_s; | ||
% rotations | ||
R_t = blkdiag(U_t,1); R_s = blkdiag(inv(U_s),1); | ||
% scalings | ||
% NOTE! | ||
% I believe the author has a typo in his original paper | ||
% The following is the original way to compute S_t, but | ||
% the result does not seem correct | ||
% S_t = diag([diag(A_t);1]); | ||
% I added a 0.5 power to correct it. | ||
S_t = diag([diag(A_t).^(0.5);1]); | ||
S_s = diag([diag(A_s).^(-0.5);1]); | ||
|
||
rgbh_e = T_t*R_t*S_t*S_s*R_s*T_s*rgbh_s; % estimated RGBs | ||
rgbh_e = bsxfun(@rdivide, rgbh_e, rgbh_e(4,:)); | ||
rgb_e = rgbh_e(1:3,:); | ||
|
||
est_im = reshape(rgb_e',size(source)); | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
% Demonstration of Xiao's Image Colour Transfer | ||
|
||
% Copyright 2015 Han Gong <gong@fedoraproject.org>, University of East | ||
% Anglia. | ||
|
||
% Now ruggedised by T E Johnson (April 2020) to ensure consistent | ||
% processing. | ||
|
||
% References: | ||
% Xiao, Xuezhong, and Lizhuang Ma. "Color transfer in correlated color | ||
% space." % In Proceedings of the 2006 ACM international conference on | ||
% Virtual reality continuum and its applications, pp. 305-309. ACM, 2006. | ||
|
||
I0 = im2double(imread('4.jpg')); | ||
I1 = im2double(imread('3.jpg')); | ||
|
||
IR = cf_Xiao06(I0,I1); | ||
|
||
figure; | ||
subplot(1,3,1); imshow(I0); title('Original Image'); axis off | ||
subplot(1,3,2); imshow(I1); title('Target Palette'); axis off | ||
subplot(1,3,3); imshow(IR); title('Result After Colour Transfer'); axis off |