不爱胡萝卜的仓鼠 发表于 2024-10-3 19:45

[嘉楠 CanMV K230]测评 ⑥摄像头图像获取并显示、输出界面画点、画线

<div class='showpostmsg'> 本帖最后由 不爱胡萝卜的仓鼠 于 2024-10-3 19:44 编辑

<p>今天我们开始K230最主要功能图像识别的第一步,从摄像头中读取出图像,并显示出来。然后在输出界面画点画线等,为后续做好基础</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:24px;">一.摄像头读取画面</span></strong></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;嘉楠官方关于摄像头的文档:<a href="https://developer.canaan-creative.com/k230_canmv/main/zh/api/mpp/K230_CanMV_Sensor%E6%A8%A1%E5%9D%97API%E6%89%8B%E5%86%8C.html" target="_blank">https://developer.canaan-creative.com/k230_canmv/main/zh/api/mpp/K230_CanMV_Sensor%E6%A8%A1%E5%9D%97API%E6%89%8B%E5%86%8C.html</a></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K230 CanMV平台sensor模块包括三个独立的能力完全相同的sensor设备,每个sensor设备均可独立完成图像数据采集捕获处理,并可以同时输出3路图像数据。如下图所示:</p>

<div style="text-align: center;"></div>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sensor 0,sensor 1,sensor 2表示三个图像传感器;Camera Device 0,Camera Device 1,Camera Device 2表示三个sensor设备;output channel 0,output channel 1,output channel 2表示sensor设备的三个输出通道。三个图像传感器可以通过软件配置映射到不同的sensor 设备。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 我们这块开发板把3路摄像头都印出来了,出厂时安装了一个,剩下两路用户有需要的话,可以自行购买摄像头安装。其中出厂安装的摄像头使用的是2号</p>

<div style="text-align: center;"></div>

<div style="text-align: center;"></div>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;摄像头的使用还是比较简单的,参照文档中的API和例程就可以跑起来。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 让摄像头工作起来调用的函数很简单,首先调用Sensor()、sensor.reset()、sensor.set_hmirror()、sensor.set_vflip()、sensor.set_framesize()、sensor.set_pixformat()函数对摄像头进行初始化,然后再调用MediaManager.init()初始化MediaManager,最后调用sensor.run()就可以让摄像头开始工作了。之后就可以在while1中不停调用sensor.snapshot()让摄像头拍照。具体代码如下</p>

<pre>
<code class="language-python">import time, os, sys

from media.sensor import *
from media.media import *

def camera_test():
    print("camera_test")

    #用默认配置构造一个Sensor对象
    sensor = Sensor()
    #复位摄像头
    sensor.reset()
    #设置摄像头水平翻转
    sensor.set_hmirror(False)
    #设置摄像头垂直翻转
    sensor.set_vflip(False)
    #设置指定通道的输出图像尺寸, FHD:1920x1080
    sensor.set_framesize(Sensor.FHD)
    #设置指定sensor设备和通道的输出图像格式
    sensor.set_pixformat(Sensor.RGB565)
   
    #初始化media manager
    MediaManager.init()
    #摄像头开始工作
    sensor.run()

    try:
      while True:
            os.exitpoint()
            #摄像头拍一张照片
            img = sensor.snapshot()

    except KeyboardInterrupt as e:
      print("user stop: ", e)
    except BaseException as e:
      print(f"Exception {e}")
      
    #摄像头停止工作
    sensor.stop()
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    #media manager去初始化
    MediaManager.deinit()

if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    camera_test()</code></pre>

<p>&nbsp;</p>

<p>因为没有写显示相关的代码,所以现在我们并不能看到画面。</p>

<p>&nbsp;</p>

<p>我们还可以增加帧率检测代码,他的实现也非常简单,首先调用time.clock()构造一个时钟对象,然后在拍照函数前后增加clock.tick()、clock.fps(),就可以通过检测出拍摄一张照片所耗费的时间,从而计算出fps。代码如下</p>

<pre>
<code class="language-python">import time, os, sys

