首先推荐一个microPython的库:
https://github.com/lemariva/micropython-camera-driver
好像是俄罗斯小伙的!很香
具体编译过程我下篇写,这里就写一下客户端和接受段的代码:
import socket
import camera
camera.init(0, format=camera.JPEG)
camera.flip(0)
camera.mirror(1)
camera.framesize(camera.FRAME_SVGA)
camera.speffect(camera.EFFECT_NONE)
camera.whitebalance(camera.WB_HOME)
camera.saturation(0)
camera.brightness(0)
camera.contrast(0)
camera.quality(10)
# 拍照,buf为jpg二进制数据,可以直接存储为jpg
buf = camera.capture()
# 客户端(esp32 cam)
# 服务端地址和端口,127.0.0.1改成你的服务端地址
ADDR = ('127.0.0.1', 10086)
print("发送UDP包...")
# socket连接
sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
# 拍照发送
while True:
buf = camera.capture()
# 发送数据
sendSock.sendto(buf, ADDR)
print("发送完毕...")
# 关闭socket连接
sendSock.close()
先建立一个Sock的对象,然后循环的发送就好,最后关闭。这里是一帧一帧的发出去的。
# 服务端
import cv2
import os
import socket
import time
# 客户端ip及端口,为空则接收任意客户端发来的数据
ADDR = ('', 10086)
recvSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
recvSock.bind(ADDR)
# 这里时间戳用来命名图片文件
time_e = int(time.time())
# 当前时间戳的第N帧
zz = 0
# 总帧数,此次为测试,可具体参考帧数来设置(我测试的效果大概为每秒6帧,录制20s,所以达到120张照片停止循环)
num = 0
print("等待数据...")
while True:
# 接收的数据大小,建议比图片本身大,不然无法传输
data = recvSock.recv(100000)
# 每次检查时间戳
time_b = int(time.time())
# 每次循环帧数加1
zz = zz + 1
# 如果时间戳+1秒,则帧数序号归零
if time_b != time_e:
time_e = time_b
zz = 0
# 存储图片
filename = str(time_e) + str(zz) + '.jpg'
with open(filename, 'wb') as f:
f.write(data)
f.close()
print(filename)
# 总帧数
num = num + 1
if num == 120:
break
# 将图片合成视频
pic_path = '.'
pics_list = [i for i in os.listdir(pic_path) if i.endswith('.jpg')]
fps = 7 # 帧率,自行参考文件命名,我的大概是7
size = (800, 600) # 视频尺寸,请根据图片实际尺寸设置,不然无法合成,SVGA为800*600
out_file_name = '{0}.mp4'.format('示例视频') # 输出视频名称
out_path = '.' # 输出视频路径
out_file = os.path.join(out_path, out_file_name)
fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
video = cv2.VideoWriter(out_file, fourcc, fps, size)
for item in pics_list:
item = out_path + '/' + item
img = cv2.imread(item)
video.write(img)
video.release()
以上代码在电脑上面跑。
这里是一个接收端初始化代码,以及最重要的建立接收端口
将接收的数据循环的接收。
文件的保存使用,时间戳加,帧数,加jpg文件后缀。
data = recvSock.recv(100000)
将data写入f。
这里就要120帧,够了就不要了。
开始合成,永远记住,图像的世界就是一帧一帧的。封装初始化参数。
写入到视频。