Matlab Image Processing: Bound image by a rectangle - matlab

I have an image and I plotted the boundary of the image. Can anyone please tell me how to draw a rectangle on the image by overwriting the boundary pixel values, using MATLAB.

If it is a straight rectangle, just set the values in the matrix:
function Stack1()
im = imread('peppers.png');
x = 10;
y = 20;
w = 40;
h = 50;
im(y:y+h,x,:) = 255;
im(y:y+h,x+w,:) = 255;
im(y,x:x+w,:) = 255;
im(y+h,x:x+w,:) = 255;
figure();imshow(im);
end

Probably you can use this File Exchange submission:
Draw a border around an image

Related

Canny edge detector is detecting the borders of the images

clear_all();
image_name = 'canny_test.png';
% no of pixels discarded on border areas
discard_pixels = 10;
% read image and convert to grayscale
input_image = gray_imread(image_name);
% discard border area
input_image = discard_image_area(input_image, discard_pixels);
% create a binary image
binary_image = edge(input_image,'canny');
imshow(binary_image);
Input
Expected Outcome
Actual Outcome
Here, we see that the borderlines of the image are being detected by the Canny Edge Detector which is not my expected outcome.
How can I achieve this?
Source Code
function [output_image] = discard_image_area( input_image, pixel_count)
output_image = input_image;
[height, width] = size(input_image);
% discard top
output_image(1:pixel_count, :) = 0;
% discard bottom
h = height - pixel_count;
output_image(h:height, :) = 0;
% discard left
output_image(:,1:pixel_count) = 0;
% discard right
output_image(:,(width-pixel_count):width) = 0;
end
function img = gray_imread( image_name )
I = imread(image_name);
if(is_rgb(I))
img = rgb2gray(I);
elseif (is_gray(I))
img = I;
end
end
Apply discard_image_area after applying the edge function. Otherwise the discarded area makes its boundary apparently. i.e. do this:
image_name = 'canny_test.png';
discard_pixels = 10;
input_image = rgb2gray(imread(image_name)); % there is no such this as gray_imread
% create a binary image
binary_image = edge(input_image,'canny');
% discard border area
binary_image = discard_image_area(binary_image , discard_pixels);
imshow(binary_image);
Output:
The answer is simple, your function discard_image_area changes the image value to 0 near the borders of the image.
Hence it creates Step between the image value and 0.
This is exactly what the Canny Edge Detector looks for.
You can easily see it if you display the image after applying the function.
Just don't use that function.

How to separate and save a part of an image?

I'm trying to save each rectangle in an image as a separate jpeg image to be able to train a neural network. this is how I draw a rectangle over trucks:
function hdl = BBox(img, samp)
I = imread(img);
hdl = imshow(img);
hold on;
s = size(samp,1);
for i=1:s
bbox = samp(i,:);
X = [bbox(3)-(bbox(5)), bbox(3)-(bbox(5)), bbox(3)-(bbox(5))+2*bbox(5), bbox(3)-(bbox(5))+2*bbox(5), bbox(3)-(bbox(5))];
Y = [bbox(4)-(bbox(6)), bbox(4)-(bbox(6))+2*bbox(6), bbox(4)-(bbox(6))+2*bbox(6), bbox(4)-(bbox(6)), bbox(4)-(bbox(6))];
Cx = bbox(3);
Cy = bbox(4);
H = [X;Y;ones(1,5)]; %// points as 3D homogeneous coordinates
Tc = [1 0 -Cx; 0 1 -Cy; 0 0 1]; %// translation as a matrix
Tr = [cosd((-bbox(7))) -sind((-bbox(7))) 0; sind((-bbox(7))) cosd((-bbox(7))) 0; 0 0 1]; %// rotation
Hr = inv(Tc) * Tr * Tc * H; %// all transformations as matrix products
plot( Hr(1,:), Hr(2,:) ); %// the rotated rect
disp(Hr);
end
I don't think the imcrop command works for rotated rectangles.
How can I save each rectangle as a different image?
I guess an easy way would be to use the extractRotatedPatch File Exchange Submission
rpatch = extractRotatedPatch(img, center, width, height, angle)
Sidenote:
Though this is not a Matlab issue, I just want to give you a heads up that you may need to train it on millions of images before machinelearning would start to give decent results.

