How to create a vintage image in MATLAB?
Given a color image as input, I would like to overlay 3 images of the same size with the following colors: green, black, and blue.
For each of these images, I would like to change their opacity:
- Green = 40%
- Black = 43%
- Blue = 39%
Once I create these images, I would like to finally overlay the input image with 38% opacity. Can anyone please help? I would like to take an original image and apply this vintage effect using MATLAB.
source to share
I have never created sepia / vintage like effects on an image using the voids you are talking about. What I usually do for sepia / vintage images is to create the output red, green and blue components using a combination of the red, green and blue channels of the input image.
As you create sepia / vintage images this way use the following equations. Suppose your red, green and blue channels for your input image are stored in inputRed
, inputGreen
and inputBlue
respectively. These are the equations recommended by Microsoft :
outputRed = (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189)
outputGreen = (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168)
outputBlue = (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131)
Source: Tech Republic
outputRed
, outputGreen
, outputBlue
- This weekend the color channels to sepia / ancient image. So, just read on your image, then extract each of the color planes, do this weighted combination for each of the output color channels, and then merge the channels together. It should be noted that when reading from an image it will most likely be of type uint8
. To preserve precision when multiplying by decimal numbers, discard the before image before continuing double
. Once you calculate the sepia / crop you need to return the result to uint8
so you can display the image correctly as well as save it to disk. So here's the code:
im = double(imread('...')); % // Read in your image here inputRed = im(:,:,1); %// Extract each colour plane inputGreen = im(:,:,2); inputBlue = im(:,:,3); %// Create sepia tones for each channel outputRed = (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189); outputGreen = (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168); outputBlue = (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131); %// Create output image by putting all of these back into a 3D matrix %// and convert back to uint8 out = uint8(cat(3, outputRed, outputGreen, outputBlue)); figure; imshow(im,[]); %// Show original image figure; imshow(out); %// Show sepia image
Note that to create a 3D matrix again use cat
which combines the arrays / matrices in a given dimension. I have indicated the third dimension as we want to connect the red, green and blue channels together to form a 3D matrix. Then I returned the result uint8
.
Here's an example. I decided to take a family portrait from Jon Woodbury Photography . Those who appear here I don't know personally, but thanks for letting me use your photo, nonetheless :)
When I load this image then run the code with this image, this is the result I get:
Sidenote - efficiency
The above code is pretty much there. You can do it in two lines (three if you count the reading in the image as a step) if you want using a combination of permute
and reshape
. You will need to encapsulate the sepia coefficients in a 2D matrix, then you can calculate each output pixel as matrix multiplication. Thus:
im = double(imread('...')); %// Read in image
%// Define sepia matrix
M = [0.393 0.769 0.189; 0.349 0.686 0.168; 0.272 0.534 0.131];
out = uint8(reshape((M*reshape(permute(im, [3 1 2]), 3, [])).', ...
[size(im,1) size(im,2), 3]));
You should get the same output as in the previous version of the code! As a test, you provided an image in the comments below:
This is what I get from using the modified code (indeed, you will only get the same results as the first version of the code):
source to share