/
vidpreproc.m
118 lines (99 loc) · 3.61 KB
/
vidpreproc.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
function [ ppvid, background ] = vidpreproc(vid, etime, outpath, crop)
%VIDPREPROC Bee tag pipeline video preprocessor
% Extracts the active region from a given video file and generates a
% background image of the active region. The active region is determined
% by computing the variance of image pixels over time. A full-width and
% partial height video is saved (.mj2) if the active region is
% successfully detected. The background image is generated by computing
% the mean of image pixels over time. A background image (.png) is saved
% for the active region (if detected) or the entire video region.
%
% SYNTAX
% [ ppvid, background ] = vidpreproc(vid, etime, outpath)
%
% DESCRIPTION
% [ ppvid, background ] = vidpreproc(vid, etime, outpath) accesses the
% video specified by the video handle vid, and computes the active region
% and background image from the videos current time to the end time
% specified by etime. The output files are written to the directory
% specified by outpath. This function returns the preprocessed video
% handle and the background image. If the active region was not detected,
% ppvid is set to vid.
%
% AUTHOR
% Blair J. Rossetti
%
% DATE LAST MODIFIED
% 2016-05-10
% check MATLAB version
legacy = verLessThan('matlab', '9.0');
% get video info
stime = vid.CurrentTime;
[~,name, ~] = fileparts(vid.Name);
% calculate mean for background
numFrames = 1;
meanImg = double(readFrame(vid));
while hasFrame(vid) && vid.CurrentTime <= etime
meanImg = meanImg + double(readFrame(vid));
numFrames = numFrames + 1;
end
meanImg = meanImg./numFrames;
% reset CurrentTime
vid.CurrentTime = stime;
if crop
% calculate variance for active region
varImg = (double(readFrame(vid)) - meanImg).^2;
while hasFrame(vid) && vid.CurrentTime <= etime
varImg = varImg + (double(readFrame(vid)) - meanImg).^2;
end
varImg = varImg./(numFrames-1);
% reset CurrentTime
vid.CurrentTime = stime;
% convert to grayscale
varImg = rgb2gray(mat2gray(varImg));
% threshold
if legacy
mask = im2bw(varImg, graythresh(varImg));
else
mask = imbinarize(varImg);
end
% clean mask
mask = imdilate(mask,strel('square',3));
mask = imfill(mask, 'holes');
% get bbox of largest object
stats = regionprops(mask,'Area', 'BoundingBox');
[~,idx] = max([stats.Area]);
bbox = round(stats(idx).BoundingBox);
% extract active region
if bbox(4)/size(varImg,1) > 0.05 && bbox(4)/size(varImg,1) < 0.99 && bbox(2) < size(varImg,1)/3
% create preprocessed video
ppvidpath = fullfile(outpath,[name '_preprocessed.mj2']);
ppvid = VideoWriter(ppvidpath,'Archival');
open(ppvid)
while hasFrame(vid) && vid.CurrentTime <= etime
frame = readFrame(vid);
writeVideo(ppvid, frame(bbox(2):bbox(2)+bbox(4)-1,:,:))
end
close(ppvid)
% reset CurrentTime
vid.CurrentTime = stime;
% define background image
background = uint8(meanImg(bbox(2):bbox(2)+bbox(4)-1,:,:));
imwrite(background, fullfile(outpath,[name '_background.png']));
% get preprocessed video handle
ppvid = VideoReader(ppvidpath);
else
% define background image
background = uint8(meanImg);
imwrite(background, fullfile(outpath,[name '_background.png']));
% use raw video
ppvid = vid;
end %if-else
else
% define background image
background = uint8(meanImg);
imwrite(background, fullfile(outpath,[name '_background.png']));
% use raw video
ppvid = vid;
end %if-else
end %function