基于Sipeed M1s Dock综合应用-网络相机
本片文章分享我在硬禾学堂的2023年寒假在家一起练活动,基于Sipeed M1s Dock综合应用的网络相机的流程及效果展示
标签
嵌入式系统
显示
2023年寒假在家一起练
反正都一样
更新2023-03-28
406

Fqwmbpq7-jbjgKdNx1PvLLmd_myb

项目介绍

本项目我通过使用硬禾学堂提供的m1s dock完成基于sipeed m1s cock综合应用的网络项目任务,该项目作品需要板卡与电脑端两边都运行程序互相配合,效果为,在电脑端开始拍摄后,会不断接收板卡发来的图像数据,并将其保存在特定目录下,在电脑端点下停止拍摄后,停止接收板卡发来的图像数据,并把已经保存的图片转换为视频

流程图

                                                               FmDPYPqrnxPrHd57nXaqJPnUlqhC

主要硬件介绍

本次板卡的硬件资源较为丰富,主芯片 BL808 RISC-V 480Mhz + NPU BLAI-100,板载 USB 转 UART 调试器,1.69 寸 240x280 电容触摸屏,200W 像素摄像头,板载 1 个模拟麦克风、1 个 LED、1 个 TF 卡座。在我的项目中,我主要是用到了摄像头这个模块。

FlSWZQakSCDGyZiU_aAJuC2EK0QY

主要软件介绍

在软件实现上,在板卡与电脑上都需要运行程序才可。

板卡我们可以从官方的SDK及示例网站上进行下载使用https://gitee.com/sipeed/M1s_BL808_example,下载下来后,需要我们先对环境进行配置。

cd ~/bl808 && mkdir M1s_BL808_SDK/toolchain

mv {your_download_path}/Xuantie-900-gcc-elf-newlib-x86_64-V2.2.4-20220715.tar.gz ~/bl808
tar -zxvf Xuantie-900-gcc-elf-newlib-x86_64-V2.2.4-20220715.tar.gz -C M1s_BL808_SDK/toolchain/

cd M1s_BL808_SDK/toolchain && mv Xuantie-900-gcc-elf-newlib-x86_64-V2.2.4/ Linux_x86_64 && cd -

cd ~/bl808/M1s_BL808_example/c906_app/

# Configure environment variables (Executed only once per working environment)
export BL_SDK_PATH=$(pwd)/../M1s_BL808_SDK

# Compile the hello_world project
./build.sh hello_world

最后的build.sh执行程序,后面加上相应的文件名,就可对相应的示例程序进行编译了。而我的项目里是直接对示例程序camera_streaming_through_wifi进行修改并使用的,该程序是官方在2月份刚更新,如果没有,重新拉库进行了。

void main()
{
    vTaskDelay(1);
    bl_cam_mipi_mjpeg_init();

    m1s_xram_wifi_init();
    m1s_xram_wifi_connect("WIFI有毒", "zhan1234");//对这里进行修改
    m1s_xram_wifi_upload_stream("192.168.1.112", 8889);//对这里进行修改
}

将main.c中的两处进行修改,分别是wifi名wifi密码,电脑端的ip地址,电脑端程序的端口。这些函数都是现实了什么功能,感兴趣的话可以自己深入研究。

便遗完成后,便可烧录进板卡中,至于烧录方式,https://wiki.sipeed.com/hardware/zh/maix/m1s/other/start.html官方介绍两种,一种是通过电脑上的烧录工具,一种是使用板卡的OTG功能,我使用的是第二种,因为比较快捷方便,按住上下两个键,再按rst复位键即可,电脑上会跳出盘符,直接拖动文件进板卡在电脑上显示的盘符中即可

FsjpcnWzWu_7hmtoV6t9mKi3F_TE

烧录成功后,连接上uart口子,串口工具选择较小的串口号,复位后,会显示一下信息

Starting bl808 now....
Heap Info: 63458 KB @ [0x0x0000000050207510 ~ 0x0x0000000054000000]
[OS] Starting aos_loop_proc task...
[OS] Start c906 xram handle...
[OS] Starting OS Scheduler...
init ring:0,tx:0x0000000022020140,rx:0x0000000000000000
init ring:2,tx:0x0000000022021340,rx:0x0000000022020340
init ring:3,tx:0x0000000022022540,rx:0x0000000022022340
init ring:4,tx:0x0000000022022840,rx:0x0000000022022740
init ring:5,tx:0x0000000000000000,rx:0x0000000000000000
Init CLI with event Driven
-------------------scan_i2c_bus--------------------
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
slv_addr[0x3c]
try matching the sensor module [BF2013]
try matching the sensor module [C2399]
try matching the sensor module [C2496]
try matching the sensor module [GC0308]
try matching the sensor module [GC0328]
try matching the sensor module [GC1054]
try matching the sensor module [GC2053]
try matching the sensor module [GC2093]
try matching the sensor module [OV2685]
-----------camera id 2685 
ID matched
Initialize sensor module [OV2685]

