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');
Related
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);
The matlab code below splits up an image into a number of smaller images. It then counts the number of black pixels in the image and displays it as a percentage of the total number of pixels in the picture. example of image
My question is - instead of counting the black pixels and displaying the percentage, how can I count the white pixels? (essentially the opposite!)
Thanks
% Divide an image up into blocks (non-overlapping tiles).
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
fontSize = 20;
% Read the image from disk.
rgbImage = imread('edge-diff.jpg');
% Display image full screen.
imshow(rgbImage);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
drawnow;
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage)
%==========================================================================
% The first way to divide an image up into blocks is by using mat2cell().
blockSizeR = 400; % Rows in block.
blockSizeC = 400; % Columns in block.
% Figure out the size of each block in rows.
% Most will be blockSizeR but there may be a remainder amount of less than that.
wholeBlockRows = floor(rows / blockSizeR);
blockVectorR = [blockSizeR * ones(1, wholeBlockRows), rem(rows, blockSizeR)];
% Figure out the size of each block in columns.
wholeBlockCols = floor(columns / blockSizeC);
blockVectorC = [blockSizeC * ones(1, wholeBlockCols), rem(columns, blockSizeC)];
% Create the cell array, ca.
% Each cell (except for the remainder cells at the end of the image)
% in the array contains a blockSizeR by blockSizeC by 3 color array.
% This line is where the image is actually divided up into blocks.
if numberOfColorBands > 1
% It's a color image.
ca = mat2cell(rgbImage, blockVectorR, blockVectorC, numberOfColorBands);
else
ca = mat2cell(rgbImage, blockVectorR, blockVectorC);
end
percentBlack = cellfun(#(x)sum(sum(all(x == 0, 3))) / (numel(x) / size(x,3)), ca);
% Now display all the blocks.
plotIndex = 1;
numPlotsR = size(ca, 1);
numPlotsC = size(ca, 2);
for r = 1 : numPlotsR
for c = 1 : numPlotsC
fprintf('plotindex = %d, c=%d, r=%d\n', plotIndex, c, r);
% Specify the location for display of the image.
subplot(numPlotsR, numPlotsC, plotIndex);
ax2 = subplot(numPlotsR, numPlotsC, plotIndex);
% Extract the numerical array out of the cell
% just for tutorial purposes.
rgbBlock = ca{r,c};
imshow(rgbBlock); % Could call imshow(ca{r,c}) if you wanted to.
[rowsB columnsB numberOfColorBandsB] = size(rgbBlock);
set(ax2, 'box', 'on', 'Visible', 'on', 'xtick', [], 'ytick', []);
% Make the caption the block number.
averageBlack = percentBlack(r,c);
disp(numPlotsR);
disp(averageBlack);
caption = sprintf('Frame #%d of %d\n Percentage information content %0.2f', ...
plotIndex, numPlotsR*numPlotsC, averageBlack*100);
title(caption);
drawnow;
% Increment the subplot to the next location.
plotIndex = plotIndex + 1;
end
end
This line:
percentBlack = cellfun(#(x)sum(sum(all(x == 0, 3))) / (numel(x) / size(x,3)), ca);
specifically the part that says all(x == 0, 3) means "all color channels have value 0". You want to change it to "all color channels have value 1 (or 255 depends on your image)"
So basically, change that 0 to 1 or 255, deependinf if your image is unit8 or double
I am trying to add more elements to an image by merging it will cropped image. My code works fine but my cropped image upon merging doesn't retain color.
B = A(y1:y2,x1:x2);
subplot(2, 2, 3);
imshow(B);
axis on;
[rows2, columns2] = size(B);
promptMessage = sprintf('Click on the upper left point where you want to paste it,\nor click Cancel to quit.');
titleBarCaption = 'Continue?';
[x, y] = ginput(1);
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-');
A(r1:r2, c1:c2) = B(1:(r2-r1+1), 1:(c2-c1+1));
subplot(2, 2, 4);
imshow(A);
The final image has cropped image but the color of the cropped image changes.Please let me know how to retain the color of the cropped image.
Thanks.
It doesn't retain colour because you are only extracting out the first channel of the image. I'm assuming your images are RGB images, and so you need to also extract all channels at the same spatial coordinates. Therefore, you need to slice into the third dimension as well:
B = A(y1:y2,x1:x2,:); %// Change
subplot(2, 2, 3);
imshow(B); % Imange B is a cropped image with same color
plot([c1 c2 c2 c1 c1], [r1 r1 r2 r2 r1], 'r-');
A(r1:r2, c1:c2,:) = B(1:(r2-r1+1), 1:(c2-c1+1),:); %// Change
subplot(2, 2, 4);
imshow(A);
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
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);