Who know how to do this interpolation problem

Image processing. Write a function to display a color image, as well as its red, green, and blue layers separately. The function declaration should be im=displayRGB(filename). filename should be the name of the image (make the function work for *.jpg images only). imshould be the final image returned as a matrix. To test the function, you should put a jpg file into the same directory as the function and run it with the filename (include the extension, for example im=displayRGB(‘testImage.jpg’)). You can use any picture you like, from your files or off the internet. Useful functions: imread, meshgrid, interp2, uint8, image, axis equal, axis tight.
a.
To make the program work efficiently with all image sizes, first interpolate each color layer of the original image so that the larger dimension ends up with 800 pixels. The smaller dimension should be appropriately scaled so that the length:width ratio stays the same. Use interp2 with cubic interpolation to resample the image.
b.
Create a composite image that is 2 times as tall as the original, and 2 times as wide. Place the original image in the top left, the red layer in the top right, the green layer in the bottom left, and the blue layer in the bottom right parts of this composite image. The function should return the composite image matrix in case you want to save it as a jpg again (before displaying or returning, convert the values to unsigned 8-bit integers using uint8). Hint: To get just a single color layer, all you have to do is set the other two layers to zero. For example if X is an MxNx3 image, then X(:,:,2)=0; X(:,:,3)=0; will retain just the red layer. Include your code and the final image in your homework writeup.
I am a self-taught beginner. And the material I use does not specifically talk about the like "pixels' or how to interpolate each color layer of the original picture, it is focused more on the algebra calculation. Thus, I have no idea at all for this question. Can someone help me? Thanks a lot!

 Accepted Answer

I don't agree with the way your instructor told you to get just a single color layer. Setting other color layers to zero leaves it a color image. Use this code to extract just a single color channel:
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
Aren't there examples for interp2() in the help that you can look at?

10 Comments

