您当前的位置: 首页 >  matlab

slandarer

暂无认证

  • 2浏览

    0关注

    248博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

MATLAB 手把手教你如何将视频水彩风格化(简易版)

slandarer 发布时间:2021-05-15 21:55:43 ,浏览量:2

前言

原本想做视频动漫风格化的,动漫风格化要求图片色块分明,所以用到的是保边缘性极强的双边滤波,但由于双边滤波需要每张图片多次滤波才能出效果,等待时机较长,MATLAB处理循环的能力并不太适合。

事实上本篇文章主要就是教大家如何用matlab简单处理视频,因此我们选择较快的水彩风格化(简易版),但即使是这样长达一分钟的视频处理也足足耗了15分钟

处理效果: 在这里插入图片描述

步骤 1.导入视频

使用VideoReader函数可以导入视频,用法如下(2012版以后的matlab支持VideoReader):

movObj=VideoReader(‘test.mp4’);

这样导入的便是一个结构体 我们可以使用

disp(movObj)

或者

get(movObj)

来查看结构体的属性:

VideoReader - 属性:

常规属性: Name: ‘test.mp4’ Path: ‘E:\bin\matlabPS\edgeMovie’ Duration: 87.7480 CurrentTime: 0.0800 NumFrames: 了解更多

视频属性: Width: 1920 Height: 1080 FrameRate: 25 BitsPerPixel: 24 VideoFormat: ‘RGB24’

其中比较重要的属性有:

  • Duration:视频时长(秒)
  • FrameRate:帧率
  • NumFrames:帧数
2.获取每一帧图片
for k=1:movObj.NumFrames
     frame=read(movObj,k);
end

read(movObj,k)就是提取视频对象第k帧,而视频一共有movObj.NumFrames帧,这些都非常好理解。

3.处理视频每一帧

水彩有一种晕开的感觉,所以我们选择不注重边缘的均值或高斯滤波,再将其与边缘结合 原图: 在这里插入图片描述 sobel卷积: 乘不乘以1.2其实差不多,当然也可以选择matlab自带的sobel边缘检测,不过那样的话边缘没有灰度的差异

ed_img=(255-sobelConv2_gray(rgb2gray(frame))).*1.2;

    function sobelPic=sobelConv2_gray(oriPic)
        Hx=[-1 0 1;-2 0 2;-1 0 1];
        Hy=[1 2 1;0 0 0;-1 -2 -1];

        [rows,cols]=size(oriPic);
        exPic=uint8(zeros([rows+2,cols+2]));
        exPic(2:rows+1,2:cols+1)=oriPic;
        
        exPic(2:rows+1,1)=oriPic(:,1);
        exPic(2:rows+1,cols+2)=oriPic(:,cols);
        exPic(1,2:cols+1)=oriPic(1,:);
        exPic(rows+2,2:cols+1)=oriPic(rows,:);
        
        exPic(1,1)=oriPic(1,1);
        exPic(rows+2,1)=oriPic(rows,1);
        exPic(1,cols+2)=oriPic(1,cols);
        exPic(rows+2,cols+2)=oriPic(rows,cols);
        
        Gx=zeros([rows,cols]);Gy=Gx;
        
        for ii=1:3
            for jj=1:3
                tempPic=double(exPic(ii:rows+ii-1,jj:cols+jj-1));
                Gx=Gx+tempPic.*Hx(ii,jj);
                Gy=Gy+tempPic.*Hy(ii,jj);
            end
        end
        sobelPic=uint8(sqrt(Gx.^2+Gy.^2));
    end

在这里插入图片描述 高斯滤波:

ga_img=imgaussfilt(frame,5);

在这里插入图片描述 图片合成: 点开看大图效果明显一点

newFrame=uint8(double(ga_img).*double(ed_img)./255);

在这里插入图片描述

4.制作新视频

制作新视频首先要用VideoWriter函数创建视频对象

