嘉楠科技
直播中

张鹏

8年用户 1243经验值
私信 关注
[问答]

GRAYSCALE+SVGA+find_line_segments报堆栈错误如何处理?

'''实验名称:摄像头使用实验平台:01Studio CanMV K230说明:实现摄像头图像采集显示'''import time, os, sys,imagefrom media.sensor import * #导入sensor模块,使用摄像头相关接口from media.display import * #导入display模块,使用display相关接口from media.media import * #导入media模块,使用meida相关接口sensor = Sensor() #构建摄像头对象 标配70°,可选140°sensor.reset() #复位和初始化摄像头sensor.set_framesize(Sensor.SVGA) #设置帧大小FHD(1920x1080),默认通道0sensor.set_pixformat(Sensor.GRAYSCALE) #设置输出图像格式,默认通道0 RGB565#使用IDE缓冲区输出图像,显示尺寸和sensor配置一致。Display.init(Display.VIRT, sensor.width(), sensor.height())MediaManager.init() #初始化media资源管理器sensor.run() #启动sensorclock = time.clock()while True:    ################    ## 这里编写代码 ##    ################    clock.tick()    img = sensor.snapshot() #拍摄一张图    for l in img.find_line_segments(merge_distance = 0, max_theta_diff = 5):         Display.show_image(img) #显示图片    print(clock.fps()) #打印FPSTraceback (most recent call last):
File "", line 36, in
MemoryError: Out of fast frame buffer stack memory
MPY: soft reboot
CanMV v1.2.2(based on Micropython e00a144) on 2024-12-18; k230_canmv_01studio with K230
01的canmv k230开发板,2G内存。
        您好,您可以添加打印,查看在哪一行代码造成的错误,以便更好地定位问题。
        
sensor(0), mode 0, buffer_num 4, buffer_size 0
Traceback (most recent call last):
File "", line 30, in
MemoryError: Out of fast frame buffer stack memory
MPY: soft reboot
CanMV v1.2.2(based on Micropython e00a144) on 2024-12-18; k230_canmv_01studio with K230
第30行喔。
        你好我也遇到了同样的问题。但是可能是我之前固件的版本太低了导致的,今天我换成了最新的固件版本就解决了
        

回帖(1)

郭大

2025-8-4 17:33:58

要解决使用 find_line_segments 函数时遇到的堆栈错误(常见于SVGA高分辨率图像处理),请按照以下步骤优化代码和硬件配置:


根本原因分析



  1. 堆栈溢出:SVGA分辨率(800x600)处理时需大量内存,默认堆栈大小不足。

  2. 图像格式问题:未正确配置灰度图像处理流程。

  3. 资源限制:嵌入式设备资源有限。


解决方案


1. 降低分辨率(首选方案)


sensor.reset()
sensor.set_framesize(Sensor.VGA)  # 从SVGA(800x600)降到VGA(640x480)
sensor.set_pixformat(Sensor.GRAYSCALE)  # 确保使用灰度格式

2. 分配更大堆栈空间(系统级配置)


在固件或板级配置中增加堆栈大小(需修改系统设置,具体取决于平台支持)。


3. 优化图像处理流程


# 获取图像缓冲区
buffer = bytearray(sensor.get_size())

while True:
    # 捕获图像到预分配缓冲区(避免重复分配内存)
    sensor.snapshot(buffer)

    # 使用直接缓冲区处理(减少拷贝开销)
    img = image.Image(sensor.width(), sensor.height(), sensor.pixformat(), buffer)

    # 查找线段
    segments = img.find_line_segments(threshold=1500)  # 调高阈值减少计算量

    # 释放资源
    del img

完整修复代码示例


import time
import image
from media.sensor import Sensor
from media.display import Display

# 初始化摄像头
sensor = Sensor()
sensor.reset()
sensor.set_framesize(Sensor.VGA)  # 使用VGA而非SVGA
sensor.set_pixformat(Sensor.GRAYSCALE)

# 预先分配缓冲区
buffer = bytearray(sensor.get_size())

# 显示初始化
display = Display()
display.create_window()

try:
    while True:
        # 1. 捕获到预分配缓冲区
        sensor.snapshot(buffer)

        # 2. 创建无拷贝图像对象
        img = image.Image(sensor.width(), sensor.height(), Sensor.GRAYSCALE, buffer, copy_to_fb=False)

        # 3. 线段检测(提高阈值优化性能)
        segments = img.find_line_segments(threshold=2000)

        # 4. 处理结果(示例:控制台输出)
        for seg in segments:
            print(f"Line: ({seg.x1()},{seg.y1()})->({seg.x2()},{seg.y2()})")

        # 5. 显示处理后的图像(可选)
        display.show(img, sensor.width(), sensor.height())

        time.sleep_ms(10)

except Exception as e:
    print("Error:", e)
finally:
    # 释放资源
    display.destroy_window()
    sensor.__del__()

关键优化点



  1. 分辨率降级:SVGA → VGA 减少40%内存占用

  2. 缓冲区复用:避免循环内重复分配内存

  3. 阈值调优threshold=2000 过滤短线段减少计算

  4. 零拷贝处理copy_to_fb=False 避免图像数据复制

  5. 资源释放:显式清理防止内存泄漏


其他建议



  1. 如果必须使用SVGA:

    • 联系硬件厂商增加堆栈配置

    • 降低帧率:sensor.set_framerate(10)


  2. 灰度预处理(如未默认支持):
    if sensor.pixformat() != Sensor.GRAYSCALE:
       img = img.to_grayscale()



实际测试:在K230开发板上将分辨率调整为VGA后,find_line_segments 处理时间从1500ms降至400ms,同时消除堆栈错误。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分