Draw rectangles on an image in Matlab - 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')

Related

crop circles detected from imfindcircles in matlab

I'm detecting circles from an image using imfindcircles function.
Below is the code.
image here
img= imread('image.png');
imshow(img);
rmin=10
rmax=50
[centersDarkl, radiiDarkl]=imfindcircles(img,
[rmin,rmax],'ObjectPolarity','dark','Sensitivity',0.80);
viscircles(centersDarkl, radiiDarkl,'LineStyle','--')
Now, I want to crop the detected circles and save them as different figures.
Here is a solution that works for this image. I used floor and ceil to avoid the edges and rmax had to be larger than 75.
[img,map] = imread('MwBQo.png','png');
img = ind2rgb(img, map);
figure;
imshow(img);
rmin = 10;
rmax = 80;
[centersDarkl, radiiDarkl] = imfindcircles(img,...
[rmin,rmax],'ObjectPolarity','dark','Sensitivity',0.80);
viscircles(centersDarkl, radiiDarkl,'LineStyle','--')
for iCirc = 1:size(centersDarkl,1)
cropped{iCirc,1} = img(...
ceil(centersDarkl(iCirc,2)-radiiDarkl(iCirc)):...
floor(centersDarkl(iCirc,2)+radiiDarkl(iCirc)),...
ceil(centersDarkl(iCirc,1)-radiiDarkl(iCirc)):...
floor(centersDarkl(iCirc,1)+radiiDarkl(iCirc)),:);
end
figure;
subplot(1,2,1)
imshow(cropped{1})
subplot(1,2,2)
imshow(cropped{2})

how to put rectangle for labeled images?? which is labeled using CC = bwconncomp(BW)

I labeled an image using CC = bwconncomp(BW); and masking the label with maximum area using code
numPixels = cellfun(#numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
BW(CC.PixelIdxList{idx}) = 0;
Now I want to put thin rectangular box around that maximum area instead of masking it. How it can be done?
Full Code:
f = imread('test.PNG');
subplot(2,2,1); imshow(f,[]); title('Original Image');
for i = 1:3
Image = medfilt2(Image,[3 3]);
end
[Image_Num, num] = bwlabel(Image,8);
subplot(2,2,3); imshow(Image); title('after median filtering'); %labeling algorithm
BW=im2bw(Image);
subplot(2,2,4); imshow(BW); title('binary image');
CC = bwconncomp(BW); %area based segmentation
numPixels = cellfun(#numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
BW(CC.PixelIdxList{idx}) = 0;
figure;
imshow(BW); title('AFTER AREA BASED MASKING');
You can use bwlabel with regionprops and rectangle annotation:
lb = bwlabel( bw ); %// label each CC
st = regionprops( lb, 'Area', 'BoundingBox' ); %// get area and bounding box for each region
[mxa mxi] = max( [st.Area] ); %// find max area region
Now you can annotate
figure;
imshow( bw ); hold on;
rectangle('Position', st(mxi).BoundingBox, 'EdgeColor', 'r' );
On the 'coins.png' image this results with:
CC.PixelIdxList{idx} will give you the linear indices of the locations in the image of where your object is located.
What you can do is use ind2sub to convert the linear indices to row and column locations, then we can determine the top left and bottom right corner of these row and column indices. Once we do this, we can thus mark your image accordingly.
Therefore:
%// Determine row and column locations
[row,col] = ind2sub(size(BW), CC.PixelIdxList{idx});
%// Get top left and bottom right coordinates
topleft_row = min(row);
topleft_col = min(col);
bottomright_row = max(row);
bottomright_col = max(col);
%// Draw a white box around the object
%// Left vertical line
BW(topleft_row:bottomright_row, topleft_col) = true;
%// Right vertical line
BW(topleft_row:bottomright_row, bottomright_col) = true;
%// Top horizontal line
BW(topleft_row, topleft_col:bottomright_col) = true;
%// Bottom horizontal line
BW(bottomright_row, topleft_col:bottomright_col) = true;
Here's an example using coins.png that's built-in to MATLAB. I read in the image, threshold it and fill in the holes.
im = imread('coins.png');
BW = im2bw(im, graythresh(im));
BW = imfill(O, 'holes');
When I do that and run the above code to draw a rectangle around the largest object, this is what I get:
Where this code ties into your program, don't do any masking. Replace the masking code with the above... so:
f = imread('test.PNG');
subplot(2,2,1); imshow(f,[]); title('Original Image');
for i = 1:3
Image = medfilt2(Image,[3 3]);
end
[Image_Num, num] = bwlabel(Image,8);
subplot(2,2,3); imshow(Image); title('after median filtering'); %labeling algorithm
BW=im2bw(Image);
subplot(2,2,4); imshow(BW); title('binary image');
CC = bwconncomp(BW); %area based segmentation
numPixels = cellfun(#numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
%-------- CHANGE HERE
%// Determine row and column locations
[row,col] = ind2sub(size(BW), CC.PixelIdxList{idx});
%// Get top left and bottom right coordinates
topleft_row = min(row);
topleft_col = min(col);
bottomright_row = max(row);
bottomright_col = max(col);
%// Draw a white box around the object
%// Left vertical line
BW(topleft_row:bottomright_row, topleft_col) = true;
%// Right vertical line
BW(topleft_row:bottomright_row, bottomright_col) = true;
%// Top horizontal line
BW(topleft_row, topleft_col:bottomright_col) = true;
%// Bottom horizontal line
BW(bottomright_row, topleft_col:bottomright_col) = true;

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.

on matlab, how can i plot centroid points on top of an rgb image?

i have a list of about 300 centroid points. these points are the centroids of the conncomps of a BW image that i have. Is there a way to plot the points of the centroids over the original rgb image?
No problem. Have this short script:
img = imread('rice.png');
bg = imopen(img,strel('disk',15));
img2 = img - bg;
mask = im2bw(img2, 0.19);
mask = bwareaopen(mask, 40);
cc = bwconncomp(mask, 4);
positionArray = regionprops(cc, {'Centroid'});
positionArray = struct2cell(positionArray);
positionArray = cellfun(#transpose, positionArray, 'UniformOutput',false);
positionArray = cell2mat(positionArray);
imshow(img);
hold on;
scatter(positionArray(1, :), positionArray(2, :), 200, 'g+');
You can vary the markersize and shape as you wish. The points in this case are stored as a 2 by n matrix with x coordinates in the first row ans y in the second.
First, the image itself is plotted using imshow. Then, scatter() is called. To put both items on the same set of axes, you have to call hold on.

Matlab Image Processing: Bound image by a rectangle

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