I type "help interp2" in my matlab and know a few things about that.But like for this question, what should I plog in for those five parameters, x,y,z,x1,y1, I have no idea.I thought I may need to extract "something"(i.e dimension?, I do not know the terminology) from the original picture and make them as x,y. And I create x1,y1, which has a 800 pixels in the large dimension and some matched pixels in the small dimension. That is all in my mind right now in terms of this question
x, y are the existing (column, row) coordinates. z are the existing intensity values at those coordinates. xi and yi are the new coordinates that you'd like to estimate/interpolate/extract (whatever you want to call it) the unknown intensity values from. It returns those intensity values as zi. Make sense now? If not, then just use imresize().
I got it.Thanks.But how could I extract x,y(existing column and row) from the original picture? Also, the 800 pixels here means I need to set x1 as 800?
Use
numrow = size(YourImage,1);
numcol = size(YourImage,2);
x = 1 : numrow;
y = 1 : numcol;
xi = linspace(1, numrow, 800);
yi should also be created using linspace(), but you need to figure out the number of pixels width the new image will have when you use the same aspect ratio as in the original image.
Did you see the help for interp2? If your input data is a full 2D image, then you can get x and y from meshgrid, which basically gives you every single (x,y) coordinate pair in the entire image. But in general I think x and y don't have to be complete - you just give it whatever you have. Similarly you get xi and yi from meshgrid so that you get every single (x,y) coordinate from the desired 800 pixel wide output image. Walter gave you a start - just pass his xi and yi into meshgrid to get the final xi and yi that you need to pass into interp2().
The x and y do not have to be from meshgrid. This is not clearly documented, but is hinted by the documentation for one of the forms:
ZI = interp2(Z,XI,YI) assumes that X = 1:n and Y = 1:m, where [m,n] = size(Z).
What is documented is that xi and yi do not need to be from meshgrid either:
XI and YI can be matrices, in which case interp2 returns the values of Z corresponding to the points (XI(i,j),YI(i,j)). Alternatively, you can pass in the row and column vectors xi and yi, respectively. In this case, interp2 interprets these vectors as if you issued the command meshgrid(xi,yi).
Notice, though, that for this to work, xi must be a row vector and yi must be a column vector.
Some part of this might be going away in future versions. The R2012b documentation indicates,
Note: In a future release, interp2 will not accept mixed combinations of row and column vectors for the sample and query grids.
Thanks for pointing that out. I didn't know that. It is easy to overlook, particularly when they do it the more complicated way with meshgrid in their example.
Funny though that the "See also" for interp2 does not mention TriScatteredInterp, but the help for TriScatteredInterp does mention interp2. Is one the preferred way for doing 2D interpolations?
function im=display(filename)
picture=imread('filename')
numrow=size(filename,1)
numcol=size(filename,2)
x=1:numrow;
y=1:numcol
x1=linspace(1,numrow,800)
y1=linspace(1,numcol,800*numcol/numrow)
[x1,y1]=meshgrid(x1,y1)
z=picture(x,y);
z1=interp2(x,y,z,x1,y1);
z=uint8(z);
pictureblue=image(picture(:,:,3));
picturegreen=image(picture(:,:,2));
picturered=image(picture(:,:,1));
axis equal;axis right;
figure
imshow(pictureblue);
Here is the codes I wrote.
I have two questions
1.why this program can not display the new blue color picture?
2.If I want to display four pictures together as required by the problem, i.e one is upper left, one is upper right, etc. How could I do that?
Thanks a lot
This is probably more of a hint that you should honestly be getting. There's still a little left to do, and you should do that yourself. But go ahead and mark as "Answered' if you have no more questions.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
format longg;
format compact;
fontSize = 20;
% Read in a standard MATLAB color demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'peppers.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
blackImage = uint8(zeros(rows, columns));
newRedChannel = [redChannel, redChannel; blackImage, blackImage];
newGreenChannel = [greenChannel, blackImage; greenChannel, blackImage];
newBlueChannel = [blueChannel, blackImage; blackImage, blueChannel];
newRGBImage = cat(3, newRedChannel, newGreenChannel, newBlueChannel);
% Display the original color image.
imshow(newRGBImage, []);
title('New Color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
Yeah.I need to do more. Thanks a lot for your help

Sign in to comment.

More Answers (1)

I tried writing a code to solve this problem and I got pretty far. I resized the image to have a standard resolution where the maximum pixel dimension is 800. And can display the original image and all of its red, green, blue layers in separate images. Although I'm getting a problem when I'm trying to insert these 4 image arrays inside one large composite array to get one single image with the original image and its other 3 layers like this:
I get as far as the top left image in its position and it displays correctly as well. When my code proceeds to insert the rest of the layers, MATLAB gives me a black image and this error:
Error using image TrueColor CData contains element out of range 0.0 <= value <= 1.0
Can anyone help make fixes in the last section to achieve this? It's kind of mind boggling. here's the code:
function im=displayRGB(filename)
img=imread(filename);
img=im2double(img);
%%------TO CONVERT ALL PICTURES INTO A STANDARD RESOLUTION PICTURE WITH MAX DIMENSION 800------
[m n r]=size(img);
rows=1:m;
columns=1:n;
[X Y]=meshgrid(columns,rows);
if m>n
xi=linspace(1,m,800);
ratio=800/m;%this ratio is calculated so the other pixel dimension can
%be adjusted to maintain the same aspect ratio
yi=linspace(1,n,n*ratio);
[XI YI]=meshgrid(xi,yi);
else if n>m
yi=linspace(1,n,800);
ratio=800/n;
xi=linspace(1,m,m*ratio);
[XI YI]=meshgrid(xi,yi);
end
end
for panel=1:r
resized_img(:,:,panel)=interp2(X,Y,img(:,:,panel),XI,YI);
end
%%----------------EXTRACTING COLOR LAYERS..................................
R=resized_img;
R(:,:,[2 3])=0;
G=resized_img;
G(:,:,[1 3])=0;
B=resized_img;
B(:,:,1:2)=0;
%%----------INSERTING IMAGE AND COLORED LAYERS INTO ONE LARGE COMPOSITE IMAGE-----
[M N Q]=size(resized_img);
im(1:M,1:N,1:Q)=resized_img;
% figure(1)
% image(im)
im((1:M),((N+1):2*N),(1:Q))=R;
% figure(2)
% image(im)
im(((M+1):2*M),(1:N),(1:Q))=G;
% figure(3)
% image(im)
im(((M+1):2*M),((N+1):2*N),(1:Q))=B;
im=uint8(im);
figure(4);
image(im);
axis tight
axis equal

3 Comments

You need to convert each image to an RGB image and then stitch them together.
% Extract the individual red, green, and blue color channels.
rgbImage = imread('peppers.png');
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
blackImage = zeros(size(redChannel), class(rgbImage));
redRGB = cat(3, redChannel, blackImage, blackImage);
greenRGB = cat(3, blackImage, greenChannel, blackImage);
blueRGB = cat(3, blackImage, blackImage, blueChannel);
% Recombine separate color channels into a single, true color RGB image.
quadImage = [rgbImage, redRGB; greenRGB, blueRGB];
imshow(quadImage);
Actually I got it to display all four images on one single image as well now. I just removed the line where I converted the image type double to type uint8. This doesn't make sense to me but it somehow fixed.
There are just some blank spaces I don't understand.
I can't see your code - you forgot to attach it - so I can't explain it to you. However did you understand my code?

Sign in to comment.

Categories

Asked:

DI
on 19 Dec 2012

Commented:

on 22 Oct 2016

Community Treasure Hunt

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

Start Hunting!