赞
踩
注意:本程序根据 OpenMV采集图片通过串口发送,PC接收并保存为图片 更改。
这个例程主要实现了以下功能:
1. OpenMV 端采集图像:使用OpenMV开发板上的摄像头采集实时图像数据。
2. 通过串口传输图像数据:将采集到的图像数据打包成字节流,通过串口发送到连接的PC端。
3. PC端接收并保存图像:PC端接收来自OpenMV的图像数据,并使用OpenCV库将其解码保存为图片文件。
整个过程模拟了一个简单的图像采集-传输-保存的应用场景。OpenMV负责图像采集和数据发送,PC端负责接收和保存图像。这种基于串口通信的图像传输方式,对于一些嵌入式设备与PC之间的图像交互非常有用。
通过这个示例程序,可以学习如何在OpenMV和PC端进行串口通信,以及如何处理和保存接收到的图像数据。这对于开发基于OpenMV的图像采集和传输应用很有帮助。
使用说明:先运行PC端,再打开OpenMv。
我最初用的是 STM32 ARM SWD 仿真器调试器中的串口 如下图:
用这个传输速率较慢,它不支持 921600的波特率
简易使用TTL能经量减少卡顿,减少传输时间。
1. 导入模块
- import sensor
- import image
- import ustruct
- import pyb
- from pyb import Pin
程序导入了 sensor
模块、image
模块、ustruct
模块、pyb
模块和 Pin
类。其中,sensor
模块和 image
模块是用于控制 OpenMV 摄像头的模块,ustruct
模块用于打包和解包数据,pyb
模块用于控制 OpenMV 开发板的外设,Pin
类用于控制开发板的引脚。
2. 初始化摄像头和串口
- sensor.reset() # Initialize the camera sensor.
- sensor.set_pixformat(sensor.RGB565) # or sensor.RGB565
- sensor.set_framesize(sensor.QVGA) # or sensor.QVGA (or others)
- sensor.skip_frames(time = 2000) # Let new settings take affect.
-
- uart = pyb.UART(3, 921600) # 选择合适的串口号和波特率
程序使用 sensor.reset()
函数初始化摄像头,并设置摄像头的像素格式为 RGB565,帧大小为 QVGA。然后,程序使用 pyb.UART()
函数初始化串口,选择合适的串口号和波特率。
注意:帧对传输速率的影响 VAG ( 图片最大,速度最慢 )
QVAG ( 图片中等,速度中等 )
QQVAG ( 图片最小,速度最快 )
如果 921600 波特率不行,建议减小波特率。
3. 定义捕获和发送图像的函数
- def capture_and_send_image():
- # 捕获图像
- img = sensor.snapshot()
-
- # 将图像转换为JPEG格式
- img_compressed = img.compress(quality=50) #质量可以修改为 10 ~ 90
-
- # 计算图像大小
- size = ustruct.pack("<L", len(img_compressed))
-
- # 发送图像大小和数据
- uart.write(size)
- uart.write(img_compressed)
-
- # 等待接收到确认信号
- while uart.any() == 0:
- pass
-
- # 接收确认信号
- confirmation = uart.read(1)
-
- # 如果接收到的确认信号为 "#"
- if confirmation == b'#':
- # 发送停止信号 "#"
- uart.write(b'#')
定义一个名为 capture_and_send_image()
的函数,用于捕获图像并发送到串口。函数的主要步骤如下:
sensor.snapshot()
函数捕获实时图像数据。img.compress()
函数将图像数据压缩为 JPEG 格式,质量为 50。ustruct.pack()
函数将压缩后的图像大小打包为 4 字节的字节流。uart.write()
函数将图像大小和压缩后的图像数据发送到串口。uart.any()
函数等待串口接收到确认信号。uart.read()
函数读取串口接收到的确认信号。#
,则发送停止信号 #
。4. 主循环
- while True:
- capture_and_send_image()
程序使用一个无限循环不断调用 capture_and_send_image()
函数,实现连续捕获和发送图像的功能。
主要功能是在 PC 端接收通过串口传输的图像数据,并将接收到的图像数据解码并显示出来。
1. 导入所需的模块
- from ast import Import
- import cv2
- import serial
- import struct
- import time
- import numpy as np
代码导入了 ast
模块的 Import
类,cv2
模块用于图像处理和显示,serial
模块用于串口通信,struct
模块用于打包和解包数据,time
模块用于添加延时,numpy
模块用于处理图像数据。
2. 打开串口
ser = serial.Serial('COM4', 921600)
代码使用 serial.Serial()
函数打开串口,并指定串口号和波特率。需要将 'COM4'
替换为你实际使用的串口号,当然波特率也同openmv一致。
3. 显示图像的函数
- def imshow(img):
- cv2.imshow("Received Image", img)
- cv2.waitKey(1)
- key = cv2.waitKey(1)
- if key == 32: # 空格退出
- cv2.destroyAllWindows()
- while True:
- pass
这个函数用于解码并显示图像。它使用 cv2.imshow()
函数显示图像,使用 cv2.waitKey()
函数等待按键输入。如果按下空格键,窗口将关闭。
4. 接收和保存图像的函数
- def receive_and_save_image(output_path, file_preserve):
- size_data = ser.read(4)
- size = struct.unpack("<L", size_data)[0]
-
- image_data = ser.read(size)
-
- img = cv2.imdecode(np.frombuffer(image_data, dtype=np.uint8), cv2.IMREAD_COLOR)
-
- if file_preserve == 1:
- with open(output_path, 'wb') as file:
- file.write(image_data)
-
- ser.write(b'#')
-
- stop_signal = ser.read(1)
- if stop_signal == b'#':
- return img, True
- else:
- return img, False
这个函数用于接收通过串口传输的图像数据,并将图像数据解码为图像。它首先读取图像大小,然后根据大小读取图像数据。接下来,使用 cv2.imdecode()
函数将图像数据解码为图像。如果 file_preserve
参数为 1,则将图像数据保存到指定的文件路径。然后,发送确认信号 #
到串口,并等待接收停止信号。如果接收到停止信号 #
,则返回解码后的图像和 True
;否则返回解码后的图像和 False
。
5. 主循环
- output_image_path = 'received_image.jpg'
-
- while True:
- #key = int(input("请输入: "))
- key = 1
- if key == 0:
- break
-
- while key == 1:
- img, uart_img_key = receive_and_save_image(output_image_path, 0)
- if uart_img_key:
- imshow(img)
- break
这个循环用于不断接收和显示图像。在循环内部,调用 receive_and_save_image()
函数接收图像,并将返回的图像数据传递给 imshow()
函数进行显示。如果接收到的图像数据有效,即 uart_img_key
为 True
,则退出内部循环。
这里key可以换成输入,来进行调试。
6. 关闭串口和窗口
- ser.close()
- cv2.destroyAllWindows()
在循环结束后,关闭串口和窗口。
- import sensor
- import image
- import ustruct
- import pyb
- from pyb import Pin
-
-
- sensor.reset() # Initialize the camera sensor.
- sensor.set_pixformat(sensor.RGB565) # or sensor.RGB565
- sensor.set_framesize(sensor.QVGA) # or sensor.QVGA (or others)
- sensor.skip_frames(time = 2000) # Let new settings take affect.
-
- # 初始化相机
- #sensor.reset()
- #sensor.set_pixformat(sensor.RGB565)
- #sensor.set_framesize(sensor.VGA) # 分辨率可以修改为QQVGA、QVGA等
- #sensor.skip_frames(time=500)
-
- # 初始化串口
- #uart = pyb.UART(3, 115200) # 选择合适的串口号和波特率
- uart = pyb.UART(3, 921600) # 选择合适的串口号和波特率
-
- # 初始化I/O
- #p_in = Pin('P9', Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻
- # value = p_in.value() # get value, 0 or 1#读入p_in引脚的值
-
- # 捕获并发送图像
- def capture_and_send_image():
- # 捕获图像
- img = sensor.snapshot()
-
- # 将图像转换为JPEG格式
- img_compressed = img.compress(quality=50) #质量可以修改为 10 ~ 90
-
- # 计算图像大小
- size = ustruct.pack("<L", len(img_compressed))
-
- # 发送图像大小和数据
- uart.write(size)
- uart.write(img_compressed)
-
- # 等待接收到确认信号
- while uart.any() == 0:
- pass
-
- # 接收确认信号
- confirmation = uart.read(1)
-
- # 如果接收到的确认信号为 "#"
- if confirmation == b'#':
- # 停止发送图像
- #while uart.any():
- #if uart.any():
- # uart.readchar()
-
- # 发送停止信号 "#"
- uart.write(b'#')
-
- # 主循环
- while True:
- capture_and_send_image() # 捕获并发送图片
-
- #coding:GBK
- from ast import Import
- import cv2
- import serial
- import struct
- import time
- import numpy as np
-
- # 打开串口
- ser = serial.Serial('COM4', 921600) # 将 COM1 替换为你的串口号和相应的波特率
- #ser = serial.Serial('COM3', 115200) # 将 COM1 替换为你的串口号和相应的波特率
-
-
- def imshow (img):
- # 解码图像数据
- #img = cv2.imdecode(np.frombuffer(image_data, dtype=np.uint8), cv2.IMREAD_COLOR)
-
- # 显示图像
- cv2.imshow("Received Image", img)
- cv2.waitKey(1)
- key = cv2.waitKey(1)
- if key == 32: #空格退出
- cv2.destroyAllWindows()
- while True:
- pass
-
-
-
-
- # 接收图像并保存
- #file_preserve = 1 保存图片文件
- def receive_and_save_image(output_path, file_preserve):
- # 读取图像大小
- size_data = ser.read(4)
- size = struct.unpack("<L", size_data)[0]
-
- # 读取图像数据
- image_data = ser.read(size)
-
- # 解码图像数据
- img = cv2.imdecode(np.frombuffer(image_data, dtype=np.uint8), cv2.IMREAD_COLOR)
-
-
- # 保存图像
- if file_preserve == 1:
- with open(output_path, 'wb') as file:
- file.write(image_data)
-
- # 发送确认信号 "#"
- ser.write(b'#')
-
- # 接收停止信号
- stop_signal = ser.read(1)
- if stop_signal == b'#':
- #imshow(image_data)
- return img,True
- else:
- return img,False
-
- # 图像保存路径
- output_image_path = 'received_image.jpg'
-
-
- while True:
- # 在需要延时的地方调用sleep()函数
- #time.sleep(0.01) # 延时0.1秒
- # 循环接收并保存图像
- #key = int(input("请输入: "))
- key = 1
- if key == 0:
- break
-
- while key == 1:
- img, uart_img_key = receive_and_save_image(output_image_path, 0, 0)
- if uart_img_key:
- imshow(img)
- break
-
- # 关闭串口
- ser.close()
- cv2.destroyAllWindows()
-
1. OpenMV采集图片通过串口发送,PC接收并保存为图片
2. OpenMv详细参数
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。