Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

298
LINES

< > BotCompany Repo | #2000475 // fastMV.m (fast motion detection in MATLAB)

New Tinybrain snippet

1  
function [rep_motion motion_vector] = fastMV(im1, im2, w)
2  
% Author:    Arash Jalalian
3  
% E-mail:    arash.jalalian@gmail.com
4  
% Arguments: [rep_motion motion_vector] = fastMV(im1, im2, w)
5  
% This is the simplified block matching algorithm(BMA) which is proposed by
6  
% L. Hao. I've simplified this algorithm for use it in a real-time problem.
7  
% We have a dynamic search pattern during finding the motion vector. 
8  
% 1. check with big diamond.
9  
% 2. check with one of the hexagon subject to previous results.
10  
% 3. check with small diamond.
11  
% 'im1' is base frame of a video and 'im2' is the second frame. and 'w' is 
12  
% the window size. 'rep_motion' is the representative motion vector and
13  
% 'motion_vector' declare motion vectors for each block of image.
14  
% Example:
15  
% im1 = imread('frame001.jpg');
16  
% im2 = imread('frame002.jpg');
17  
% w = 16;
18  
% [rep_m m_vector] = fastMV(im1, im2, w);
19  
20  
%   clear all
21  
%   close all
22  
%   clc
23  
%   im1 = imread('img_1057.pgm');
24  
%   im2 = imread('img_1058.pgm');
25  
%  % dis = 2;
26  
%   w = 8;
27  
28  
29  
% initialization
30  
[r1 c1] = size(im1);
31  
[r2 c2] = size(im2);
32  
if r1 ~= r2 || c1 ~= c2 
33  
    error('The images must be in a same size')
34  
end
35  
36  
pat.org    = [0; 0];
37  
pat.diam1  = [2 0 -2 0; 0 2 0 -2];%big diamond
38  
pat.diam2  = [1 0 -1 0; 0 1 0 -1];%small diamond
39  
pat.hexver = [2 1  -1 -2 -1 1; 0 2 2 0 -2 -2];
40  
pat.hexhor = [2 0 -2 -2 0 2 ;1 2 1 -1 -2 -1];
41  
42  
r_time = int16(floor(r1 ./ w));
43  
c_time = int16(floor(c1 ./ w));
44  
45  
% for preventing index exceeding from end of image. 4 is the maximum
46  
% Magnitude of the motion vector
47  
if mod(r1, w) < 4 
48  
    r_time = r_time -1;
49  
end
50  
if mod(c1, w) < 4
51  
    c_time = c_time -1;
52  
end
53  
slice1 = cell(r_time, c_time);
54  
slice2 = cell(r_time, c_time);
55  
motion_vector = cell(r_time, c_time);
56  
57  
% creating slices with cell array of slices
58  
for i = 1:r_time
59  
    for j = 1:c_time
60  
        slice1{i, j} = im1(((i-1) * w) + 1:i * w, ((j-1) * w) + 1:j * w);
61  
        slice2{i, j} = im2(((i-1) * w) + 1:i * w, ((j-1) * w) + 1:j * w);
62  
    end
63  
end
64  
65  
% first step checking with 4 points of big diamond and the origin
66  
mad_org = zeros(r_time, c_time);
67  
min_mad = zeros(r_time, c_time);
68  
idx_min_mad = zeros(r_time, c_time);
69  
for i = 1:r_time
70  
    for j = 1:c_time       
71  
        s_h_r = ((i-1) * w) + 1;%slice head row
72  
        s_h_c = ((j-1) * w) + 1;%slice head column
73  
        diff.org{i, j} = abs(slice2{i, j} - slice1{i, j});
74  
        [r_diam c_diam] = size(pat.diam1);
75  
        for k = 1:c_diam
76  
            if s_h_r + pat.diam1(1, k) > 0 && s_h_c + pat.diam1(2, k) > 0
77  
                diff.diam1{1, k} = abs(slice1{i, j}- im2(s_h_r + pat.diam1(1, k):...
78  
                    i *w + pat.diam1(1, k),...
79  
                    s_h_c + pat.diam1(2, k):...
80  
                    j * w + pat.diam1(2, k)));
81  
                % calculating MAD = Mean Absolute Difference
82  
                diff.diam1{2, k} = sum(sum(diff.diam1{1,k})) / (w ^ 2);% insert each MAD below each Pat
83  
                mad(k) = sum(sum(diff.diam1{1,k})) / (w ^ 2);
84  
            else
85  
                diff.diam1{1, k} = 9999999999999;
