电影条形码的制作

Tesia ·
更新时间:2024-09-21
· 533 次阅读

2017年的时候,我发现了网上流传了一种东西叫电影条形码,当时很感兴趣,但是不知道怎么做,还去了知乎提问,但是没有得到答案,如今疫情在家闲来无事,自己写了个程序,制作并优化了一下条形码

Reddit网友etherealpenguin做了一件很好玩的事儿:他用Java做了一个程序,可以截取电影中每一帧画面的颜色的平均色。他选了几部喜欢的电影截取平均色,然后把所有帧的颜色都压进了一张图里,看起来就像是这个电影的专属条形码。

但是我不认同平均色这种做法,因为他没有上下的变化,整个画面只有一种颜色,这是不太准确的。本文选择了kmeans聚类选择主色调

其次如果一帧一长条的话太长了,我选成1秒1长条

由于我们习惯从左向右看图,所以我们可以对每一行取一个主色调。使用kmeans聚类算法

对Matlab的kmeans函数,解释如下:

[Idx,C,sumD,D]=kmeans(X,K,para1,var1,para2,var2,……)
[Idx]=……
[Idx,C]=……
[Idx,C,sumD]=……
[Idx,C,sumD,D]=……

X N*P的数据矩阵
K 表示将X划分为几类,为整数
Idx N*1的向量,存储的是每个点的聚类标号
C K*P的矩阵,存储的是K个聚类质心位置
sumD 1*K的和向量,存储的是类间所有点与该类质心点距离之和
D N*K的矩阵,存储的是每个点与所有质心的距离

para
Distance距离测度(默认欧氏距离)
sqEuclidean欧氏距离
cityblock绝对误差和,L1范数
cosine针对向量,余弦距离
correlation针对时序关系的值
Hamming二进制数据,汉明距离

para
Start初始质心位置选择方法(默认sample)
从数据集中随机选取K个质心
uniform根据数据的分布范围均匀的随机生成K个质心
cluster初始聚类阶段随机选取10%的数据集子样本
Replicates聚类重复次数,为整数

para……(太多了写不完)
display,emptyaction……

生成条形码的代码如下:这是竖版的,有兴趣的同学可以自己做一下横板的,代码改一下很方便

videopath='.\video\1.mp4';%视频路径 saveimgpath='.\frame\';%保存帧的路径 savepath='.\result\barcode1.jpg';%保存条形码图片的路径 savedatapath='.\result\barcode1.mat';%保存原条形码数据的路径 imshow(run(videopath,saveimgpath,savepath,savedatapath)/256)%生成条形码、显示条形码 function [barcode]=run(videopath,saveimgpath,savepath,savedatapath)%生成条形码 num=readvideo(videopath,saveimgpath);%获取总共有多少帧 imgpathtemp=strcat(saveimgpath,num2str(1),'.jpg');%获取第一帧 [h,~,~]=size(imread(imgpathtemp));%读取第一帧,获取电影画面的宽度 barcode=zeros(h,num,3);%初始化条形码 parfor i=1:num barcode(:,i,:)=make(imread(strcat(saveimgpath,num2str(i),'.jpg')));%读取每一帧的主色调并保存为条形码 end end function [P]=make(I)%获取图像主色调 I=double(I);%要使用kmeans,所以换成double [h,w,~]=size(I);%获取边长大小 P=ones(h,1,3);%把每一帧的主色存为h乘以1的条形 for j=1:h [~,c]=kmeans(reshape(I(j,:,:),w,3),1,'distance','sqEuclidean');%c是聚类中心,也就是我们的主色调,这一帧所有像素点的颜色都里这个颜色附近 P(j,1,:)=roundn(c,0);%分配这一条的这一个点的RGB值 end end function [s]=readvideo(fileName,path) obj=VideoReader(fileName);%读取视频 numFrames=obj.NumFrames;%获取帧的总数 skep=roundn(obj.FrameRate,0);%每秒的帧数 parfor k = 1:numFrames%读取数据,每秒只取一帧 if(mod(k-1,skep)==0) imwrite(read(obj,k),strcat(path,num2str(((k-1)/skep)+1),'.jpg'));%保存帧 end end s=((numFrames-1)/skep)+1; end

看下结果吧,首先我选取的电影是:

然后生成的条形码是:

可以注意到,在竖方向上是存在纹理的,如果想做横着的也是同理,这里我没试。

最后放一个我最喜欢的电影《堕落天使》,用时8819.287905s,我的电脑是8代i5低电压

可是这个太长了,MATLAB里面有imresize函数可以修改一下尺寸,我修改成了和我电脑分辨率一样的:1366*768

这是春光乍泄的:

可以发现王家卫的电影的色调很相似


作者:施垚



电影 条形码

需要 登录 后方可回复, 如果你还没有账号请 注册新账号