Code covered by the BSD License  

Highlights from
Images blending/mixture/photomontage

image thumbnail
from Images blending/mixture/photomontage by Nikolay S.
Combine images together in a photomontage style.

imagesMixture(mainImg, blendImg, coords, varargin)
function mixedImg= imagesMixture(mainImg, blendImg, coords, varargin)
%% imagesMixture
% Combine images together in a photomontage style.
%
%% Syntax
%  mixedImg= imagesMixture(mainImg, blendImg, coords);
%  mixedImg= imagesMixture(mainImg, blendImg, coords, 'coordsMode', coordsMode);
%  mixedImg= imagesMixture(mainImg, blendImg, coords, 'coordsMode', coordsMode, 'opacity', opacity);
%  mixedImg= imagesMixture(mainImg, blendImg, coords, 'coordsMode', coordsMode, 'opacity', opacity, 'blendMask', blendMask);
%
%% Description
% This is a small function designed to enter a small image, onto a bigger one. it can be
%  handy in several cases- both for images and especially for videos (perhaps I'll write a
%  wrapper function for video later on). It can be used for hiding an object (like faces
%  of persons interested in staying anonymous). Another option is water marking.
%  Annotation, and image/video editing is also an option- adding an object to an existing
%  image. The function receives a main- tile image, and a smaller image subject to
%  insertion. The user specifies the inserted image position, the part of the image to be
%  inserted, the way coordinates should be treated, and the opacity value. Image mixture
%  is generated according to the above parameters, and the new image is returned.
%
%% Input arguments (defaults exist):
%   mainImg-    the main/tile image subject to blending/ images mixture. Expected to be of
%        dimensions higher or equal to blendImg dimensions.
%   blendImg-     the image added (or blended into) mainImg. Expected to be of smaller or
%        eqaul dimensions of mainImg.
%   coords-      [row, column] 
%                 [], will cause generation of automated name.
% ---Optional parameters-----------------------------------------------
%   coordsMode-   a string {['Center'], 'TopLeft', 'BottomRight'} defining how the coords
%     are trerated- what should lie there blendImg Center, TopLeft or BottomRight corner?
%     Default value is 'Center'.
%   opacity- a double value [0:1] determines the images ratio in the support area.
%        Default is 1- complete blending- mainImg is totally faced by blendImg.
%   blendMask-     a matrix of logicals, of same dimensions as blendImg. Determines the
%        region of blendImg subject of blending- default is a matrix of tue's- whole
%        blending.
%
%% Output arguments
%   mixedImg- a matrix representing an image, of same type and size as mainImg, with
%        blendImg merged with it at appropriate position and opacity.
%
%% Issues & Comments
%
%% Example I
% mainImg=imread('cameraman.tif');
% subImg=mainImg(185:220, 100:120);
% mixedImg= imagesMixture(mainImg, subImg, [10, 40], 'opacity', 1, 'coordsMode', 'TopLeft');
% figure;
% subplot(1, 2, 1)
% imshow(mainImg);
% hold on;
% hndl=rectangle('Position',[100, 185, size(subImg, 2), size(subImg, 1)], 'EdgeColor', 'r');
% hold off;
% title('Original Image');
% 
% subplot(1, 2, 2)
% imshow(mixedImg);
% title('Mixed Image');
%
%% Example II
% matlabVfile='rhinos.avi'; % 'xylophone.mpg'; % no other input video files in Matlab default path was found
% peppersImg=imread('peppers.png');
% subImg=peppersImg(130:205, 85:190, :);
% redPepperMask=subImg(:,:,1)>100 & subImg(:,:,1)<190 & subImg(:,:,2)<100;
% outVideoInsterObj=apply2VideoFrames('inVideo', matlabVfile,...
%   'hAppliedFunc',@imagesMixture, 'outVideoFile', 'hardMix', 'PARAMS',...
%   subImg, [40, 38], 'blendMask', redPepperMask);
% implay(outVideoInsterObj);
% outVideoWaterMark=apply2VideoFrames('inVideo', matlabVfile,...
%   'hAppliedFunc',@imagesMixture, 'outVideoFile', 'waterMark', 'PARAMS',...
%    subImg, [40, 38], 'opacity', 0.6);
% implay(outVideoWaterMark);
% implay(matlabVfile);

%
%% See also
% - imcrop
% - apply2VideoFrames
% - rectangle
%
%% Revision history
% First version: Nikolay S. 2012-05-16.
% Last update:   Nikolay S. 2012-05-21.
%
% *List of Changes:*
% 2012-05-21- A few bugs fixed.
%

%% Default parameters
coordsMode='Center';
opacity=1;
blendMask=[];

%% Load uses params, overifding default ones
if nargin>4
    for iArg=1:2:length(varargin) % automatically get all input pairs and store in local vairables
        %         eval([varargin{iArg},'=varargin{iArg+1};']);  % TODO get read of EVAL.
        assignin_value(varargin{iArg},varargin{iArg+1});
    end
end

%% Bring blended images to commmon color space
mainImgClass=class(mainImg);
mainImgDims=size(mainImg);
if length(mainImgDims)<3
   mainImgDims(3)=1;
end

blendImgDims=size(blendImg);
if length(blendImgDims)<3
   blendImgDims(3)=1;
end

if isempty(blendMask)
    blendMask=true( blendImgDims );
end

% Make both images to be of same type- RGB or GrayScale
if mainImgDims(3)~=blendImgDims(3)
   if mainImgDims(3) > blendImgDims(3)
      blendImg=repmat( blendImg, [1, 1, mainImgDims(3)] );
   else
      blendImg=rgb2gray(blendImg);
   end
   blendImgDims(3)=mainImgDims(3);
end

if size(blendMask, 3) < blendImgDims(3)
   blendMask=repmat(blendMask, [1, 1, blendImgDims(3)]);
end

%% calculate the blending coordinates
%rect=cat(2, NaN(1,2), blendImgDims(2), blendImgDims(1));
switch( upper(coordsMode) )
   case( upper('TopLeft') )
      modeG=0;
   case( upper('BottomRight') )
      modeG=1;
   otherwise
      modeG=1/2;
end
rowMin=round( coords(1)-modeG*blendImgDims(1) );
colMin=round( coords(2)-modeG*blendImgDims(2) );

%% verify rect values are legal
% Left Top point is inside mainImgDims
rowMin=max(1, rowMin);
colMin=max(1, colMin);
rowMin=min(rowMin, mainImgDims(1));
colMin=min(colMin, mainImgDims(2));

% Rigth Bottom point is inside mainImgDims
rowMax=rowMin+blendImgDims(1)-1;
rowMax=min(rowMax, mainImgDims(1));
colMax=colMin+blendImgDims(2)-1;
colMax=min(colMax, mainImgDims(2));

% If rect was reduced- crop blendImg, blendMask accourdingly
blendImg=blendImg(1:(1+rowMax-rowMin), 1:(1+colMax-colMin), :);
blendMask=blendMask(1:(1+rowMax-rowMin), 1:(1+colMax-colMin), :);

% Preapre insetred image
subImg=mainImg( rowMin:rowMax, colMin:colMax, : );
blendSubImg=double(subImg);
% Blend images
blendSubImg(blendMask)=(1-opacity)*blendSubImg(blendMask)+opacity*double(blendImg(blendMask));

% Return output of same type as input
if ~strcmpi(mainImgClass, 'double')
   blendSubImg=cast(blendSubImg, mainImgClass);
end

mixedImg=mainImg;

mixedImg( rowMin:rowMax, colMin:colMax, : )=blendSubImg;

Contact us