cropping an image using centroids

20 views (last 30 days)
C.G.
C.G. on 18 May 2020
Commented: C.G. on 19 May 2020
I have an image of multiple footballs, where I have located the centroid of each football in the image.
I want to crop the image using the centroids, to create a series of sub-images, where each ball has its own image.
Is there a way to do this using the centroids?
%Input video using videoreader command and name it 'obj'
obj = VideoReader('2D_football_video.mp4')
%% Read the frames in the video
%Define the frames in the video which you want MATLAB to read, in this case it is them all between frames 20-34
frames_no = [20:34];
%Tell it to read the frames in the video (named obj) where 20 is start and 34 finish
vidFrames = read(obj,[20 34]);
%Tell it to get the number of individual frames in the whole video
numFrames = size(vidFrames,4);
%Get individual frames
%Colormap is a table of colors used for index color videos
%c.data is an image sequence matrix
%How many times you repeat a function in a loop is defined by 'k'
%k = the range of values the for loop will run through before ending.
for k = 1: numFrames %k = all the frames between 1 and the total number in the video
mov(k).cdata = vidFrames(:,:,:,k); %for all rows and columns in k
mov(k).colormap = []; % [], create an empty matrix
end
%Watch the video in a new figure using movie command
figure(1), movie(mov, 1, obj.FrameRate), title('Original movie');
%Show a certain range of frames in a montaged figure, in this case between 20 and 34
figure(2), montage(vidFrames(:,:,:,1:15)),title('Montage of frames 20 to 34'); % you have told matlab to identify 15 individual video frames
%% Tracking particle translations from ball centroids
%Define the frames between which particles are going to be tracked
start_frame = 1;
number_of_frames = 100;
%Define the radii of the circles to get MATLAB to search for
min_radius = 5;
max_radius = 10;
quality = .9; %quality is a number between 0-1 to see how strong a circle must be in order to be found. Values of 1 discard no circles
t = 0.1; % t is the frame rate, used as time in the velocity calculation
% Grid coarseness
n = 5; %spacing in the grid
% Here I am going to do all the same steps but in one move, this will be much more memory efficient.
tmpframe = read(obj,1); %read only the first frame from the video
% Meshgrid creates 2D grid coordinates with x and y coordinates defined by the length of the two inputted vectors
% Grids going from 1 to the length of tmpframe, in spacings of 5 (n)
[X,Y]=meshgrid(1:n:size(tmpframe,2),1:n:size(tmpframe,1));
%Track the particles and plot velocity for frames 1 and 2
for k = 1:numFrames;
%binarize frames 1 and 2 from the video (using rgb2gray)
frame_1 = rgb2gray(read(obj,k+start_frame-1));
frame_2 = rgb2gray(read(obj,k+start_frame));
%identify the circles in frames 1 and 2 with radii between the defined min and max
centres_1 =imfindcircles(frame_1,[min_radius,max_radius],'Sensitivity',quality,'Method','TwoStage');
centres_2 =imfindcircles(frame_2,[min_radius,max_radius],'Sensitivity',quality,'Method','TwoStage');
% dsearchm returns the indicies of the closest points in the 2 vectors
% identifies where each centroid has moved between frames 1 and 2
[index,dist] = dsearchn(centres_2,centres_1);
% here we have the distances not in order
% assign the centres from frames 1 and 2 to x and y coordinate variables
x_1{k} = centres_1(:,1);
x_2{k} = centres_2(index,1);
y_1{k} = centres_1(:,2);
y_2{k} = centres_2(index,2);
% now we compute the translational velocity as s = d/t
vel_x{k} = (x_2{k}-x_1{k})/t; %x velocity using frame 2 - frame 1
vel_y{k} = (y_2{k}-y_1{k})/t; %y velocity using frame 2 - frame 1
vel_res{k} = sqrt(vel_x{k}.^2 + vel_y{k}.^2); %the final velocity vector as a function as its x and y components
% now we can make a overall velocity, by reshaping the array
% for all the columns in 'loop', reshape the array 'griddata' to define, size U, V and RES
U(:,:,k)=reshape(griddata(x_1{k},y_1{k},vel_x{k},X(:),Y(:)),size(X,1),size(X,2));
V(:,:,k)=reshape(griddata(x_1{k},y_1{k},vel_y{k},X(:),Y(:)),size(X,1),size(X,2));
RES(:,:,k)=reshape(griddata(x_1{k},y_1{k},vel_res{k},X(:),Y(:)),size(X,1),size(X,2));
end
figure(3)
% Set graphics objects properties: size of the figure (x0,y0,width,height)
set(gcf,'position',[246,738,1701,210])
% This loop will now display what we have just made
for k = 1:number_of_frames-1;
subplot(1,2,1); %creates a figure with 2 plots side by side
scatter(x_1{k},y_1{k},20,vel_res{k})
hold on
subplot(1,2,2);
%displays RES as an image using the full range of colors where each element of RES corresponds to a rectangular area in the image
imagesc(RES(:,:,k))
pause(1)
end
  2 Comments
C.G.
C.G. on 18 May 2020
yes, none of the balls go out of frame at any point

Sign in to comment.

Accepted Answer

darova
darova on 18 May 2020
Try this
A = imread('image.png');
I = im2bw(A,0.1); % binarize image
[L,n] = bwlabel(I); % label image
for i = 1:n
I1 = L == i; % select region
[ii,jj] = find(I1); % find all 'nonzero' indices
I2 = A(min(ii):max(ii), jj(1):jj(end),:);
imshow(I2)
pause(0.5)
end
  4 Comments
C.G.
C.G. on 19 May 2020
Thankyou, I will try these.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!