目标:实现加载任意视频文件,并按帧取指定图像区域的某颜色值代表该区域的颜色值。

1. 加载视频文件

加载视频文件使用函数VideoReader,输入为文件夹路径,返回为一个VideoReader对象,具体使用方法见​​创建对象以读取视频文件 - MATLAB - MathWorks 中国​

vidObj = VideoReader('FIR_032.MOV');
width = vidObj.Width;
height = vidObj.Heigh;

2. 对调用VideoReader的调用内置函数,按照顺序读取每一帧。 

while hasFrame(vidObj)
vidFrame = readFrame(vidObj);
imshow(vidFrame)
pause(0.01)
end

 vidFrame即3d数据,也就是一幅图像。

3.1 计算vidFrame指定区域的颜色均值

将h*w*3的输入3维矩阵img,转化为高度h*w,宽度3的矩阵,然后计算列均值mean(:,1)即img的平均颜色。

FL = vidFrame(1:height,1:width,:);
FL = img(1:height/2,1:width/2,:);
RGB = MeanRGB(img);

function rgb = meanRGB(img)
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
rgb = uint8(mean(double(rimg),1));
end

除此之外,还提供以下以某个颜色值代表整个区域颜色值的方法:

3.2 颜色最大值

注意,在此处为了更好的效果,并非对rgb三个通道分别取最大值(这样基本结果为#ffffff),而是看作一个整体取最大值,即计算r^2+g^2+b^2最大的颜色值。

同理转化为高度h*w,宽度3的矩阵,用sum(X.^2,2)计算每行所有元素的平方值和,取max得到对应的索引index,并转换维原始三维矩阵下的索引[X,Y]。

function rgb = maxRGB(img) 
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
value = sum(double(rimg).^2,2);
[~,index] = max(value);
x = mod(index, h);
if x == 0
x = h;
end
y = ceil(index / h);
rgb = img(x,y,:);
rgb = reshape(rgb, [1,3]);
% if max(rgb) < 140
% rgb= [0,0,0];
% end
end

3.3 第三个四分位(排序后75%位置的颜色)

总体思路和3.2相似,不过将max换为prctile(x,75)

function rgb = quantileRGB(img) 
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
value = sum(double(rimg).^2,2);
quavlaue = prctile(value,75);
%存在误差导致可能find(quavlaue==value)结果为空,因此修改为绝对差小于100
index = find(abs(quavlaue-value) < 100, 1);
x = mod(index, h);
if x == 0
x = h;
end
y = ceil(index / h);
rgb = img(x,y,:);
rgb = reshape(rgb, [1,3]);
end

3.4 指定位置颜色(例如最中心)

转化为二维矩阵后取行数的一半即原始中心区域。

function rgb = selectRGB(img) 
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
rgb = rimg(h*w/2,:);
end

4. 得到rgb后进行处理,保存。

完整实例:

vidObj = VideoReader('FIR_032.MOV');
width = vidObj.Width / 2;
height = vidObj.Height / 2;
i = 0;
data = zeros(vidObj.NumFrames + 2, 18);
while hasFrame(vidObj)
vidFrame = readFrame(vidObj);
i = i + 1;
img = vidFrame;
FL = img(1:height,1:width,:);
FR = img(1:height,width + 1:2 * width,:);
RL = img(height +1 :2 * height,1:width,:);
RR = img(height +1 :2 * height,width + 1:2 * width,:);
newdata = zeros(1,18);
newdata(1:12) = [meanRGB(FL), meanRGB(FR), meanRGB(RL),meanRGB(RR)];
newdata(17) = 1;
data(i + 1,:) = newdata;
end
% vidObj = VideoReader('Fireworks Display At Night.MP4');
% width = vidObj.Width / 2;
% height = vidObj.Height / 2;
% i = 0;
% data = zeros(vidObj.NumFrames + 1, 18);
% while hasFrame(vidObj)
% vidFrame = readFrame(vidObj);
% i = i + 1;
% img = vidFrame(:,:,:);
% FL = img(1:height,1:width,:);
% FR = img(1:height,width + 1:2 * width,:);
% RL = img(height +1 :2 * height,1:width,:);
% RR = img(height +1 :2 * height,width + 1:2 * width,:);
% newdata = zeros(1,18);
% newdata(1:12) = [quantileRGB(FL), quantileRGB(FR), quantileRGB(RL),quantileRGB(RR)];
% for j = 1 : 4
% if (max(newdata((j - 1) * 3 + 1: j * 3)) > 200)
% newdata(12 + j) = 1;
% end
% end
%
% data(i + 1,:) = newdata;
% end
function rgb = selectRGB(img)
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
rgb = rimg(h*w/2,:);
end
function rgb = meanRGB(img)
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
rgb = uint8(mean(double(rimg),1));
if rgb(2) > rgb(1)
rgb(2) = rgb(3);
end
end
function rgb = quantileRGB(img)
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
value = sum(double(rimg).^2,2);
quavlaue = prctile(value,75);
index = find(abs(quavlaue-value) < 100, 1);
x = mod(index, h);
if x == 0
x = h;
end
y = ceil(index / h);
rgb = img(x,y,:);
rgb = reshape(rgb, [1,3]);
end
function rgb = maxRGB(img)
h = size(img,1);
w = size(img,2);
rimg = reshape(img,[h*w,3]);
value = sum(double(rimg).^2,2);
[~,index] = max(value);
x = mod(index, h);
if x == 0
x = h;
end
y = ceil(index / h);
rgb = img(x,y,:);
rgb = reshape(rgb, [1,3]);
if max(rgb) < 140
rgb= [0,0,0];
end
end