4802浏览
查看: 4802|回复: 5

[ESP8266/ESP32] FireBeelte 做一个全自动拍照平台

[复制链接]
全世界公认摄影是法国L·达盖尔于1839年发明的。他是一位风景画家,专业画舞台背景,当时风景画、绘画时流行一种工具——暗箱。暗箱的作用:风景物透过镜头进入暗箱中,再经过反光镜再反射到位于暗箱上方的磨砂玻璃上,再在磨砂玻璃上铺上画布作画。显而易见,这种近似于作弊的方法能够帮助画家绘制出准确的作品,用今天通俗语言的描述就是“如同照相机一般”,用艺术的语言可以称作“超现实主义”。
FireBeelte 做一个全自动拍照平台图1
路易·雅克·芒代·达盖尔(Louis Jacques Mande Daguerre),1787-1851
1839年8月19日的巴黎大街,熙熙攘攘,比肩继踵,来自世界各地、对摄影感兴趣的科学家和艺术家,将街上的光学商店挤得满满当当。原来在当天,法国科学院和艺术院的联席会议向全世界宣布:法国政府收购了“达盖尔摄影法”(daguerreotype)的发明专利,并将这项技术赠给世界。【参考2】
“达盖尔式摄影法”只是一种单纯的“正像”工艺:首先用碘蒸汽将一块经过仔细清洁、抛光的镀银铜版“光敏化”,再放入照相机曝光形成潜影,然后用汞蒸汽“显影”(development),然后用大苏打溶液“定影”(fixing bath),最终形成一个稳定的正像。不过,“达盖尔摄影法”虽然成像精细,细节丰富,但也只是一种“孤本”摄影术,因为拍摄一次只能得到一个影像左右相反的银版“正像”。
1888年,乔治·伊斯曼(Geotge Eastman)发明了一种照相机,能把照片记录在滚动的感光纸上。这种被命名为柯达(Kodak)的照相机非常简单,不熟练的业余爱好者都能用它来拍摄照片。第二年,伊斯曼引人了透明的赛璐路(celluloid)胶卷,在走向电影的过程中取得了突破性进展。
1888年,托马斯·爱迪生(Thomas Edison),这位已经发明了留声机和电灯泡的成功发明家,决定设计一台制作和放映活动影像的机器。他把伊斯曼胶片切成一英寸宽的带子(约为35毫米),然后首尾粘连,并在每一格胶片的两边钻四个孔,以便齿轮能将胶片拖过摄影机和活动电影放映机。迪克生在早期的这一决定影响了电影的整个历史。35毫米、每格四个齿孔,已经成为规范。
FireBeelte 做一个全自动拍照平台图2
活动放映机
1894年,卢米埃兄弟——路易和奥古斯特,设计出一台优雅的小型摄影机,活动电影(Cinematographe),这台摄影机使用了35毫米胶片,和与缝纫机类似的间歇运动机构。卢米埃兄弟做出的一个重要决定,是以每秒钟16格拍摄影片(而不是爱迪生使用的每秒钟46格);这种速度在大约二十五年内都是国际标准的电影速度。
FireBeelte 做一个全自动拍照平台图3
1895年12月28日,历史上最著名的一场电影放映出现了。放映地点是巴黎大咖啡馆的一个房间。那些日子,咖啡馆是一个聚会的地方,人们在那里吸饮咖啡,阅读报纸,享受歌手和其他表演者的助兴演出。那天晚上,时髦的顾客们支付一个法郎,就可以观看由每部长约一分钟的十部影片组成的一段二十五分钟的节目。放映的影片包括奥古斯特·卢米埃和他的妻子喂孩子的近景,一个男孩踩住水管导致困惑的园丁让水浇了自己一身的戏剧化喜剧场景(后来被命名为《水浇园丁》)以及《工厂大门》等。
FireBeelte 做一个全自动拍照平台图4
【参考3】
从上面可以看出很难把电影的发明归功于单独某个人。并不是在某一时刻,电影突然就出现了。实际上,活动影像技术来自多重贡献的累积,主要源于美国、德国、英国和法国。史学家们认为,卢米埃尔兄弟所拍摄和放映已经脱离了实验阶段,并完成了电影商业化。因此,他们把1895年12月28日世界电影首次公映之日即定为电影诞生之时,卢米埃尔兄弟自然当之无愧地成为 “电影之父”。
从上面也可以看出,如果连续拍摄照片并且连续在大屏幕上播放出来就能够实现电影的技术。有时候我们需要制作一个360°展示物品的视频。这次就制作一个能够控制手机全角度拍摄的设备。从原理上介绍就是让云台旋转一个角度,手机自动拍照,然后再旋转一个角度,再次拍摄,最终从照片来生成视频。这样做的好处是:手机拍摄视频分辨率有限,笔者的华为手机最高只能拍摄1920x1080分辨率的视频,但是相机轻松可以达到2736x3648的分辨率,高像素模式能拍摄5472x7296像素的照片。用获得的照片很容易制作出4K 视频。


