庐山派K230,初步探索,按键(触摸)拍照保存TF卡,边缘检测,多通道显示等
按键与触摸拍照:用户既可以通过物理按键,也可以通过触摸屏幕的特定区域来触发拍照功能,拍摄的照片将被保存到 TF 卡中。图像边缘检测:对摄像头捕获的图像进行边缘检测处理,增强图像的特征信息,以便后续的图像分析和处理。多通道显示:利用摄像头的多个通道同时捕获不同分辨率和格式的图像,并在显示屏上进行多窗口显示,提供更丰富的视觉信息。通过以上代码的实现,我们成功利用庐山派 K230 开发板完成了按键(触摸
·
一、引言
庐山派 K230 是一款功能强大的开发板,具备丰富的硬件资源和多样化的接口,为开发者提供了广阔的应用开发空间。本文将围绕庐山派 K230 开发板,详细阐述如何实现按键(触摸)拍照并保存到 TF 卡、图像边缘检测以及多通道显示等功能。通过对代码的深入分析和详细注释,帮助开发者更好地理解和掌握相关技术,为后续的开发工作奠定基础。
二、功能概述
本次开发主要实现了以下几个核心功能:
- 按键与触摸拍照:用户既可以通过物理按键,也可以通过触摸屏幕的特定区域来触发拍照功能,拍摄的照片将被保存到 TF 卡中。
- 图像边缘检测:对摄像头捕获的图像进行边缘检测处理,增强图像的特征信息,以便后续的图像分析和处理。
- 多通道显示:利用摄像头的多个通道同时捕获不同分辨率和格式的图像,并在显示屏上进行多窗口显示,提供更丰富的视觉信息。
三、代码实现与详细解释
3.1 导入必要的库
import time, os, sys
from media.sensor import *
from media.display import *
from media.media import *
from machine import Pin
from machine import FPIOA
import time
from machine import Timer
from machine import TOUCH
from machine import WDT
time:用于处理时间相关的操作,如延时、计时等。os:提供了与操作系统进行交互的功能,如文件操作、系统退出点设置等。sys:包含了一些与 Python 解释器和系统相关的变量和函数。media.sensor:用于操作摄像头传感器,实现图像的捕获和配置。media.display:负责显示屏的初始化和图像的显示。media.media:提供媒体管理相关的功能。machine.Pin:用于控制开发板的 GPIO 引脚。machine.FPIOA:用于引脚功能的配置。machine.Timer:用于创建和管理定时器。machine.TOUCH:用于处理触摸事件。machine.WDT:用于实现看门狗定时器,确保系统的稳定性。
3.2 初始化硬件参数
sensor_id = 2
sensor = None
picture_width = 800
picture_height = 480
tp = TOUCH(0)
# 创建FPIOA对象,用于初始化引脚功能配置
fpioa = FPIOA()
# 设置引脚功能,将指定的引脚配置为普通GPIO功能
fpioa.set_function(62,FPIOA.GPIO62)
fpioa.set_function(20,FPIOA.GPIO20)
fpioa.set_function(63,FPIOA.GPIO63)
fpioa.set_function(53,FPIOA.GPIO53)
# 实例化Pin62, Pin20, Pin63为输出,分别用于控制红、绿、蓝三个LED灯
LED_R = Pin(62, Pin.OUT, pull=Pin.PULL_NONE, drive=7) # 红灯
LED_G = Pin(20, Pin.OUT, pull=Pin.PULL_NONE, drive=7) # 绿灯
LED_B = Pin(63, Pin.OUT, pull=Pin.PULL_NONE, drive=7) # 蓝灯
# 按键引脚为53,按下时为高电平,所以这里设置为下拉并设置为输入模式
button = Pin(53, Pin.IN, Pin.PULL_DOWN) # 使用下拉电阻
# 初始化时先关闭所有LED灯
LED_R.high() # 关闭红灯
LED_G.high() # 关闭绿灯
LED_B.high() # 关闭蓝灯
status = 0
flag_button = 0
# 显示模式选择:可以是 "VIRT"、"LCD" 或 "HDMI"
DISPLAY_MODE = "LCD"
# 根据模式设置显示宽高
if DISPLAY_MODE == "VIRT":
# 虚拟显示器模式
DISPLAY_WIDTH = ALIGN_UP(1920, 16)
DISPLAY_HEIGHT = 1080
elif DISPLAY_MODE == "LCD":
# 3.1寸屏幕模式
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 480
elif DISPLAY_MODE == "HDMI":
# HDMI扩展板模式
DISPLAY_WIDTH = 1920
DISPLAY_HEIGHT = 1080
else:
raise ValueError("未知的 DISPLAY_MODE,请选择 'VIRT', 'LCD' 或 'HDMI'")
sensor_id:指定摄像头传感器的 ID。picture_width和picture_height:定义拍摄照片的宽度和高度。tp:实例化触摸模块对象。fpioa:创建 FPIOA 对象,用于配置引脚功能。LED_R、LED_G、LED_B:分别控制红、绿、蓝三个 LED 灯的引脚对象。button:按键引脚对象,设置为下拉输入模式。DISPLAY_MODE:选择显示模式,根据不同的模式设置显示的宽度和高度。
3.3 定时器与看门狗初始化
def LED_toggle(timer):
"""
定时器回调函数,用于周期性地切换绿灯的状态
:param timer: 定时器对象
"""
LED_G.value(not LED_G.value())
# 创建一个软件定时器实例,-1 表示使用软件定时器
tim = Timer(-1)
# 配置定时器为周期模式(PERIODIC),每隔2000毫秒(2秒)调用一次 LED_toggle 函数
tim.init(period=2000, mode=Timer.PERIODIC, callback=LED_toggle)
# 实例化 WDT1,超时时间设置为 3 秒
wdt1 = WDT(1, 8)
LED_toggle:定时器的回调函数,用于周期性地切换绿灯的状态,作为系统运行的一个简单指示。tim:创建软件定时器对象,设置为周期模式,每隔 2 秒调用一次LED_toggle函数。wdt1:实例化看门狗定时器,超时时间设置为 3 秒,用于确保系统在出现异常时能够自动复位。
3.4 摄像头与显示初始化
try:
# 构造一个具有默认配置的摄像头对象
sensor = Sensor(id=sensor_id,width=1920, height=1080)
# 重置摄像头sensor
sensor.reset()
# 无需进行镜像和翻转
# 设置不要水平镜像
sensor.set_hmirror(False)
# 设置不要垂直翻转
sensor.set_vflip(False)
sensor.set_framesize(width=picture_width, height=picture_height, chn=CAM_CHN_ID_0)
# 设置通道0的输出像素格式为RGB565
sensor.set_pixformat(Sensor.RGB565, chn=CAM_CHN_ID_0)
# 通道2 320*240
sensor.set_framesize(Sensor.QVGA, chn = CAM_CHN_ID_1)
sensor.set_pixformat(Sensor.GRAYSCALE, chn = CAM_CHN_ID_1)
# 通道3 320*240
sensor.set_framesize(Sensor.QVGA, chn = CAM_CHN_ID_2)
sensor.set_pixformat(Sensor.RGB565, chn = CAM_CHN_ID_2)
# 根据模式初始化显示器
if DISPLAY_MODE == "VIRT":
Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, fps=60)
elif DISPLAY_MODE == "LCD":
Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
elif DISPLAY_MODE == "HDMI":
Display.init(Display.LT9611, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
# 初始化媒体管理器
MediaManager.init()
# 启动传感器
sensor.run()
# 丢掉前面100帧数据,防止摄像头还不稳定
#for i in range(100):
# sensor.snapshot()
fps = time.clock()
number = 1
read_number = 1
sensor:创建摄像头对象,并进行初始化和配置,包括图像尺寸、像素格式、镜像和翻转设置等。Display.init:根据选择的显示模式初始化显示器。MediaManager.init:初始化媒体管理器。sensor.run:启动摄像头传感器。fps:用于计算帧率。number:用于记录保存照片的编号。
3.5 主循环处理
while True:
fps.tick() # 更新帧率计数器
os.exitpoint() # 检查系统退出点
img = sensor.snapshot(chn=CAM_CHN_ID_0) # 捕获通道0的图像
# 在图像上绘制两个同心圆
img.draw_circle(720, 240, 25, color=(255, 255, 255), thickness = 1, fill=True)
img.draw_circle(720, 240, 40, color=(200, 200, 200), thickness = 10)
# 捕获通道1的图像
src_img = sensor.snapshot(chn=CAM_CHN_ID_1)
# 对通道1的图像进行拉普拉斯边缘检测
src_img.laplacian(2,mul=0.2)
# 在屏幕上显示通道1经过处理后的图像
Display.show_image(src_img, x = 0,layer = Display.LAYER_OSD1,alpha = 80)
sr_img = sensor.snapshot(chn=CAM_CHN_ID_2)
#Display.show_image(sr_img, x = 800-320,layer = Display.LAYER_OSD0,alpha = 80)
p = tp.read(1) # 读取触摸事件
if p!=():
print(p)
x, y, event = p[0].x, p[0].y, p[0].event
if event == 2 or event == 3:
# 在触摸位置绘制十字标记
img.draw_cross(x, y, color = (255, 0, 0), size = 10, thickness = 6)
if 720 - 40 < x < 720 + 40 and 240 - 40 < y < 240 + 40 and event == 2:
# 当触摸特定区域时,拍摄照片并保存到 TF 卡
img = sensor.snapshot()
img = sensor.snapshot(chn=CAM_CHN_ID_0)
img.save("/data/img_%d.bmp"%number)
number = number + 1
print("已按下")
time.sleep(1)
Display.show_image(img) # 显示通道0的图像
# 按键消抖
if button.value() == 1:
time.sleep_ms(10) # 延时10毫秒进行消抖
current_time = time.ticks_ms() # 获取当前时间(单位:毫秒)
if button.value() == 1:
while button.value() == 1:
pass # 等待按键释放
if time.ticks_ms() - current_time <= 500:
# 短按按键,拍摄照片并保存到 TF 卡
src_img = sensor.snapshot(chn=CAM_CHN_ID_0)
src_img.save("/data/img_%d.bmp"%number)
number = number + 1
print("保存成功")
print(time.ticks_ms() - current_time)
elif time.ticks_ms() - current_time > 500:
# 长按按键,显示上一张保存的照片
test_img = image.Image("/data/img_%d.bmp"%(number - 1))
#test_img.histeq() #直方图均衡化
Display.show_image(test_img)
print("显示成功")
#print(time.ticks_ms()-current_time)
# 喂狗操作,重置 WDT 计时器
wdt1.feed()
# 打印帧率到控制台
# print(fps.fps())
except KeyboardInterrupt as e:
print("用户停止: ", e)
except BaseException as e:
print(f"异常: {e}")
finally:
# 停止传感器运行
if isinstance(sensor, Sensor):
sensor.stop()
# 反初始化显示模块
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)
# 释放媒体缓冲区
MediaManager.deinit()
fps.tick():更新帧率计数器,用于计算帧率。os.exitpoint():检查系统退出点,确保程序可以安全退出。sensor.snapshot():从摄像头的不同通道捕获图像。img.draw_circle()和img.draw_cross():在图像上绘制图形,用于标记特定位置。src_img.laplacian():对通道 1 的图像进行拉普拉斯边缘检测。Display.show_image():在显示屏上显示图像。- 触摸事件处理:当触摸屏幕特定区域时,拍摄照片并保存到 TF 卡。
- 按键事件处理:通过按键消抖处理,短按按键拍摄照片保存,长按按键显示上一张保存的照片。
wdt1.feed():喂狗操作,重置看门狗定时器,避免系统因超时复位。try-except-finally:捕获异常并进行相应的处理,确保程序在出现异常或用户手动停止时能够安全退出,释放相关资源。
四、总结
通过以上代码的实现,我们成功利用庐山派 K230 开发板完成了按键(触摸)拍照保存到 TF 卡、图像边缘检测以及多通道显示等功能。这些功能展示了庐山派 K230 开发板在图像处理和硬件控制方面的强大能力,为后续的应用开发提供了坚实的基础。开发者可以根据实际需求对代码进行进一步的扩展和优化,实现更多复杂的功能。

更多推荐



所有评论(0)