86  
                diff.diam1{2, k} = 9999999999999;
87  
                mad(k) = sum(sum(diff.diam1{1,k})) / (w ^ 2);
88  
            end
89  
        end
90  
        % calculating minimum of mad in 4 pat and the origin and inserting
91  
        % them into a min_mad(i, j). where i, j decler the position of the
92  
        % slice in the image
93  
        mad_org(i , j) = sum(sum(diff.org{i,j})) / (w ^ 2);
94  
        mad = [mad mad_org(i, j)];
95  
        [min_mad(i, j) idx_min_mad(i, j)] = min(mad);
96  
        clear mad
97  
        
98  
    end
99  
end 
100  
% if the idx_min_mad == 5 it means that the origin has the minimum value of
101  
% mad (between 4 big diamond points and the origin the orogin has the
102  
% minimum value) otherwise the index in idx_min_mad shows the pat index that
103  
% has the min mad value.
104  
idx_min_mad2 = zeros(r_time, c_time);
105  
min_mad2 = zeros(r_time, c_time);
106  
for i = 1:r_time
107  
    for j = 1:c_time
108  
        clear mad
109  
        if idx_min_mad(i, j) == 5
110  
            % it means this point didn't moved and it's better to do not use
111  
            % any motion vectors so we must put [0; 0] for these points as a
112  
            % motion vector.accourding to the paper for any slices that 
113  
            % idx_min_mad(i, j) ==5 we must use anothe four points as new
114  
            % pat and check the slices with these i and j for mad. and the
115  
            % final solution for these slices is these mad. here we must
116  
            % use pat.diam2 as new patterns and repeat thise process again.
117  
            s_h_r = ((i-1) * w) + 1;%slice head row
118  
            s_h_c = ((j-1) * w) + 1;%slice head column
119  
%           diff.org{i, j} = abs(slice2{i, j} - slice1{i, j});
120  
            [r_diam c_diam] = size(pat.diam1);
121  
            for k = 1:c_diam
122  
                if s_h_r + pat.diam2(1, k) > 0 && s_h_c + pat.diam2(2, k) > 0
123  
                    diff.diam2{1, k} = abs(slice1{i, j}- im2(s_h_r + pat.diam2(1, k):...
124  
                        i *w + pat.diam2(1, k),...
125  
                        s_h_c + pat.diam2(2, k):...
126  
                        j * w + pat.diam2(2, k)));
127  
                    % calculating MAD = Mean Absolute Diffrence
128  
                    diff.diam2{2, k} = sum(sum(diff.diam2{1,k})) / (w ^ 2);% insert each MAD below each Pat
129  
                    mad(k) = sum(sum(diff.diam2{1,k})) / (w ^ 2);
130  
                else
131  
                    diff.diam2{1, k} = 9999999999999;
132  
                    diff.diam2{2, k} = 9999999999999;
133  
                    mad(k) = sum(sum(diff.diam2{1,k})) / (w ^ 2);
134  
                end
135  
            end
136  
            % calculating minimum of mad in 4 pat and the origin and inserting
137  
            % them into a min_mad(i, j). where i, j decler the position of the
138  
            % slice in the image
139  
%            mad_org(i , j) = sum(sum(diff.org{i,j})) / (w ^ 2);
140  
%            mad = [mad mad_org(i, j)];
141  
            [min_mad2(i, j) idx_min_mad2(i, j)] = min(mad);
142  
143  
        end
144  
    end
145  
end
146  
for i = 1:r_time
147  
    for j = 1:c_time
148  
        if idx_min_mad2(i, j) ~= 0
149  
            motion_vector{i , j} = pat.diam2(:, idx_min_mad2(i, j));
150  
        end
151  
    end
152  
end
153  
154  
% other points that their minimum mads idx ~= 5. it means that these slices
155  
% are closer to farder slices.
156  
idx_min_mad3 = zeros(r_time, c_time);
157  
min_mad3 = zeros(r_time, c_time);
158  
for i = 1:r_time
159  
    for j = 1:c_time
160  
        clear mad
161  
        if idx_min_mad(i, j) ~= 5
162  
            s_h_r = ((i-1) * w) + 1;%slice head row
163  
            s_h_c = ((j-1) * w) + 1;%slice head column
164  
%           diff.org{i, j} = abs(slice2{i, j} - slice1{i, j});
165  
            [r_hex c_hex] = size(pat.hexhor);
166  
            for k = 1:c_hex