zoologist  高级技匠
 楼主|

发表于 2021-2-18 21:29:19

首先,从淘宝上购买一个旋转云台。基本参数有旋转速度,供电方式,称重等等。对于我们来说,需要选择一个USB 外部供电的,其他参数都可以忽略。
FireBeelte 做一个全自动拍照平台图1
接下来进行硬件设计。主控采用 DFRobot 的 FireBeelte ,它的核心是 ESP32 功能强大,特别是提供了蓝牙。
主控部分电路如下:USBMale 是设计给整个设备供电的,可以将一个充电宝作为电源从这里接入提供电力;其中的H1 是一个跳线,当使用 USB 线和 FireBeelte通讯时,需要断开这个位置,防止电流倒灌。
FireBeelte 做一个全自动拍照平台图2
因为预期使用充电宝提供电力,这里还特别设计了一个用于方式充电宝自动关机的电路如下。充电宝为了节省电力,当外部负载小于100ma超过一定时间后会自动切断供电(我的小米充电宝大约是30秒)。云台电力消耗在 40ma 左右,远低于这个阈值。这里使用一个三极管,POWERCNS 是 FireBeelte D4 ,当其为高时,R3上电流为 122ma; 当为低时,R3上电流为 0.1pa。
FireBeelte 做一个全自动拍照平台图3
我并不会计算三极管的电流,为此我使用来自https://www.falstad.com/circuit/e-pnp.html 的在线工具。绘制好电路图后可以通过拉动Base Voltage 来调整最左侧的电压。
FireBeelte 做一个全自动拍照平台图4
最后是  FireBelte D2 来控制 VCC5 提供给云台的电流,D2 是一个 DAC pin,我们能够调整它上面的电压从而达到控制云台电流的目的。
FireBeelte 做一个全自动拍照平台图5
PCB设计如下,上面是USB 母头用于连接到云台,下面是USB 公头,用于从充电宝取电。
FireBeelte 做一个全自动拍照平台图6
3D 预览如下:
FireBeelte 做一个全自动拍照平台图7

回复

使用道具 举报

zoologist  高级技匠
 楼主|

发表于 2021-2-18 21:33:40