Draw rectangles on an image in Matlab

I am trying to figure out how to draw rectangles on an image in Matlab.
Once the rectangles are drawn on the image I would like to save the changes.
Thanks in advance!
Use getframe
img = imread('cameraman.tif');
fh = figure;
imshow( img, 'border', 'tight' ); %//show your image
hold on;
rectangle('Position', [50 70 30 60] ); %// draw rectangle on image
frm = getframe( fh ); %// get the image+rectangle
imwrite( frm.cdata, 'savedFileName.png' ); %// save to file
See rectanlge for more options on drawing rectangles. The 'Position' argument for rectangle is in format [from_x from_y width height] and is given in units of pixels.
Without using getframe:
im=imread('face.jpg'); %Image read
rectangle('Position', [10 10 30 30] ,...
'EdgeColor', 'r',...
'LineWidth', 3,...
'LineStyle','-');%rectangle properties
imshow( im, rectangle); %draw rectangle on image.
For more detail visit this MathWorks thread :)
The best and easy way to use is in the updated Matlab versions
img = imread('abcd.jpg');
box = [X1, Y1, width, height];
outImage= insertObjectAnnotation(img,'rectangle',bbox,'Rectangle');
figure, imshow(outImage), title('Image with rectangle');
I am using octave and the function getframe is not available so i wrote this trivial function
%% Draw red rectangle IN the image using the BoundingBox from regionprops
function rgbI = drawRectangleOnImg (box,rgbI)
x = box(2); y = box(1); w = box(4); h = box(3);
rgbI(x:x+w,y,1) = 255;
rgbI(x:x+w,y+h,1) = 255;
rgbI(x,y:y+h,1) = 255;
rgbI(x+w,y:y+h,1) = 255;
rgbI(x:x+w,y,2) = 0;
rgbI(x:x+w,y+h,2) = 0;
rgbI(x,y:y+h,2) = 0;
rgbI(x+w,y:y+h,2) = 0;
rgbI(x:x+w,y,3) = 0;
rgbI(x:x+w,y+h,3) = 0;
rgbI(x,y:y+h,3) = 0;
rgbI(x+w,y:y+h,3) = 0;
end
I=imread('%required image');
[M,N] = size(rgb2gray(I));%find the size of the image
x=int16(M/3);y=int16(N/3);xwidth=int16(N/3); ywidth=int16(N/3);%specify the position
pos=[x y xwidth ywidth];% give the position in which you wanna insert the rectangle
imshow(I);hold on
rectangle('Position',pos,'EdgeColor','b')

How to draw a filled circle on a video frame using matlab