167  
                if s_h_r + pat.hexhor(1, k) > 0 && s_h_c + pat.hexhor(2, k) > 0 && (idx_min_mad(i, j) == 1 || idx_min_mad(i, j) == 3)
168  
                    diff.hex{1, k} = abs(slice1{i, j}- im2(s_h_r + pat.hexhor(1, k):...
169  
                        i *w + pat.hexhor(1, k),...
170  
                        s_h_c + pat.hexhor(2, k):...
171  
                        j * w + pat.hexhor(2, k)));
172  
                    % calculating MAD = Mean Absolute Diffrence
173  
                    diff.hex{2, k} = sum(sum(diff.hex{1,k})) / (w ^ 2);% insert each MAD below each Pat
174  
                    mad(k) = sum(sum(diff.hex{1,k})) / (w ^ 2);
175  
                elseif s_h_r + pat.hexver(1, k) > 0 && s_h_c + pat.hexver(2, k) > 0 && (idx_min_mad(i, j) == 2 || idx_min_mad(i, j) == 4)
176  
                    diff.hex{1, k} = abs(slice1{i, j}- im2(s_h_r + pat.hexver(1, k):...
177  
                        i *w + pat.hexver(1, k),...
178  
                        s_h_c + pat.hexver(2, k):...
179  
                        j * w + pat.hexver(2, k)));
180  
                    % calculating MAD = Mean Absolute Diffrence
181  
                    diff.hex{2, k} = sum(sum(diff.hex{1,k})) / (w ^ 2);% insert each MAD below each Pat
182  
                    mad(k) = sum(sum(diff.hex{1,k})) / (w ^ 2);
183  
                else
184  
                    diff.hex{1, k} = 9999999999999;
185  
                    diff.hex{2, k} = 9999999999999;
186  
                    mad(k) = sum(sum(diff.hex{1,k})) / (w ^ 2);
187  
                end
188  
            end
189  
            % calculating minimum of mad in 4 pat and inserting
190  
            % them into a min_mad(i, j). where i, j decler the position of the
191  
            % slice in the image
192  
%            mad_org(i , j) = sum(sum(diff.org{i,j})) / (w ^ 2);
193  
%            mad = [mad mad_org(i, j)];
194  
            [min_mad3(i, j) idx_min_mad3(i, j)] = min(mad);
195  
196  
        end
197  
    end
198  
end
199  
% org_mov declare the movement vector for new pattern origins.
200  
org_mov = cell(r_time, c_time);
201  
for i = 1:r_time
202  
    for j = 1:c_time
203  
        if idx_min_mad3(i, j) ~= 0 && (idx_min_mad(i, j) == 1 || idx_min_mad(i, j) == 3)
204  
            org_mov{i , j} = pat.hexhor(:, idx_min_mad3(i, j));
205  
        elseif idx_min_mad3(i, j) ~= 0 && (idx_min_mad(i, j) == 2 || idx_min_mad(i, j) == 4)
206  
            org_mov{i , j} = pat.hexver(:, idx_min_mad3(i, j));
207  
        end
208  
    end
209  
end
210  
% now we must go the theird step. the minimum mad point found in the
211  
% previous search step is repositioned as the center point to form a new
212  
% hexagon nad only three new non overlaped points will be checked as
213  
% candidates each time. so we must define new pattern. this time our
214  
% patterns must have a dynamic behavior. and also these pattern must be
215  
% created based on the old pat.hexver and pat.hexhor
216  
[r_mov c_mov] = size(org_mov);
217  
idx_min_mad4 = zeros(r_mov, c_mov);
218  
min_mad4 = zeros(r_mov, c_mov);
219  
for i = 1:r_mov
220  
    for j = 1:c_mov
221  
        clear mad
222  
        nu = sparse(org_mov{i, j});
223  
        [r_nu c_nu] = size(nu);
224  
        if r_nu ~= 0 || c_nu ~= 0
225  
            for z = 1:c_hex
226  
                pat.hexver_new(:, z) = pat.hexver(:, z) + org_mov{i, j};
227  
                pat.hexhor_new(:, z) = pat.hexhor(:, z) + org_mov{i, j};
228  
            end
229  
            s_h_r = ((i-1) * w) + 1;%slice head row
230  
            s_h_c = ((j-1) * w) + 1;%slice head column
231  
%           diff.org{i, j} = abs(slice2{i, j} - slice1{i, j});
232  
            [r_hex c_hex] = size(pat.hexhor_new);
233  
            for k = 1:c_hex
