how to browse image and process it before it's displayed to axes in GUI matlab - image

I want to create a GUI with matlab, to browse for an image and process it before displaying it to some axes.
I can't browse the image with my current program, and the image that I want to display is related to the previous process. Is it possible to browse and display all of the processed images to the axes with just one pushbutton? Can someone help me create the GUI for this sample program?
folder = 'D:\wildlife';
baseFileName = 'page-6.png';
fullFileName = fullfile(folder, baseFileName);
% 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: %Gambar tidak ditemukan.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = .
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 3, 1);
imshow(rgbImage);
title('Gambar Asli', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
%set the morphology
SE = strel ('square', 3);
j=imerode (rgbImage, SE);
subplot(2, 3, 2);
imshow(j);
title('Penebalan Citra', 'FontSize', fontSize);
% Binarize to find black pixels
% Find where either red, green, or blue channel is dark.
thresholdValue = 55;
binaryImage = j(:,:, 1) < thresholdValue | j(:,:, 2) < thresholdValue | j(:,:, 3) < thresholdValue;
% Display the image.
subplot(2, 3, 3);
imshow(binaryImage);
title('Citra Biner', 'FontSize', fontSize);
% Fill the image
filledImage = imfill(binaryImage, 'holes');
% Display the image.
subplot(2, 3, 4);
imshow(filledImage);
title('Pengisian Citra Biner', 'FontSize', fontSize);
drawnow;

To create the GUI, Matlab's GUIDE feature is well documented and relatively easy to use and learn (http://www.mathworks.com/help/matlab/gui-building-basics.html). Simply type 'guide' at the Matlab prompt to bring up the quick start menu.
Once you create a new blank GUI, you can add a push button and as many axes as you need to display the various images (4 for your sample code above). Then the code to browse for, process, and display the image can be placed in the callback for the push button. To open the callback code, right click on the push button and select "View Callbacks -> Callback" from the menu.
Then you can us something like the following to browse for the desired image:
[baseFileName, folder, FilterIndex] = uigetfile('*.png');
To display the image in the desired axis, specify the appropriate axis handle as the 'Parent' argument in your calls to 'imshow', rather than using 'subplot':
% Display the original color image.
fullFileName = [folder baseFileName];
rgbImage = imread(fullFileName);
imshow(rgbImage, 'Parent', handles.axes1);

Related

Changing a part of an image

How can I paste back a part of my picture after I changed it in MATLAB? I cropped the plates off this image of a car and now I want to put it back automatically. The plates are still at the same coordinates as they were initially, but the background is all black.
The car I want to paste on:
And this is what I want to paste:
Here is my code, I want to change the part where I need to draw by hand the plate.
fontSize = 20;
format compact;
baseFileName1 = 'blurr_plate.jpg';
baseFileName2 = 'car2.jpg';
sourceImage = imread(baseFileName1);
subplot(1, 2, 1);
imshow(sourceImage);
axis on;
caption = sprintf('Source image, %s', baseFileName1);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
targetImage = imread(baseFileName2);
subplot(1, 2, 2);
imshow(targetImage);
axis on;
caption = sprintf('Target image, %s, original', baseFileName2);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
% Ask user to draw freehand mask.
message = sprintf('In the LEFT IMAGE...\nLeft click and hold to begin drawing.\nSimply lift the mouse button to finish');
subplot(1, 2, 1);
uiwait(msgbox(message));
hFH = imfreehand(); % Actual line of code to do the drawing.
% Create a binary image ("mask") from the ROI object.
mask = hFH.createMask();
xy = hFH.getPosition;
% Paste it onto the target image.
targetImage(mask) = sourceImage(mask);
% Display new image.
subplot(1, 2, 2); % Switch active axes to right hand axes.
imshow(targetImage);
imwrite(targetImage, 'car_new.jpg')
axis on;
caption = sprintf('Target image, %s, after paste', baseFileName2);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
Your code will work only in case when both source and target images are grayscale. As your target image is coloured, make following changes:
Delete line number 35,36 and 41.
paste this code after line 33.
redChannel = targetImage(:, :, 1);
greenChannel = targetImage(:, :, 2);
blueChannel = targetImage(:, :, 3);
redChannel(mask) = sourceImage(mask);
greenChannel(mask) = sourceImage(mask);
blueChannel(mask) = sourceImage(mask);
targetImage = cat(3, redChannel, greenChannel, blueChannel);

Image extraction: when entering image code stops executing

I have to extract features of an image using the image extraction from MATLAB. It works successfully with the image provided by The MathWorks in their tutorial, but when I enter another image it doesn't work
My code for image extraction is:
boxImage = imread('stapleRemover.jpg');
%boxImage = imread('D:\matlab test\book\IMG_2294.jpg');
figure;
imshow(boxImage);
title('Image of a Box');
%sceneImage = imread('D:\matlab test\book\IMG_2291.jpg');
sceneImage = imread('clutteredDesk.jpg');
figure;
imshow(sceneImage);
title('Image of Cluttered Scene');
%detecting feature point
boxPoints = detectSURFFeatures(boxImage);
scenePoints = detectSURFFeatures(sceneImage);
figure;
imshow(boxImage);
title('100 strongest feature Points from Box Image');
hold on;
plot(selectStrongest(boxPoints, 100));
figure;
imshow(sceneImage);
title('300 Strongest Feature Points from Scene Image');
hold on;
plot(selectStrongest(scenePoints, 300));
%extracting feature descriptor
[boxFeatures, boxPoints] = extractFeatures(boxImage, boxPoints);
[sceneFeatures, scenePoints] = extractFeatures(sceneImage, scenePoints);
%finding putative point match
boxPairs = matchFeatures(boxFeatures, sceneFeatures);
matchedBoxPoints = boxPoints(boxPairs(:, 1), :);
matchedScenePoints = scenePoints(boxPairs(:, 2), :);
figure;
showMatchedFeatures(boxImage, sceneImage, matchedBoxPoints, matchedScenePoints, 'montage');
title('Putatively Matched Points (Including Outliers)');
%locating object in the scene using putative matches
[tform, inlierBoxPoints, inlierScenePoints] = estimateGeometricTransform(matchedBoxPoints, matchedScenePoints, 'affine');
figure;
showMatchedFeatures(boxImage, sceneImage, inlierBoxPoints,inlierScenePoints, 'montage');
title('Matched Points (Inliers Only)');
boxPolygon = [1, 1; % top-left
size(boxImage, 2), 1; % top-right
size(boxImage, 2), size(boxImage, 1); % bottom-right
1, size(boxImage, 1); % bottom-left
1, 1]; % top-left again to close the polygon
newBoxPolygon = transformPointsForward(tform, boxPolygon);
figure;
imshow(boxPolygon);
imshow(sceneImage);
hold on;
line(newBoxPolygon(:, 1), newBoxPolygon(:, 2), 'Color', 'y');
title('Detected Box');
It runs successfully, but when I change the image which is made by me using my camera, it stops executing code on this line:
boxPoints = detectSURFFeatures(boxImage);
Can anyone help me to out?
What error are you getting? From the information you've given, I would guess that your image is RGB, and you need to convert it to grayscale before passing it to detectSURFFeatures.
Undefined function showMatchedFeatures
for input arguments of type SURFPoints.
in matlab 2012a

Displaying pixel values of an image in Octave?

If I load and display an image, for example
c = imread('cameraman.tif');
imshow(c)
then in the plot window, under the image itself, there are two numbers indicating the current cursor position, in the form
[39.25, 120.6]
I have two questions about this:
Can the display be tweaked so that the positions are integers? So one image pixel per screen pixel?
Can this information include the grayscale/rgb value of the pixel, such as
[23, 46] = 127
or
[23, 46] = (46,128,210)?
I've tried fiddling with the "axis" command, but I haven't found anything which helps.
I guess what I want is something like Matlab's "Pixel Information Tool" impixelinfo:
http://www.mathworks.com.au/help/images/ref/impixelinfo.html though I know from the octave image wiki at http://wiki.octave.org/Image_package that impixelinfo is not currently implemented in Octave. But maybe there's another way to achieve the same result?
I'm using Octave-3.8.0, the image package 2.2.0, under linux (Ubuntu 12.04).
GNU Octave 3.8 uses FLTK as standard graphics_toolkit. Unfortunately WindowButtonMotionFcn is only triggered if a button is pressed while the mouse moves (dragging) with this toolkit (Today I would consider this as a bug). But you can use WindowButtonDownFcn.
This examples updates the title with the position and the image value at that position if you click in the image:
img = imread ("cameraman.png");
imshow (img)
function btn_down (obj, evt)
cp = get (gca, 'CurrentPoint');
x = round (cp(1, 1));
y = round (cp(1, 2));
img = get (findobj (gca, "type", "image"), "cdata");
img_v = NA;
if (x > 0 && y > 0 && x <= columns (img) && y <= rows (img))
img_v = squeeze (img(y, x, :));
endif
if (numel (img_v) == 3) # rgb image
title(gca, sprintf ("(%i, %i) = %i, %i, %i", x, y, img_v(1), img_v(2), img_v(3)));
elseif (numel (img_v) == 1) # gray image
title(gca, sprintf ("(%i, %i) = %i", x, y, img_v));
endif
endfunction
set (gcf, 'WindowButtonDownFcn', #btn_down);
You can also place a text next to the cursor if you want.

MATLAB Pasting multiple images in a line onto another image?

I am trying to paste multiple smaller images (9 rectangles of different sizes) onto a black background. The center horizontal line of each of these images should be aligned and all the edges should be touching. It doesn't matter where on the black it is pasted as long as they are aligned as described. I will attach some images of what I mean.
example of a smaller image
http://i.imgur.com/Dlu6es4.png
desired result
http://i.imgur.com/ujuhCWs.png
ImageAnalyst provided this great code for pasting images, but I think what I need is a bit more complicated. If anybody can help out or point me to a good direction, I would be very grateful. Many thanks!
if true
% % Lets user drag out a box on an image, then define where they want to paste it.
% Then it pastes the drawn region onto the original image.
% Figure out how to select two points for pasting
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.
fontSize = 20;
format compact;
grayImage = imread('Blackout.png');
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Display the cropped image.
rotatedImage=imread('rotatedImage.png');
subplot(2, 2, 3);
imshow(rotatedImage);
axis on;
title('Region that you defined', 'FontSize', fontSize);
% Paste it onto the original image
[rows2 columns2] = size(rotatedImage)
promptMessage = sprintf('Click on the upper left point where you want to paste it,\nor Cancel to abort processing?');
titleBarCaption = 'Continue?';
button = questdlg(promptMessage, titleBarCaption, 'Continue', 'Cancel', 'Continue');
if strcmpi(button, 'Cancel')
return;
end
[x, y] = ginput(1)%pick 1 two-dimensional points from the figure and returns x y coordinates.
% Determine the pasting boundaries.
r1 = int32(y);
c1 = int32(x);
r2 = r1 + rows2 - 1;
r2 = min([r2 rows]);
c2 = c1 + columns2 - 1;
c2 = min([c2, columns]);
plot([c1 c2 c2 c1 c1], [r1 r1 r2 r2 r1], 'r-');
% Paste as much of croppedImage as will fit into the original image.
grayImage(r1:r2, c1:c2) = rotatedImage(1:(r2-r1+1), 1:(c2-c1+1));
subplot(2, 2, 4);
imshow(grayImage);
axis on;
title('Region that you defined pasted onto original', 'FontSize', fontSize);
%save rotated image
imwrite(grayImage, 'alignedImage.png');
Actually, I think I've figured it out! Just use the row sizes of each of the images to determine the placement of the next image. It's a little messy but I think it's a good start :)
% Lets user drag out a box on an image, then define where they want to paste it.
% Then it pastes the drawn region onto the original image.
% Figure out how to select two points for pasting
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.
fontSize = 20;
format compact;
%%
grayImage = imread('Blackout.png');
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[I1R I1C numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(1, 3, 1);
imshow(grayImage);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
%%
% Display the cropped image.
rotatedImage=imread('rotCoxa.png');
subplot(1, 3, 2);
imshow(rotatedImage);
axis on;
title('Region that you defined', 'FontSize', fontSize);
% Paste it onto the original image
[I2R I2C] = size(rotatedImage);
%%
x = 1;
y = I1R/2;
% Determine the pasting boundaries.
r1 = int32(y);
c1 = int32(x);
r2 = r1 + I2R - 1;
r2 = min([r2 I1R]);
c2 = c1 + I2C - 1;
c2 = min([c2, I1R]);
plot([c1 c2 c2 c1 c1], [r1 r1 r2 r2 r1], 'r-');
% Paste as much of croppedImage as will fit into the original image.
grayImage(r1:r2, c1:c2) = rotatedImage(1:(r2-r1+1), 1:(c2-c1+1));
subplot(1, 3, 3);
imshow(grayImage);
axis on;
title('Region that you defined pasted onto original', 'FontSize', fontSize);
%%
%save rotated image
imwrite(grayImage, 'alignedImage.png');
%%
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.
fontSize = 20;
format compact;
%%
%delete('Blackout.png');
grayImage = imread('alignedImage.png');
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[I1R I1C numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(1, 3, 1);
imshow(grayImage);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
%%
% Display the cropped image.
rotatedImage=imread('rotTrochanter.png');
subplot(1, 3, 2);
imshow(rotatedImage);
axis on;
title('Region that you defined', 'FontSize', fontSize);
% Paste it onto the original image
[I3R I3C] = size(rotatedImage);
%%
previouslyrotatedImage=imread('rotCoxa.png');
[I2R I2C] = size(previouslyrotatedImage);
x = I2C;
y = I1R/2 + I2R/2 - I3R; %check math. I3R/2 or I3R?
% Determine the pasting boundaries.
r1 = int32(y);
c1 = int32(x);
r2 = r1 + I3R - 1;
r2 = min([r2 I1R]);
c2 = c1 + I3C - 1;
c2 = min([c2, I1C]);
plot([c1 c2 c2 c1 c1], [r1 r1 r2 r2 r1], 'r-');
% Paste as much of croppedImage as will fit into the original image.
grayImage(r1:r2, c1:c2) = rotatedImage(1:(r2-r1+1), 1:(c2-c1+1));
subplot(1, 3, 3);
imshow(grayImage);
axis on;
title('Region that you defined pasted onto original', 'FontSize', fontSize);
%%
%save rotated image
imwrite(grayImage, 'alignedImage.png');

Playing image sequences in MATLAB

Greetings to all of you.
I have this somewhat frustrating problem, and I hope that you kindly help me solve it.
I am developing a human tracking system in MATLAB, and would like to show the result in an appealing GUI (also in MATLAB using GUIDE).
There is this main window where an image sequence of about 2500 gray scale images of size 320x240 would be played like a video but where the humans be outlined in them nicely.
The challenge is; these images need a bit of processing (detection outlining of humans) before being shown on the window.
Now, is it possible to display a set of images while at the same time do some processing for another set to be shown afterwards?
I would very much prefer it to play like a normal video, but I guess that would be somehow ambitious.
Here is an example showing a scenario similar to what you described. This was adapted from the demo I mentioned in the comments.
function ImgSeqDemo()
figure()
for i=1:10
%# read image
img = imread( sprintf('AT3_1m4_%02d.tif',i) );
%# process image to extract some object of interest
[BW,rect] = detectLargestCell(img);
%# show image
imshow(img), hold on
%# overlay mask in red color showing object
RGB = cat(3, BW.*255, zeros(size(BW),'uint8'), zeros(size(BW),'uint8'));
hImg = imshow(RGB); set(hImg, 'AlphaData',0.5);
%# show bounding rectangle
rectangle('Position', rect, 'EdgeColor','g');
hold off
drawnow
end
end
Here is the processing function used above. In your case, you would insert your algorithm instead:
function [BW,rect] = detectLargestCell(I)
%# OUTPUT
%# BW binary mask of largest detected cell
%# rect bounding box of largest detected cell
%# find components
[~, threshold] = edge(I, 'sobel');
BW = edge(I,'sobel', threshold*0.5);
se90 = strel('line', 3, 90);
se0 = strel('line', 3, 0);
BW = imdilate(BW, [se90 se0]);
BW = imclearborder(BW, 4);
BW = bwareaopen(BW, 200);
BW = bwmorph(BW, 'close');
BW = imfill(BW, 'holes');
%# keep largest component
CC = bwconncomp(BW);
stats = regionprops(CC, {'Area','BoundingBox'});
[~,idx] = max([stats.Area]);
rect = stats(idx).BoundingBox;
BW(:) = 0;
BW(CC.PixelIdxList{idx}) = 1;
end

Resources