Reputation: 65
I have been assigned recently a task related to image processing. The thing is that I have no prior experience to this subject so I face some difficulties.
The concept is to create a 3D image from a 2D image by initially extracting the R,G,B components and combine them after shifting the red one according to some sort of a formula (i.e. calculate the pixel which has to be shifted by applying the formula a = x(i,j,k)*40/max(Rcomponent(:))
to each element of the red image and replace element x(i,j-a,k)
by the value of x(i,j,k))
.
Here is my current progress:
original = imread(nameofimag); % read file
imaginfos = imfinfo(nameofimag); % identify colortype
coltype = imaginfos(1).ColorType;
truecol = 'truecolor';
if strcmp(coltype,truecol) == 1 % convert to grayscale if needed
originalgray = rgb2gray(original);
else
originalgray = original;
end
Z = zeros(size(originalgray,1),size(originalgray,2));
% create red, blue, green parts
imagR = cat(3,originalgray,Z,Z);
imagG = cat(3,Z,originalgray,Z);
imagB = cat(3,Z,Z,originalgray);
imagRshifted = zeros(size(originalgray,1),size(originalgray,2));
h = waitbar(0,'Please wait...');
% shift red image
for i = 1:size(imagR,1)
for j = 1:size(imagR,2)
for k = 1:size(imagR,3)
imagRshifted(i,j,k) = imagR(i,j,k);
pixeltochange = round((imagRshifted(i,j,k)*40)...
/max(original(:)));
if pixeltochange < j
imagRshifted(i,j-pixeltochange,k) =...
imagRshifted(i,j,k);
end
end
end
waitbar(i/size(imagR,1));
end
imagRshifted = uint8(imagRshifted);
% combine R,G,B to create 3D image
imag3D = imfuse(imagRshifted,imfuse(imagG,imagB));
% plot the desired images
if depictrgb == 0;
figure;imshow(imag3D);
else
figure;imshow(imag3D);
figure;imshow(imagR);
figure;imshow(imagB);
figure;imshow(imagG);
end
close(h);
end
As you can see the result is quite confusing (at least to me). At first there is a line splitting the final image in two parts (it seems like the formula has been applied only on the left part of the line leaving the right part untouched). Additionally the produced image is more like a reconstruction of random pixels rather than a combination of the R,G,B components.
Any ideas would be more than appreciated.
Thank you in advance.
Upvotes: 0
Views: 448
Reputation: 35525
My friend, you have 2 main problems: You don't know exactly what you are doing and you are using Matlab extremely inefficiently.
So lets go to what you need, and how to do it.
You described your problem relatively OK. Lets re-describe it.
Starting from a grayscale image, create a color image with the red channel shifted by an amount given by the following equation: shift = x_ij*40/max(x(:))
.
There are missing things here, like: what to do if the shift goes out of the image? In this case we will assume that if the shift is too big, then make it zero.
lets start: First we are going to load an image, and if it is not grayscale, convert it to grayscale. I am using the following image:
% // same as you had
nameofimag='https://2.bp.blogspot.com/-db3zQg7geYA/UYqnvBriBeI/AAAAAAAAAHo/cv3Dy40mUFo/s1600/Meteosat_grid.jpg'
original = imread(nameofimag); % read file
imaginfos = imfinfo(nameofimag); % identify colortype
coltype = imaginfos(1).ColorType;
truecol = 'truecolor';
if strcmp(coltype,truecol) == 1 % convert to grayscale if needed
originalgray = rgb2gray(original);
else
originalgray = original;
end
Now we want to compute the shift per pixel we can do that in one line:
% compute shifts
shift=-round( double(originalgray) *40./double(max(originalgray(:))));
And we want to make sure that we don't go over the iamge, so we will compute the actual index (indY+shift) and check if that's inside the image
% get indexes
[indY,~]=meshgrid(1:size(originalgray,2),1:size(originalgray,1));
% Make sure we dont go out of the image
shift(indY+shift<=0)=0;
Now we have a proper shift, that we know its not going out. Realize, shift is a matrix size(image)
, thus we have all we need.
Now, lets take the R channel and shift it. Realize, that the image is grayscale, thus R G and B are exactyl equal. we will then shift the original image.
% allocate memory
redshifted = zeros(size(originalgray,1),size(originalgray,2));
% actually shift red
for ii=1:size(originalgray,1)
redshifted(ii,:)=originalgray(ii,indY(ii,:)+shift(ii,:));
end
Now that we have the red shifted, lets create a new image, that has RGB values, where GB are the original image and R the shifted image
colorImg=cat(3,redshifted,originalgray,originalgray);
imshow(colorImg)
This gives:
Conclusion: This code applies the shift to a grayscale image (or truecolor converted to grayscale) and generates a color image with the red shifted. Modifications need to be done if the original image is actually truecolor without the grayscale conversion, but these modifications will be minor, and mainly relate to changing originalgray
in different places to proper RGB chanel access (e.g. original(:,:,2)
is G).
As a final note: Realise that this will only look good with 3D glasses if the image is a depthmap. Else, you will get weird visual effect, as the color of an image has nothing to do with the depth of it (thus displacement of red)
Upvotes: 2