I have an "inverted-pendulum" video which I try to find the mid point of moving part. I am using Computer Vision Toolbox
I change the mid point's color using detected coordinates. Assume that X is the frame's row number for the detected mid point and the Y is the col number.
while ~isDone(hVideoFileReader)
frame = step(hVideoFileReader);
...
frame(X-3:X+3, Y-3:Y+3, 1) = 1; % # R=1 make the defined region red
frame(X-3:X+3, Y-3:Y+3, 2) = 0; % # G=0
frame(X-3:X+3, Y-3:Y+3, 3) = 0; % # B=0
step(hVideoPlayer, frame);
end
Then I easily have a red square. But I want to add a red filled circle on the detected point, instead of a square. How can I do that?
You can use the insertShape function. Example:
img = imread('peppers.png');
img = insertShape(img, 'FilledCircle', [150 280 35], ...
'LineWidth',5, 'Color','blue');
imshow(img)
The position parameter is specified as [x y radius]
EDIT:
Here is an alternative where we manually draw the circular shape (with transparency):
% some RGB image
img = imread('peppers.png');
[imgH,imgW,~] = size(img);
% circle parameters
r = 35; % radius
c = [150 280]; % center
t = linspace(0, 2*pi, 50); % approximate circle with 50 points
% create a circular mask
BW = poly2mask(r*cos(t)+c(1), r*sin(t)+c(2), imgH, imgW);
% overlay filled circular shape by using the mask
% to fill the image with the desired color (for all three channels R,G,B)
clr = [0 0 255]; % blue color
a = 0.5; % blending factor
z = false(size(BW));
mask = cat(3,BW,z,z); img(mask) = a*clr(1) + (1-a)*img(mask);
mask = cat(3,z,BW,z); img(mask) = a*clr(2) + (1-a)*img(mask);
mask = cat(3,z,z,BW); img(mask) = a*clr(3) + (1-a)*img(mask);
% show result
imshow(img)
I'm using the poly2mask function from Image Processing Toolbox to create the circle mask (idea from this post). If you don't have access to this function, here is an alternative:
[X,Y] = ndgrid((1:imgH)-c(2), (1:imgW)-c(1));
BW = (X.^2 + Y.^2) < r^2;
That way you get a solution using core MATLAB functions only (no toolboxes!)
If you have an older version of MATLAB with the Computer Vision System Toolbox installed, you can use vision.ShapeInserter system object.
Thanks #Dima, I have created a shapeInserter object.
greenColor = uint8([0 255 0]);
hFilledCircle = vision.ShapeInserter('Shape','Circles',...
'BorderColor','Custom',...
'CustomBorderColor', greenColor ,...
'Fill', true, ...
'FillColor', 'Custom',...
'CustomFillColor', greenColor );
...
fc = int32([Y X 7;]);
frame = step(hFilledCircle, frame, fc);
I then applied it to detected point.

How to cut the portion and highlight it

Suppose we take any image from Internet and then copy or move some part from that image to any other area inside that image the image should show from where that the part is copied / moved and then pasted. By using matlab.
a = imread('obama.jpg');
a = rgb2gray(a);
[x1 y1] = size(a);
b = uint8(imcrop(a, [170 110 200 150]));
[x2 y2] = size(b);
c = uint8(zeros(x1,y1));
for i = 1:x2
for j = 1:y2
c(i+169,j+109) = b(i,j);
end
end
[x3 y3] = size(c)
subplot(1,3,1),imshow(a);
subplot(1,3,2),imshow(b);
subplot(1,3,3),imshow(c);
Code
%%// Input data and params
a = imread('Lenna.png');
a = rgb2gray(a);
src_xy = [300,300]; %% Starting X-Y of the source from where the portion would be cut from
src_dims = [100 100]; %% Dimensions of the portion to be cut
tgt_xy = [200,200]; %% Starting X-Y of the target to where the portion would be put into
%%// Get masks
msrc = false(size(a));
msrc(src_xy(1):src_xy(1)+src_dims(1)-1,src_xy(2):src_xy(2)+src_dims(2)-1)=true;
mtgt = false(size(a));
mtgt(tgt_xy(1):tgt_xy(1)+src_dims(1)-1,tgt_xy(2):tgt_xy(2)+src_dims(2)-1)=true;
%%// If you would like to have a cursor based cut, explore ROIPOLY, GINPUT - e.g. - mask1 = roipoly(a)
mask1 = msrc;
a2 = double(a);
%%// Get crop-mask boundary and dilate it a bit to show it as the "frame" on the original image
a2(imdilate(edge(mask1,'sobel'),strel('disk',2))) = 0;
a2 = uint8(a2);
%%// Display original image with cropped portion being highlighted
figure,imshow(a2);title('Cropped portion highlighted')
figure,imshow(a);title('Original Image')
figure,imshow(mask1);title('Mask that was cropped')
img1 = uint8(bsxfun(#times,double(a),mask1));
figure,imshow(img1);title('Masked portion of image')
%%// Get and display original image with cropped portion being overlayed at the target coordinates
a_final = a;
a_final(mtgt) = a(msrc);
figure,imshow(uint8(a_final));title('Original image with the cut portion being overlayed')
Output
Please note that to use RGB images, you would need to tinker a bit more with the above code.