matlab打开视频文件并提取颜色数据

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

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

你可能感兴趣的:(计算机视觉与图像处理,matlab,开发语言)