from media.sensor import *
from media.media import *

def camera_test():
    print("camera_test")

    #用默认配置构造一个Sensor对象
    sensor = Sensor()
    #复位摄像头
    sensor.reset()
    #设置摄像头水平翻转
    sensor.set_hmirror(False)
    #设置摄像头垂直翻转
    sensor.set_vflip(False)
    #设置指定通道的输出图像尺寸, FHD:1920x1080
    sensor.set_framesize(Sensor.FHD)
    #设置指定sensor设备和通道的输出图像格式
    sensor.set_pixformat(Sensor.RGB565)
   
    #初始化media manager
    MediaManager.init()
    #摄像头开始工作
    sensor.run()
   
    #构造一个时钟对象
    clock = time.clock()

    try:
      while True:
            os.exitpoint()
            
            #开始追踪运行时间
            clock.tick()
            
            #摄像头拍一张照片
            img = sensor.snapshot()

            #停止追踪运行时间,并返回当前FPS(每秒帧数),通过print函数打印出来
            print(clock.fps())

    except KeyboardInterrupt as e:
      print("user stop: ", e)
    except BaseException as e:
      print(f"Exception {e}")
      
    #摄像头停止工作
    sensor.stop()
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    #media manager去初始化
    MediaManager.deinit()

if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    camera_test()</code></pre>

<p>代码运行后,我们就可以在日志界面看到不停打印的帧率</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p><strong><span style="font-size:24px;">二.画面显示</span></strong></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;嘉楠官方关于画面显示的文档:<a href="https://developer.canaan-creative.com/k230_canmv/main/zh/api/mpp/K230_CanMV_Display%E6%A8%A1%E5%9D%97API%E6%89%8B%E5%86%8C.html" target="_blank">https://developer.canaan-creative.com/k230_canmv/main/zh/api/mpp/K230_CanMV_Display%E6%A8%A1%E5%9D%97API%E6%89%8B%E5%86%8C.html</a></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 在之前的文章中我们说过,开发板支持3种图像输出方式</p>

<ul>
        <li><code class="hljs">IDE缓冲区显示</code>:性价比最高,图像质量有一定下降,但能满足大部分场合调试使用。最大支持1920x1080分辨率。</li>
        <li><code class="hljs">HDMI</code>:外接HDMI显示屏,清晰度最高。最大支持1920x1080分辨率。</li>
        <li><code class="hljs">MIPI显示屏</code>:外接01Studio 3.5寸MiPi显示屏,可以一体化组装,适合离线部署调试使用。最大支持800x480分辨率。</li>
</ul>

<p>&nbsp;</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 我们这里就使用IDE缓冲显示的方式,实现起来也很简单,只需要调用Display.init()函数初始化屏幕,这里就可以选择输出方式了。在摄像头拍摄图片后,调用Display.show_image即可显示图片,非常的简单。代码如下</p>

<pre>
<code class="language-python">import time, os, sys

from media.sensor import *
from media.media import *
from media.display import *

def camera_test():
    print("camera_test")

    #用默认配置构造一个Sensor对象
    sensor = Sensor()
    #复位摄像头
    sensor.reset()
   
    #设置摄像头水平翻转
    sensor.set_hmirror(False)
    #设置摄像头垂直翻转
    sensor.set_vflip(False)

    #设置指定通道的输出图像尺寸, FHD:1920x1080
    sensor.set_framesize(Sensor.FHD)
    #设置指定sensor设备和通道的输出图像格式
    sensor.set_pixformat(Sensor.RGB565)

    #通过IDE缓冲区显示图像
    Display.init(Display.VIRT, sensor.width(), sensor.height())
   
    #初始化media manager
    MediaManager.init()
    #摄像头开始工作
    sensor.run()
   
    #构造一个时钟对象
    clock = time.clock()

    try:
      while True:
            os.exitpoint()
            
            #开始追踪运行时间
            clock.tick()
            
            #摄像头拍一张照片
            img = sensor.snapshot()
            Display.show_image(img)

            #停止追踪运行时间,并返回当前FPS(每秒帧数),通过print函数打印出来
            print(clock.fps())


    except KeyboardInterrupt as e:
      print("user stop: ", e)
    except BaseException as e:
      print(f"Exception {e}")
      
    #摄像头停止工作
    sensor.stop()
    # deinit display
    Display.deinit()
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    #media manager去初始化
    MediaManager.deinit()

