2021 牛年快乐

祝福2021 新年快乐。那么下面,我们便来看看这个是怎么做的。
步骤如下:

1.找到一句 ‘2021 HAPPY niu Year'话,将之转为莫尔斯电码

'HAPPY NEW YEAR' NEW→ niu(拼音,牛) 是在网上看到的,很不错

2.将莫尔斯电码导出音频文件

这里利用了 CWplayer这个软件,它很方便地便可以将英文数字转为morse电码的音频导出 ,软件资源来源于“哈罗CQ火腿社区”

软件:CWplayer 截图

3.做出随着音频变化的图片流

视频是用一张张的图片随时间不断更新得到的。
在上面的视频中 图片变化即“点 划 空”的增加,在上图中,我们使用了71张图片用来叠加产生“点 划 空”的增加,同时将“2021 HAPPY niu YEAR”用一张图片产生,利用(Adobe Premiere Pro) ,Pr将之剪辑,使大致上每张图片对应到音频文件中声音随时间的变化,然后导出,保存,便完成了!

那么图片是怎么做出来的?当然,可以手画,71张图,也不慢。(比起想着仅用一次写程序来解决这个问题,快的多)
我 这里使用了matlab来做这个事情。

4.matlab 关于图片流的制作

4.1 音频的读入和时域图

通过该图,我们便能看到,约莫21秒的视频中,“点” “划”都是一个正弦函数,而空则保持为零。
空有两种 :
1. 字母(数字)与字母(数字)之间
2.单词(连起来字母数字)与单词(连起来的字母数字)之间

我们先对这个序列取个模值,那么 点 划 都是大于0的值,空则是等于零的值,我们还可以看到 点持续的时间比划短, 字母间空比单词间空短。

我们将大于0的值都看作1,则整个序列变成了 01序列, 再根据01的保持时间长度,我们便能区分出 点 划 空


由此 我们便从时域图上,将读出来的点 划 空,赋值给一个字符串数组。
它大概是这个样子“..--- -.-. ---."等等。
便读出来了音频信号中的莫尔斯电码
-----

4.1注释--①

1.整个图上分析很容易,但实际处理时,上述y(t)时间长度是21秒左右,而相邻离散的时刻的时间差值(约21/470000 秒),y-t变量是47万组数据,单单将y(t)中大于0的记为1(所以,我们进行了一定的采样处理,这里不展开了,最后我们处理的数据仅有4700左右,为原来的百分之一这个采样是对照前后采样的图试出来的结果),这个“01化”循环如下:

for i=1:length(y)%读取(遍历)整个数组
if(y(i)>0)
y(i)=1;
end
end
需要运行47万次

而计算0 1序列 01的保持方法:
则是 在遍历01序列的循环(用 i )中,在嵌套循环,例如:
现在是i=10,y是1,进入循环while(y(i)>0) i++;
当y(i)<0,跳出,计算跳出后的i值与最初的i值得差,就是这时 1的保持位数。
0则同理,下述为方法的测试代码
下述存在问题:
经验证 ,最后一位值,下述循环方法不计算, 认为影响不大,实际中,可以默认最后接收的信号没有

bianhua_01=[];bianhua_01_weishu=[];
% bianhua_01 是”01化“的原序列  bianhua_01_weishu 为相应01的保持位数
y1=[ 1 0 1 0 1 0 0 1];
i=1;
while i<=length(y1)-1
if(y1(1)==0)
   a=i;
   while(y1(i)<0.5&&i<length(y1))
   i=i+1;
   end
   bianhua_01=[bianhua_01 0];
   bianhua_01_weishu=[bianhua_01_weishu (i-a)];
   a=i;
   while(y1(i)>0.5&&i<length(y1)) 
   i=i+1; 
   end 
   bianhua_01=[bianhua_01 1]; 
   bianhua_01_weishu=[bianhua_01_weishu (i-a)]; 
else 
   a=i;
   while(y1(i)>0.5&&i<length(y1)) 
   i=i+1;
   end 
   bianhua_01=[bianhua_01 1];
   bianhua_01_weishu=[bianhua_01_weishu (i-a)]; 
   a=i-1;
   while(y1(i)<0.5&&i<length(y1))
   i=i+1; 
   end 
   bianhua_01=[bianhua_01 0]; 
   bianhua_01_weishu=[bianhua_01_weishu (i-a)]; 
   end
end

4.2 字符串数组与画图

由此 我们便从时域图上,将读出来的点 划 空,赋值给一个字符串数组。
它大概是这个样子“..--- -.-. ---."等等。
便读出来了音频信号中的莫尔斯电码

接上文,我们如何将字符串数组来操控画图呢?
步骤1:
1.导入 画图的”底板“、 点 划 空 基本元素的图片
每个单一元素大小都是 101(竖直)x100(水平)像素,
而底板则是 404x2400像素大小

2.逐个读取 “..--- -.-. ---."字符串变量的每一个字符,控制画图

%这里的x y则是实现在dipai(404x2400像素的空白图片上定义好位置)(见下方代码)
figure;
hold on
while (m<=length(jieguo))
    if(strcmp(jieguo(m),'.'))
        input=dian;
        
    elseif(strcmp(jieguo(m),'-'))
         input=hua;
    else
         input=kong;
    end
    if (m>length(jieguo))
        break;
    end
    dipai(x(m):x(m)+100,y(m):y(m)+99)=input;%循环在底板上画图
%这里的x y则是实现在dipai(404x2400像素的空白图片上定义好位置)
    imshow(dipai);
%imshow 配合 hold on - hold off  保证在在当前figure循环做图时,不断更新
    m=m+1;
end
hold off

最后运行,便是如下gif演示的结果

可惜,程序运行的快慢和音频中的快慢不一致,所以,最后只得保存每一帧的图片在Pr中完成了拼接!

但很不错,好嘞,牛年快乐!!!