为了更好的显示状态,使用了FireBeetle萤火虫OLED12864显示屏 来展示当前状态信息,这款屏幕引脚使用情况如下:
FireBeelte 做一个全自动拍照平台图1
其中 D2 D8 是用于检测 A B 两个按键,A0 用于检测方向的五个按键, SPI 引脚用于取字模信息,I2C 用于和屏幕通讯。
代码设计如下:
  1. #include "DFRobot_OLED12864.h"
  2. #include <BleKeyboard.h>
  3. BleKeyboard bleKeyboard;
  4. #define PULSEDELAY 10000UL
  5. #define KEYA D3
  6. #define KEYB D8
  7. #define MAXCYCLES 700
  8. const uint8_t I2C_addr = 0x3c;
  9. const uint8_t pin_SPI_cs = D5;
  10. boolean AKeyPressed=false;
  11. boolean BKeyPressed=false;
  12. DFRobot_OLED12864 OLED(I2C_addr, pin_SPI_cs);
  13. void KeyAInterrupt()
  14. {
  15.   AKeyPressed=true;
  16. }
  17. void KeyBInterrupt()
  18. {
  19.   BKeyPressed=true;
  20. }
  21. void ShowString(char line1[],char line2[],char line3[],char line4[])
  22. {
  23.   if (line1!="") {      
  24.       OLED.disStr(0, 0, "               ");
  25.       OLED.disStr(0, 0,line1);
  26.     }
  27.   if (line2!="") {
  28.       OLED.disStr(0, 16,"               ");
  29.       OLED.disStr(0, 16,line2);
  30.     }
  31.   if (line3!="") {
  32.       OLED.disStr(0, 32,"               ");
  33.       OLED.disStr(0, 32,line3);
  34.     }
  35.   if (line4!="") {
  36.       OLED.disStr(0, 48,"               ");
  37.       OLED.disStr(0, 48,line4);
  38.     }
  39.    
  40.   OLED.display();
  41. }
  42. void setup(void)
  43. {
  44.   Serial.begin(115200);
  45.   OLED.init();
  46.   OLED.flipScreenVertically();
  47.   pinMode(KEYA, INPUT_PULLUP);
  48.   pinMode(KEYB, INPUT_PULLUP);
  49.   pinMode(D2,ANALOG);
  50.   dacWrite(D2,0);
  51.   pinMode(D4,OUTPUT);
  52.   digitalWrite(D4,LOW);
  53.   attachInterrupt(D3, KeyAInterrupt, FALLING);
  54.   attachInterrupt(D8, KeyBInterrupt, FALLING);
  55.   
  56.   bleKeyboard.begin();
  57.   
  58. }
  59. String inString;
  60. unsigned long Elsp=0;
  61. unsigned int Cycles=0;
  62. const char     str_num[] = "0123456789";
  63. char str_temp[] = "第0000次";
  64. void numToStr(char *ch, int dat)
  65. {
  66.   int var = dat;
  67.   ch[3] = str_num[var / 1000]
  68.   ;
  69.   ch[4] = str_num[var / 100 % 10];
  70.   ch[5] = str_num[var / 10 % 10];
  71.   ch[6] = str_num[var % 10];
  72. }
  73. byte Status=0;
  74. void loop(void)
  75. {
  76.    // 每隔PULSEDELAY发送一次脉冲,让充电宝持续输出
  77.    if (Elsp<millis()) {
  78.          digitalWrite(D4,HIGH);
  79.          delay(200);
  80.          digitalWrite(D4,LOW);
  81.          Elsp=millis()+PULSEDELAY;
  82.     }
  83.    
  84.    // 任何状态下如果蓝牙中断都会跳入状态4
  85.    if ((Status==1)||(Status==2)||(Status==4)||(Status==5)) {
  86.       if (bleKeyboard.isConnected()==false) {
  87.             Status=4;
  88.             ShowString("蓝牙断开","","","");
  89.             dacWrite(D2,0);
  90.             pinMode(D4,OUTPUT);
  91.             digitalWrite(D4,LOW);
  92.             ShowString("","","A或者B键重新开始","已经停止");
  93.       }
  94.     }
  95.    
  96.    // 状态4 中检查按键
  97.    if (Status==4) {
  98.         // 按下 A 或者 B 都会重新等待连接
  99.         if ((AKeyPressed)||(BKeyPressed)) {
  100.           Status=0;
  101.           Cycles=0;
  102.           // 清除按键状态
  103.           AKeyPressed=false; BKeyPressed=false;
  104.           ShowString("",""," "," ");
  105.         }
  106.    }
  107.    //状态0 等待蓝牙连接
  108.    if (Status==0) {
  109.         ShowString("等待蓝牙连接","","","");
  110.         delay(1000);
  111.         if (bleKeyboard.isConnected()) {
  112.             ShowString("蓝牙已连接","","A 键暂停","旋转中.....");
  113.             Status=1;
  114.         }
  115.     }
  116.     // 状态1 旋转一圈
  117.     if (Status==1) {
  118.         // 按下 A 键
  119.         if (AKeyPressed) {
  120.             ShowString("","","按A继续按B清零","暂停中.....");
  121.             //进入状态5
  122.             Status=5;
  123.             // 清除按键状态
  124.             AKeyPressed=false; BKeyPressed=false;            
  125.         }
  126.         dacWrite(D2,200);
  127.         delay(100);
  128.         dacWrite(D2,0);
  129.         // 显示当前圈数
  130.         numToStr(str_temp, Cycles);
  131.         OLED.disStr(0, 16, str_temp);
  132.         OLED.display();
  133.         Cycles++;
  134.         // 等待旋转停止
  135.         delay(3000);
  136.         bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
  137.         // 等待相机拍照
  138.         delay(500);
  139.         // 如果当前已经达到最大圈数,那么进入状态2
  140.         if (Cycles>MAXCYCLES) {
  141.             ShowString("","","A/B重新开始","完成圈数停止");   
  142.             Status=2;
  143.             }
  144.     }  
  145.    
  146.     // 状态2,达到最大圈数
  147.     if (Status==2) {
  148.       // 如果有按键就返回状态1
  149.       if ((AKeyPressed)||(BKeyPressed)) {
  150.           Cycles=0;
  151.           Status=1;
  152.           ShowString("","","A 键暂停","旋转中.....");         
  153.           // 清除按键状态
  154.           AKeyPressed=false; BKeyPressed=false;
  155.         }
  156.     }
  157.    
  158.    //状态5 暂停状态
  159.    if (Status==5) {
  160.         // 如果有A按键就返回状态1
  161.         if (AKeyPressed) {
  162.             ShowString("","","A键暂停","旋转中.....");   
  163.             Status=1;
  164.             // 清除按键状态
  165.             AKeyPressed=false;
  166.         }
  167.         // 如果有B按键就返回状态1,圈数清零
  168.         if (BKeyPressed) {
  169.             ShowString("","","A键暂停","旋转中.....");         
  170.             Cycles=0;
  171.             Status=1;
  172.             // 清除按键状态
  173.             BKeyPressed=false;
  174.         }               
  175.     }  
  176. }