newObj=VideoWriter(‘waterColorResult’);

视频名称为waterColorResult,这里视频格式默认为avi,如果想要mp4格式之类的其他格式,要设置profile属性,例如(mp4格式):

newObj=VideoWriter(‘waterColorResult’,‘MPEG-4’);

设置新视频帧率: 和原视频帧率相同

newObj.FrameRate=movObj.FrameRate;

打开视频对象,并将每一帧写入新视频对象

open(newObj)
for k=1:movObj.NumFrames
     frame=read(movObj,k);
     ga_img=imgaussfilt(frame,5);
     ed_img=(255-sobelConv2_gray(rgb2gray(frame))).*1.2;
     newFrame=uint8(double(ga_img).*double(ed_img)./255);
     %下面这一行就是帧的写入
	 writeVideo(newObj,newFrame); 
end
close(newObj)
5.进度展示

理论上靠前四部已经能够制作出视频了,但是一个视频处理时间不短,我们需要一个进度显示的功能,类似下面这样:

close all;
fig=figure(1);
fig.NumberTitle='off';

for k=1:movObj.NumFrames
     %一大堆操作
     %。。。。。。
     %。。。。。。
     imshow(newFrame)
     fig.Name=['Frame:[',num2str(k),'/',num2str(movObj.NumFrames),']'];
end

这样就能在左上角显示处理进度啦: 在这里插入图片描述

6.完整代码
function waterColorMov
movObj=VideoReader('test.mp4');

newObj=VideoWriter('waterColorResult','MPEG-4'); 
newObj.FrameRate=movObj.FrameRate;
open(newObj)

close all;
fig=figure(1);
fig.NumberTitle='off';

tic
for k=1:movObj.NumFrames
     frame=read(movObj,k);
     ga_img=imgaussfilt(frame,5);
     ed_img=(255-sobelConv2_gray(rgb2gray(frame))).*1.2;
     newFrame=uint8(double(ga_img).*double(ed_img)./255);
	 writeVideo(newObj,newFrame);
     imshow(newFrame)
     fig.Name=['Frame:[',num2str(k),'/',num2str(movObj.NumFrames),']'];
end
toc
close(newObj)

    function sobelPic=sobelConv2_gray(oriPic)
        Hx=[-1 0 1;-2 0 2;-1 0 1];
        Hy=[1 2 1;0 0 0;-1 -2 -1];

        [rows,cols]=size(oriPic);
        exPic=uint8(zeros([rows+2,cols+2]));
        exPic(2:rows+1,2:cols+1)=oriPic;
        
        exPic(2:rows+1,1)=oriPic(:,1);
        exPic(2:rows+1,cols+2)=oriPic(:,cols);
        exPic(1,2:cols+1)=oriPic(1,:);
        exPic(rows+2,2:cols+1)=oriPic(rows,:);
        
        exPic(1,1)=oriPic(1,1);
        exPic(rows+2,1)=oriPic(rows,1);
        exPic(1,cols+2)=oriPic(1,cols);
        exPic(rows+2,cols+2)=oriPic(rows,cols);
        
        Gx=zeros([rows,cols]);Gy=Gx;
        
        for ii=1:3
            for jj=1:3
                tempPic=double(exPic(ii:rows+ii-1,jj:cols+jj-1));
                Gx=Gx+tempPic.*Hx(ii,jj);
                Gy=Gy+tempPic.*Hy(ii,jj);
            end
        end
        sobelPic=uint8(sqrt(Gx.^2+Gy.^2));
    end
end

当然如果不怕处理时间久的话可以尝试别的类型的风格化,and matlab 循环着实有点慢,其实可以考虑一下C++的。。。

原始视频: 链接:https://pan.baidu.com/s/1OMwX1MuDPr_558EBJZ3-FQ 提取码:jkt1

关注
打赏
1664692598
查看更多评论
立即登录/注册

微信扫码登录

0.1163s