由于一些特殊原因,我又拿出了尘封已久的自制相机(ESP32-CAM)。
突发奇想,既然视频本质上是一帧帧图片构成的,那么让相机全速运行去拍照,再后期合成视频应该是可行的。
原因:白平衡没调好
解决方案:后期调整
不过,我使用的摄像头型号为OV2640,应该自带白平衡调整功能。
可以看出又可以自动调整白平衡和亮度了,我不明白……
VGA大小(640x480,推荐),最大UXGA(1600x1200,帧率低)
通过在源代码添加一点语句,我们可得出ESP32在拍摄单张图片(VGA大小)时平均会耗时80ms,换算过来就是12.5FPS。
5秒的视频(图片)占用<3MB。
<20¥,不计SD卡。
5V,这里用的是充电宝。
ESP32-CAM
TF卡
主程序由ESP32-CAM Take Photo and Save to MicroSD Card | Random Nerd Tutorials修改而来。
x1
2
3
4
5
6
7
8
9
10// define the number of bytes you want to access
11
12
13// Pin definition for CAMERA_MODEL_AI_THINKER
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32int pictureNumber = 0;
33long int frame = 0;
34int a = 0;
35int b = 0;
36
37void setup() {
38 WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
39 Serial.begin(115200);
40 camera_config_t config;
41 config.ledc_channel = LEDC_CHANNEL_0;
42 config.ledc_timer = LEDC_TIMER_0;
43 config.pin_d0 = Y2_GPIO_NUM;
44 config.pin_d1 = Y3_GPIO_NUM;
45 config.pin_d2 = Y4_GPIO_NUM;
46 config.pin_d3 = Y5_GPIO_NUM;
47 config.pin_d4 = Y6_GPIO_NUM;
48 config.pin_d5 = Y7_GPIO_NUM;
49 config.pin_d6 = Y8_GPIO_NUM;
50 config.pin_d7 = Y9_GPIO_NUM;
51 config.pin_xclk = XCLK_GPIO_NUM;
52 config.pin_pclk = PCLK_GPIO_NUM;
53 config.pin_vsync = VSYNC_GPIO_NUM;
54 config.pin_href = HREF_GPIO_NUM;
55 config.pin_sscb_sda = SIOD_GPIO_NUM;
56 config.pin_sscb_scl = SIOC_GPIO_NUM;
57 config.pin_pwdn = PWDN_GPIO_NUM;
58 config.pin_reset = RESET_GPIO_NUM;
59 config.xclk_freq_hz = 20000000;
60 config.pixel_format = PIXFORMAT_JPEG;
61/*
62 FRAMESIZE_96x96, // 96x96
63 FRAMESIZE_QQVGA, // 160x120
64 FRAMESIZE_QQVGA2, // 128x160
65 FRAMESIZE_QCIF, // 176x144
66 FRAMESIZE_HQVGA, // 240x176
67 FRAMESIZE_240x240, // 240x240
68 FRAMESIZE_QVGA, // 320x240
69 FRAMESIZE_CIF, // 400x296
70 FRAMESIZE_VGA, // 640x480
71 FRAMESIZE_SVGA, // 800x600
72 FRAMESIZE_XGA, // 1024x768
73 FRAMESIZE_SXGA, // 1280x1024
74 FRAMESIZE_UXGA, // 1600x1200
75 FRAMESIZE_QXGA, // 2048*1536
76 FRAMESIZE_INVALID
77*/
78 if(psramFound()){
79 config.frame_size = FRAMESIZE_VGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
80 config.jpeg_quality = 10;
81 config.fb_count = 2;
82 } else {
83 config.frame_size = FRAMESIZE_SVGA;
84 config.jpeg_quality = 12;
85 config.fb_count = 1;
86 }
87 // Init Camera
88 esp_err_t err = esp_camera_init(&config);
89 if (err != ESP_OK) {
90 Serial.printf("Camera init failed with error 0x%x", err);
91 return;
92 }
93 //Serial.println("Starting SD Card");
94 if(!SD_MMC.begin()){
95 Serial.println("SD Card Mount Failed");
96 return;
97 }
98 uint8_t cardType = SD_MMC.cardType();
99 if(cardType == CARD_NONE){
100 Serial.println("No SD Card attached");
101 return;
102 }
103 camera_fb_t * fb = NULL;
104
105 // initialize EEPROM with predefined size
106 EEPROM.begin(EEPROM_SIZE);
107 pictureNumber = EEPROM.read(0) + 1;
108 // Path where new picture will be saved in SD Card
109 String path = "/" + String("Video") + String(pictureNumber);
110 fs::FS &fs = SD_MMC;
111 fs.mkdir(path.c_str());
112 Serial.printf("Picture file name: %s\n", path.c_str());
113 EEPROM.write(0, pictureNumber);
114 EEPROM.commit();
115
116 while(1) { //这个也可以放在loop()函数里
117 //a = millis();
118 // Take Picture with Camera
119 fb = esp_camera_fb_get();
120 if(!fb) {
121 Serial.println("Camera capture failed");
122 return;
123 }
124 String framePath = path + "/" + String(frame) + ".jpg";
125 File file = fs.open(framePath.c_str(), FILE_WRITE);
126 if(!file){
127 Serial.println("Failed to open file in writing mode");
128 }
129 else {
130 file.write(fb->buf, fb->len); // payload (image), payload length
131 //Serial.printf("Saved file to path: %s\n", framePath.c_str());
132 }
133 file.close();
134 esp_camera_fb_return(fb);
135 frame++;
136 //b = millis();
137 //Serial.print(b - a);
138 }
139}
140
141void loop() {}
图片合成视频软件:如何将多张连续图像帧合并为视频哔哩哔哩bilibili
希望玩的开心(要是可以的话)
如果能优化代码就告诉我方法呗