复制代码
例如,使用上面的方法可以拍摄出 700张照片,之后使用下面的批处理对文件进行重命名,将之前IMG_20210130_093136.jpg这样的文件命名为 00001.jpg 这样的文件。
  1. SETLOCAL ENABLEDELAYEDEXPANSION
  2. set /A num=0
  3. FOR /F "tokens=*" %%i in ('dir /A-D /B /OD /TC') do (
  4.     IF NOT "%%i"=="%~n0%~x0" (
  5.         set /A num+=1
  6.         if !num! LSS 10 (
  7.             ren "%%i" 0000!num!%%~xi
  8.         ) ELSE (
  9.             if !num! LSS 100 (
  10.                 ren "%%i" 000!num!%%~xi
  11.             ) ELSE (
  12.                 if !num! LSS 1000 (
  13.                     ren "%%i" 00!num!%%~xi
  14.                 ) ELSE (
  15.                     if !num! LSS 10000 ren "%%i" 0!num!%%~xi
  16.                 )
  17.             )
  18.         )
  19.     )
  20. )
  21. ENDLOCAL
复制代码


回复

使用道具 举报

zoologist  高级技匠
 楼主|

发表于 2021-2-18 21:40:52

重命名前:
FireBeelte 做一个全自动拍照平台图1
重命名后:
FireBeelte 做一个全自动拍照平台图2
之后再使用 ffmpeg 来将文件生成影片格式,命令如下:
ffmpeg-f image2 -i z:\%05d.jpg -vcodec mjpeg_qsv -r 20 -s 3648x2736  -y sixshot.mp4
运行之后生成的结果如下:
FireBeelte 做一个全自动拍照平台图3
生成的文件可以用Formatplayer 或者 PotPlayer 这种万能播放器直接查看,如果视频清晰度超过你的显示器,在播放过程中还可以随时放大查看。
FireBeelte 做一个全自动拍照平台图4
上图为正常播放

FireBeelte 做一个全自动拍照平台图5
可以放大播放直接能够看清楚字迹

另外,推荐开源的视频剪辑软件OpenShotVideoEditor来对生成的影片进一步处理,比如,可以添加片头或者背景音乐。推荐这款软件额外的原因是,这是一个开源的软件,它支持导出高分辨率影片。
FireBeelte 做一个全自动拍照平台图6
最近在看张鸣先生的书,他在上面提出了一个观点:传统观点认为火车的出现导致之前从事运输行业的人员失业,但是从他的调查研究来看火车的出现同样创造了新的岗位,比如:之前的运输行业人员进入站点从事卸货之类的工作,同样的列车的到来会使得当地人有机会将农副产品更直接的出售。这样的观点对错我不清楚,但是很明显照相技术的发明并没有使得画家失业,人们或者需要美术从业者将自己拍摄的漂亮,或者需要他们直接将底片中的人物修改的漂亮。换句话说,只要人类对于美的追求依然存在,绘画就能作为一种技能继续存在。
参考:


回复

使用道具 举报

zoologist  高级技匠
 楼主|

发表于 2021-2-18 21:44:12

拍摄制作的电影可以在下面看到:

1.生成的原始电影,1.7G
https://www.bilibili.com/video/BV1gA411M7yP/

2.使用软件处理后的电影
https://www.bilibili.com/video/BV1s54y1Y7mM/
回复

使用道具 举报

hnyzcj  版主

发表于 2021-2-19 08:10:19

赞一个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail