土豆12 发表于 2024-7-28 01:30

【Sipeed MAix BiT AIoT 开发套件】2,Yolo_v2人脸识别

<div class='showpostmsg'><p>要实现人脸追踪,第一步就是要实现人脸的检测。</p>

<p>&nbsp;</p>

<p>人脸检测属于机器学习里非常常规的应用。一般情况下,我们不需要去自己训练模型,可以试用官方准备好的模型,在下面链接下载face_model_at_0x300000.kfpkg模型文件:</p>

<p><a href="https://dl.sipeed.com/MAIX/MaixPy/model" target="_blank">https://dl.sipeed.com/MAIX/MaixPy/model</a></p>

<p>&nbsp;</p>

<p>下载完成后,需要通过和上一期更新固件时同样的工具kflash_gui把模型刷写到开发板上:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>不需要担心这个刷写会覆盖掉我们之前刷写的bin固件。因为这次刷写的文件是kfpkg文件,这个文件中有记载文件应该被刷写道flash的什么位置。</p>

<p>MaixPy 中的存储介质主要由 Flash,SD 卡组成,分为三块区域,分别是 MaixPy.bin 固件区,xxx.kmodel 模型区,文件系统区:Flash 上为 spiffs(SPI Flash File System),SD 卡为 Fatfs(FAT file system)。可以从下图中看到储存系统的分配,因此相互之间不会影响。</p>

<p>&nbsp;</p>

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

<div>&nbsp;</div>

<p>&nbsp;</p>

<p>接下来加载模型,只需要把模型的刷鞋地址作为参数传递给函数即可。</p>

<pre>
<code class="language-python">import KPU as kpu

task = kpu.load(0x300000)
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
</code></pre>

<p>&nbsp;</p>

<p>其中,anchor元组是锚点参数,这个参数与模型是一一对应的,也就是说,这个元组我们不可以去做任何自行修改,一定要保持一模一样。</p>

<p>&nbsp;</p>

<p>init_yolo2这个函数可以初始化模型。我们可以看到中间有两个浮点数参数。其中第一个参数是概率阈值, 只有是这个物体的概率大于这个值才会输出结果, 取值范围:;第二个参数是box_iou 门限, 为了防止同一个物体被框出多个框,当在同一个物体上框出了两个框,这两个框的交叉区域占两个框总占用面积的比例 如果小于这个值时, 就取其中概率最大的一个框。</p>

<p>&nbsp;</p>

<p>接着我们准备好想要识别的图片实体,这个图片通过摄像头获得。首先我们初始化摄像头:</p>

<pre>
<code class="language-python">import sensor

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)</code></pre>

<p>&nbsp;</p>

<p>接着,通过下面这个函数就可以抓取到照片,并保存为img变量</p>

<pre tabindex="0">
<code class="language-python">img = sensor.snapshot()</code></pre>

<p>&nbsp;</p>

<p>得到照片后,将照片放入模型中进行识别,识别出的结果是一个可以遍历的实体,里面每一个元素就是我们识别到的每一个人脸。&nbsp;因为图像中的人脸可能不止一个,但追踪时我们只能选择最近的追踪。因此我们可以遍历每一个识别到的人脸,选择最大的哪个,把它的框画在图上。</p>

<pre>
<code class="language-python">objects = kpu.run_yolo2(self.task, img)
if objects:
    max_area = 0
    max_i = 0
    for i, j in enumerate(objects):
      a = j.w()*j.h()
      if a &gt; max_area:
            max_i = i
            max_area = a

    img.draw_rectangle(objects.rect())</code></pre>

<p>&nbsp;</p>

<p>最后,我们可以把识别到的图像显示在LCD上。同样的,先要初始化LCD,只需一行代码即可完成。接着显示图片即可。</p>

<pre>
<code>import lcd

lcd.init(type=1)

lcd.display(img)</code></pre>

<p>&nbsp;</p>

<p>如果一切顺利,逐行运行上述代码,如果图像中有人脸,我们可以看到LCD上显示出了对应的识别结果:</p>

<p> &nbsp;</p>

<p>完整代码如下:</p>

<pre>
<code class="language-python">import sensor, image, lcd, time
import KPU as kpu
import gc, sys


def lcd_show_except(e):
    import uio

    err_str = uio.StringIO()
    sys.print_exception(e, err_str)
    err_str = err_str.getvalue()
    img = image.Image(size=(224, 224))
    img.draw_string(0, 10, err_str, scale=1, color=(0xFF, 0x00, 0x00))
    lcd.display(img)


def main(model_addr=0x300000, lcd_rotation=2, sensor_hmirror=False, sensor_vflip=False):
    try:
      sensor.reset()
    except Exception as e:
      raise Exception(
            "sensor reset fail, please check hardware connection, or hardware damaged! err: {}".format(
                e
            )
      )
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.set_hmirror(sensor_hmirror)
    sensor.set_vflip(sensor_vflip)

    lcd.init(type=1)
    lcd.rotation(lcd_rotation)

    clock = time.clock()

    anchors = (
      1.889,
      2.5245,
      2.9465,
      3.94056,
      3.99987,
      5.3658,
      5.155437,
      6.92275,
      6.718375,
      9.01025,
    )
    try:
      task = kpu.load(model_addr)
      kpu.init_yolo2(task, 0.5, 0.3, 5, anchors)# threshold:, nms_value:
      while True:
            clock.tick()
            img = sensor.snapshot()
            objects = kpu.run_yolo2(task, img)
            if objects:
                for obj in objects:
                  img.draw_rectangle(obj.rect())
                  center = (
                        round(obj.x() + obj.w() / 2, 1),
                        round(obj.y() + obj.h() / 2, 1),
                  )
            else:
                center = "N/A"

            img.draw_string(0, 200, "FPS: %f" % (clock.fps()), scale=2)
            img.draw_string(0, 220, "Center: %s" % str(center), scale=2)
            lcd.display(img)
    except Exception as e:
      raise e
    finally:
      if not task is None:
            kpu.deinit(task)


if __name__ == "__main__":
    try:
      main()
    except Exception as e:
      sys.print_exception(e)
      lcd_show_except(e)
    finally:
      gc.collect()
</code></pre>

<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>
页: [1]
查看完整版本: 【Sipeed MAix BiT AIoT 开发套件】2,Yolo_v2人脸识别