234  
%                clear mad
235  
                if s_h_r + pat.hexhor_new(1, k) > 0 && s_h_c + pat.hexhor_new(2, k) > 0 && (idx_min_mad(i, j) == 1 || idx_min_mad(i, j) == 3)
236  
                    diff.hex{1, k} = abs(slice1{i, j}- im2(s_h_r + pat.hexhor_new(1, k):...
237  
                        i *w + pat.hexhor_new(1, k),...
238  
                        s_h_c + pat.hexhor_new(2, k):...
239  
                        j * w + pat.hexhor_new(2, k)));
240  
                    % calculating MAD = Mean Absolute Diffrence
241  
                    diff.hex{2, k} = sum(sum(diff.hex{1,k})) / (w ^ 2);% insert each MAD below each Pat
242  
                    mad(k) = sum(sum(diff.hex{1,k})) / (w ^ 2);
243  
                elseif s_h_r + pat.hexver_new(1, k) > 0 && s_h_c + pat.hexver_new(2, k) > 0 && (idx_min_mad(i, j) == 2 || idx_min_mad(i, j) == 4)
244  
                    diff.hex{1, k} = abs(slice1{i, j}- im2(s_h_r + pat.hexver_new(1, k):...
245  
                        i *w + pat.hexver_new(1, k),...
246  
                        s_h_c + pat.hexver_new(2, k):...
247  
                        j * w + pat.hexver_new(2, k)));
248  
                    % calculating MAD = Mean Absolute Diffrence
249  
                    diff.hex{2, k} = sum(sum(diff.hex{1,k})) / (w ^ 2);% insert each MAD below each Pat
250  
                    mad(k) = sum(sum(diff.hex{1,k})) / (w ^ 2);
251  
                else
252  
                    diff.hex{1, k} = 9999999999999;
253  
                    diff.hex{2, k} = 9999999999999;
254  
                    mad(k) = sum(sum(diff.hex{1,k})) / (w ^ 2);
255  
                end
256  
            end
257  
            % calculating minimum of mad in 4 pat and inserting
258  
            % them into a min_mad(i, j). where i, j declare the position of the
259  
            % slice in the image
260  
%            mad_org(i , j) = sum(sum(diff.org{i,j})) / (w ^ 2);
261  
            mad = [mad mad_org(i, j)];
262  
            [min_mad4(i, j) idx_min_mad4(i, j)] = min(mad);
263  
%              clear mad
264  
        end
265  
    end
266  
end
267  
% org_mov declare the movement vector for new pattern origins.
268  
% final motion vector calculation
269  
for i = 1:r_mov
270  
    for j = 1:c_mov
271  
        if idx_min_mad4(i, j) == 7 
272  
            motion_vector{i, j} = pat.org;
273  
        elseif idx_min_mad4(i, j) ~= 0 && (idx_min_mad(i, j) == 1 || idx_min_mad(i, j) == 3)
274  
            motion_vector{i , j} = pat.hexhor_new(:, idx_min_mad4(i, j));
275  
        elseif idx_min_mad4(i, j) ~= 0 && (idx_min_mad(i, j) == 2 || idx_min_mad(i, j) == 4)
276  
            motion_vector{i , j} = pat.hexver_new(:, idx_min_mad3(i, j));
277  
        end
278  
    end
279  
end
280  
281  
% now we want to find rep_motion vector
282  
motion_vectors = cat(2, motion_vector{:});
283  
most_motion_vector = zeros(1, r_time .* c_time);
284  
clear temp
285  
temp = motion_vectors;
286  
for i=1:r_time .* c_time
287  
    my_count = 0;
288  
    element(:, 1) = temp(:, i);
289  
    for k = i+1:r_time .* c_time
290  
        if temp(:, k) == element(:, 1)
291  
            my_count = my_count+1;
292  
%             temp(:, k) = [];
293  
        end
294  
    end
295  
    most_motion_vector(i) = my_count;
296  
end
297  
[value, idx] = max(most_motion_vector);
298  
rep_motion= motion_vectors(:, idx);

Author comment

from http://www.mathworks.com/matlabcentral/fileexchange/15767-fast-motion-detection-bugs-fixed-

download  show line numbers   

Snippet is not live.

Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #2000475
Snippet name: fastMV.m (fast motion detection in MATLAB)
Eternal ID of this version: #2000475/1
Text MD5: 58b7089023914955e95075a921fb6063
Author: stefan
Category:
Type: New Tinybrain snippet
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-08-01 16:28:49
Source code size: 13213 bytes / 298 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 715 / 128
Referenced in: [show references]