说明,板卡上的程序已经准备完毕了

至于电脑上的程序,则是使用python脚本制作而成,主要功能代码如下

def generate_video():
    for root, dirs, files in os.walk(path+'./img/'):
        for file in files:
            list.append(file) # 获取目录下文件名列表
            list.sort(key=lambda x: int(x[:-4])) #文件名按数字排序,不然会卡帧
    video = cv.VideoWriter('myvideo01.avi', cv.VideoWriter_fourcc(*'MJPG'),10,(800,600))
    print(len(list))
    for i in range(1, len(list)):
        img = cv.imread(path +'./img/' + list[i - 1])
        img = cv.resize(img, (800, 600))
        video.write(img)
    #釋放资源
    print("视频生成成功" + path + '\\myvideo01.avi')#给个弹策提示吧
    showinfo('网络相机' , '图像转换视频 完成')
    video.release()



def start_transfer():
    global flag

    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立即释放,否则的话在30秒-2分钟之内这个端口是不会被释放的,这是TCP的为了保证传输可靠性的机制。
    tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 给客户端绑定端口号,客户端需要知道服务器的端口号才能进行建立连接。IP地址不用设置,默认就为本机的IP地址。
    tcp_server.bind(("", 8889))
    # 设置监听
    # 128:最大等待建立连接的个数, 提示: 目前是单任务的服务端,同一时刻只能服务与一个客户端,后续使用多任务能够让服务端同时服务与多个客户端
    # 不需要让客户端进行等待建立连接
    # listen后的这个套接字只负责接收客户端连接请求,不能收发消息,收发消息使用返回的这个新套接字tcp_client来完成
    tcp_server.listen(128)
    # 等待客户端建立连接的请求, 只有客户端和服务端建立连接成功代码才会解阻塞,代码才能继续往下执行
    # 1. 专门和客户端通信的套接字: tcp_client
    # 2. 客户端的ip地址和端口号: tcp_client_address
    tcp_client, tcp_client_address = tcp_server.accept()
    # 代码执行到此说明连接建立成功
    print("摄像头连接成功,IP端口号为:", tcp_client_address)
    pic_num = 1
    while True:
        if flag == 1:
            # 接收客户端发送的数据, 这次接收数据的最大字节数是4
            recv_data = tcp_client.recv(4)
            mjpeg_len = int.from_bytes(recv_data, 'little')
            print("recv len: ", mjpeg_len)
            tcp_client.send(recv_data)
            recv_data_mjpeg = b''
            remained_bytes = mjpeg_len
            while remained_bytes > 0:
                recv_data_mjpeg += tcp_client.recv(remained_bytes)
                remained_bytes = mjpeg_len - len(recv_data_mjpeg)
            print("recv stream success")
            if recv_data_mjpeg[:2] != b'\xff\xd8' \
                    or recv_data_mjpeg[-2:] != b'\xff\xd9':
                continue
            mjpeg_data = np.frombuffer(recv_data_mjpeg, 'uint8')
            img = cv.imdecode(mjpeg_data, cv.IMREAD_COLOR)

            #cv.imshow('stream', img)
            # 保存图片
            cv.imwrite(path + './img/' + str(pic_num) + '.jpg', img)
            print("已将" + str(pic_num) + ".jpg图片成功保存!")
            pic_num += 1
        elif flag == 0:
            print("停止获取")
            generate_video()
            break

FpvBWIwHxrGmtIMqyvOk_DxIL_ER

一个是接收板卡发来的图片数据并保存在相应目录下,其中接收图片数据的部分是直接使用官方的示例。另一个则是停止接收图片数据,并将已经收集到的图片数据转换成视频,得到的视频文件名myvideo01.avi,保存路径可以自己设置。

其中用到到了opencv,tkinter,threading库,可以自己一一导入使用。

具体的效果,可以看上方视频链接进行观看。

主要的收获和遇到的困难

通过本次的实践练习,我对摄像头和网络传输的了解更加深入,编程能力得到一定程度的提升,尤其是对原理图的使用有了更深刻的理解。在平时的学习生活中曾接触过网络通信的使用,故对本次的活动项目产生了极为浓厚的兴趣。但在编程的过程中,也意识到了自己的不足。首先是在电子方向上仍然存在着很多还未了解的专业知识,其次是代码的编写略显累赘,期望在下次的活动中有所改善。

 

附件下载
例程.zip
团队介绍
个人
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号