通过k230保存图片时使用的方法和得到的图片格式问题

Viewed 434

重现步骤
前几天运行这个save/show代码可以跑起来,然后得到的文件为bin格式,今天想仿照save_snapshot_bin(width,height,save_bin)这个功能函数进行尝试,遇到一些问题。

首先存储函数在图像处理API文档中,save()的文字描述也是这个功能,为什么这里不使用这个方法而是选择file.write(img_np.tobytes())这样实现,当然video例程里,也是使用的这个file.write实现,所以我不理解,save()功能是哪里不太合适还是说有什么限制条件。

第二点file.write之后,得到的图片以bin格式保存,这个格式我在电脑上位机没办法解析和查看,想尝试保存为jpg或者bmp之类的格式,我尝试在bin_path的路径,将末尾.bin改成.jpg,这种行为也是没有用,想请问应该修改哪里

期待结果和实际结果
期待能够完成图片保存,然后格式为电脑能接受或者认识的格式。

软硬件版本信息
硬件为K230。固件版本CanMV-K230_micropython_v1.0_sdk_v1.6_nncase_v2.8.3(创乐博V3.0)。

补充材料

from media.sensor import *
from media.display import *
from media.media import *
import os,sys,gc
import ulab.numpy as np
import image
import time

sensor = Sensor(id=2,fps=30)

def read_bin(bin_path,width,height):
    with open(bin_path, 'rb') as f:
        data = f.read()
    data_ori = np.frombuffer(data, dtype=np.uint8).reshape((width,height,3))
    print(data_ori.shape)
    img=image.Image(width, height, image.RGB888, alloc=image.ALLOC_REF,data =data_ori)
    return img

def save_snapshot_bin(width,height,save_bin):
    try:

        # sensor reset
        sensor.reset()
        # set hmirror
        # sensor.set_hmirror(False)
        # sensor vflip
        # sensor.set_vflip(False)

        # set chn1 output format
        sensor.set_framesize(width = width, height = height, chn = CAM_CHN_ID_1)
        sensor.set_pixformat(Sensor.RGB888, chn = CAM_CHN_ID_1)

        # use hdmi as display output
        Display.init(Display.VIRT, to_ide = True)
        # init media manager
        MediaManager.init()
        # sensor start run
        sensor.run()

        # drop 100 frames
        for i in range(100):
            img=sensor.snapshot(chn=CAM_CHN_ID_1)
            Display.show_image(img)

        # snapshot and save
        img = sensor.snapshot(chn = CAM_CHN_ID_1)

        img_np=img.to_rgb888().to_numpy_ref()
        print(img_np.shape)

        with open(save_bin, "wb") as file:
            file.write(img_np.tobytes())
            print('Success!')
        file.close()
    except KeyboardInterrupt as e:
        print(f"user stop")
    except BaseException as e:
        print(f"Exception '{e}'")
    finally:
        # sensor stop run
        if isinstance(sensor, Sensor):
            sensor.stop()
        # deinit display
        Display.deinit()
        os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
        time.sleep_ms(100)
        # release media buffer
        MediaManager.deinit()


if __name__=="__main__":
    bin_path="/sdcard/examples/output.bin"
    width=640
    height=480
    mode="save" # "save" or "show"
    if mode=="save":
        save_snapshot_bin(width,height,bin_path)
    elif mode=="show":
        img=read_bin(bin_path,width,height)
        try:
            img.compress_for_ide()
            gc.collect()
        except Exception as e:
            sys.print_exception(e)
    else:
        pass

An error occurred during buffer used: [Errno 12] ENOMEM
这个是缓冲区报错

1 Answers

你好,目前将image保存为jpeg,bmp或者png格式只支持转换少数几种原图格式,如果是从摄像头采集的yuv420等格式,建议将其转换为rgb565之后再进行保存。如果想查看保存的yuv格式图像,推荐使用YUView或者yuvplayer等工具