if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    camera_test()</code></pre>

<p>&nbsp;</p>

<p>可以看到,右上角已经显示出图像了,说明我们之前的摄像头代码和现在显示的代码都是可以正常工作的</p>

<div style="text-align: center;"></div>

<div>同时,现在的FPS已经来到了50左右,使用IDE缓冲的方式还是会损失一些FPS的(后续增加图像识别的相关函数,估计还得下降,或许可以考虑降低分辨率,因为现在使用的是最高的1920*1080)</div>

<div>&nbsp;</div>

<p><strong><span style="font-size:24px;">三.在输出界面画点画线等</span></strong></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;嘉楠官方关于画点画线的文档:<a href="https://developer.canaan-creative.com/k230_canmv/main/zh/api/openmv/image.html#id7" target="_blank">https://developer.canaan-creative.com/k230_canmv/main/zh/api/openmv/image.html#id7</a></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 01Studio关于画点画线的文档:<a href="https://wiki.01studio.cc/docs/canmv_k230/machine_vision/draw" target="_blank">https://wiki.01studio.cc/docs/canmv_k230/machine_vision/draw</a></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 画点画线的本质就是对摄像头拍到的图像在显示之前,进行加工处理。</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我这边就简单的随便画点,其他更多图案等可以去详细看看文档,代码如下</p>

<pre>
<code class="language-python">import time, os, sys

from media.sensor import *
from media.media import *
from media.display import *

def camera_test():
    print("camera_test")

    #用默认配置构造一个Sensor对象
    sensor = Sensor()
    #复位摄像头
    sensor.reset()
   
    #设置摄像头水平翻转
    sensor.set_hmirror(False)
    #设置摄像头垂直翻转
    sensor.set_vflip(False)

    #设置指定通道的输出图像尺寸, FHD:1920x1080
    sensor.set_framesize(Sensor.FHD)
    #设置指定sensor设备和通道的输出图像格式
    sensor.set_pixformat(Sensor.RGB565)

    #通过IDE缓冲区显示图像
    Display.init(Display.VIRT, sensor.width(), sensor.height())
   
    #初始化media manager
    MediaManager.init()
    #摄像头开始工作
    sensor.run()
   
    #构造一个时钟对象
    clock = time.clock()

    try:
      while True:
            os.exitpoint()
            
            #开始追踪运行时间
            clock.tick()
            
            #摄像头拍一张照片
            img = sensor.snapshot()
            img.draw_line(10, 20, 500, 20, color = (255, 0, 0), thickness = 10)
            img.draw_rectangle(10, 50, 100, 100, color = (0, 255, 0), thickness = 10, fill = False)
            img.draw_string_advanced(10, 200, 50, "文字显示测试Test", color = (255, 255, 255))
            Display.show_image(img)

            #停止追踪运行时间,并返回当前FPS(每秒帧数),通过print函数打印出来
            print(clock.fps())


    except KeyboardInterrupt as e:
      print("user stop: ", e)
    except BaseException as e:
      print(f"Exception {e}")
      
    #摄像头停止工作
    sensor.stop()
    # deinit display
    Display.deinit()
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    #media manager去初始化
    MediaManager.deinit()

if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    camera_test()</code></pre>

<div style="text-align: center;"></div>

<p>&nbsp;</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

Jacktang 发表于 2024-10-6 09:26

<p>在摄像头拍摄图片后,调用Display.show_image即可显示图片,非常的简单,看着是这样滴</p>
页: [1]
查看完整版本: [嘉楠 CanMV K230]测评 ⑥摄像头图像获取并显示、输出界面画点、画线