858|4

20

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【DigiKey创意大赛】家庭共享智能药盒04+人脸分辨程序设计 [复制链接]

  本帖最后由 oet 于 2024-10-18 20:57 编辑
 
上一贴介绍了设计PCB和调试BME280,给OPENMV增加了显示模块和传感器。本帖介绍人脸分辨程序的设计过程。
基于OPENMV的人脸分辨程序设计在星瞳官网有一个专门的教程,链接如下:
里面还有对应的视频,将原理讲解的比较明白。主要是使用OPENMV系统自带的LBP算法实现人脸分辨。
最开始我使用官网例程进行学习,请家人做模特照相,调试程序。如下图是试验的文件。
效果基本和官网视频介绍的相当,但是需要手工在TF卡上建立文件,然后分别录入图片,整个操作流程繁琐,结构松散,想整合到我这次作品中,有点无从下手。
思虑后我打算参考例程自己从新写个程序,实现我这次特定的功能。我先把程序需求想好了,然后备忘就在记事本上记下来了。恰好当时正在给孩子处理作业的事情,使用Kimi找算术题,造句等,借助AI给孩子辅导作业很方便。这个弄完我突然想到,何不让AI帮我写程序呢,试试又不花钱,说干就干。
我把之前写好的需求直接输入Kimi,经过它的一通查询,果然给我弄出一篇代码,我仔细读后发现有些问题,开始手动修改代码。然后出来第一版能凑合运行的框架程序,但是距离能用还差很远。
本来打算放弃了,但是又有点不甘心,就又尝试告诉Kimi,指明它生成的代码有哪些不足,让它自己修改,然后我就发现它果然能改好,这让我大喜,我就按照和同事沟通一样,不停的多次沟通,它就不停的迭代生成的代码。如下图是某次沟通截图。
使用Kimi关键是文字需求描述要清晰准确,下图是我三次更改描述语句,让Kimi进行程序生成。
经过七次大版本迭代,终于搞出一版在程序结构,功能实现上基本都能满足要求的代码。下图是我保存的历次大版本代码。
直接生成的代码,在编译运行时还是有些问题的,下面是直接生成的代码,大家可以看看有什么问题。
代码1:
  • #带显示功能
  • import sensor, image, time, pyb, os
  • from fpioa_manager import fm, board_info
  • from Maix import GPIO
  • from display import SPIDisplay
  • # 初始化摄像头
  • sensor.reset()
  • sensor.set_pixformat(sensor.GRAYSCALE)
  • sensor.set_framesize(sensor.QVGA)
  • sensor.skip_frames(time=2000)
  • sensor.set_auto_gain(False) # 关闭自动增益
  • sensor.set_auto_whitebal(False) # 关闭自动白平衡
  • # 初始化SD卡
  • uos.mount(sdcard, '/sd')
  • # 初始化LED灯
  • led = pyb.LED(1)
  • # 初始化串口
  • uart3 = pyb.UART(3, 115200)
  • # 初始化显示屏
  • lcd = SPIDisplay(width=132, height=132, bgr=True)
  • lcd.init()
  • # 阈值设置
  • THRESHOLD = 50
  • # 录入人脸图片并计算LBP特征
  • def capture_face(index):
  • if not os.path.exists('/sd/{}'.format(index)):
  • os.mkdir('/sd/{}'.format(index))
  • for i in range(10):
  • img = sensor.snapshot()
  • img = img.resize(128, 128) # 调整图像大小
  • lcd.display(img) # 显示调整大小后的图像
  • lbp = img.find_lbp((0, 0, img.width(), img.height()))
  • lbp.save('/sd/{}/face_{}.lbp'.format(index, i))
  • led.on()
  • time.sleep(100)
  • led.off()
  • time.sleep(900)
  • # 接收指令并录入人脸
  • def receive_and_capture():
  • while True:
  • data = uart3.read()
  • if data:
  • cmd = data.decode()[0]
  • if cmd.isdigit() and int(cmd) in range(1, 7):
  • capture_face(cmd)
  • elif cmd == 'r':
  • face_recognition()
  • # 启动人脸识别
  • def face_recognition():
  • img = sensor.snapshot()
  • img = img.resize(128, 128) # 调整图像大小
  • lcd.display(img) # 显示调整大小后的图像
  • lbp = img.find_lbp((0, 0, img.width(), img.height()))
  • min_diff = 999999
  • recognized = None
  • for folder in range(1, 7):
  • for i in range(10):
  • template_file = '/sd/{}/face_{}.lbp'.format(folder, i)
  • if os.path.exists(template_file):
  • template = image.load(template_file)
  • diff = image.match_descriptors(lbp, template)
  • if diff < min_diff:
  • min_diff = diff
  • recognized = folder
  • if min_diff < THRESHOLD:
  • uart3.write('{}\n'.format(recognized))
  • else:
  • uart3.write('0\n')
  • # 显示识别结果
  • img.draw_string(10, 10, "Recognizing...", color=(255), scale=2)
  • if recognized:
  • img.draw_string(10, 40, "Match Found!", color=(255), scale=2)
  • else:
  • img.draw_string(10, 40, "No Match Found", color=(255), scale=2)
  • lcd.display(img) # 显示带有识别结果的图像
  • # 主循环
  • def main():
  • while True:
  • data = uart3.read()
  • if data:
  • cmd = data.decode()[0]
  • if cmd == 'r':
  • face_recognition()
  • elif cmd.isdigit() and int(cmd) in range(1, 7):
  • capture_face(cmd)
  • if __name__ == '__main__':
  • main()

 

经过我的修改,最终能运行的代码:
代码2:
  • #带显示功能
  • #import sensor, image, time, pyb, os
  • #from fpioa_manager import fm, board_info
  • #from Maix import GPIO
  • #from display import SPIDisplay
  • import time, os, pyb
  • import display
  • import sensor, image, machine
  • # 初始化摄像头
  • sensor.reset()
  • sensor.set_pixformat(sensor.GRAYSCALE)
  • #sensor.set_framesize(sensor.QVGA)
  • #sensor.set_pixformat(sensor.RGB565) # or sensor.GRAYSCALE
  • sensor.set_framesize(sensor.B128X128) # 128x160大小的特定液晶屏。
  • sensor.skip_frames(time=200)
  • sensor.set_auto_gain(False) # 关闭自动增益
  • sensor.set_auto_whitebal(False) # 关闭自动白平衡
  • # 初始化SD卡
  • #os.mount(sdcard, '/sd')
  • # 初始化LED灯
  • led = pyb.LED(1)
  • # 初始化串口
  • uart3 = pyb.UART(3, 115200)
  • # 初始化显示屏
  • lcd = display.SPIDisplay( width=132, height=132,bgr=True)
  • #lcd = SPIDisplay(width=132, height=132, bgr=True)
  • #lcd.init()
  • print("start ok")
  • # 阈值设置
  • THRESHOLD = 2600
  • # 录入人脸图片并计算LBP特征
  • def capture_face(index):
  • if not '{}'.format(index) in os.listdir():
  • os.mkdir('{}'.format(index)) # 新建一个新的文件夹
  • print("mkdir ok")
  • for i in range(10):
  • led.on()
  • time.sleep_ms(100)
  • img = sensor.snapshot()
  • lcd.write(img) # 拍照并显示图像。
  • img.save('/{}/face_{}.pgm'.format(index, i))
  • print('/{}/face_{}.pgm'.format(index, i))
  • led.off()
  • time.sleep_ms(900)
  • # 接收指令并录入人脸
  • def receive_and_capture():
  • while True:
  • data = uart3.read()
  • if data:
  • cmd = data.decode()[0]
  • if cmd.isdigit() and int(cmd) in range(1, 7):
  • capture_face(cmd)
  • elif cmd == 'r':
  • face_recognition()
  • # 启动人脸识别
  • def face_recognition():
  • img = sensor.snapshot()
  • lcd.write(img) # 拍照并显示图像。
  • lbp = img.find_lbp((0, 0, img.width(), img.height()))
  • min_diff = 999999
  • recognized = None
  • img_temp = img
  • for folder in range(1, 7):
  • for i in range(10):
  • if '{}'.format(folder) in os.listdir():
  • template_file = '/{}/face_{}.pgm'.format(folder, i)
  • img = image.Image(template_file)
  • template = img.find_lbp((0, 0, img.width(), img.height()))
  • diff = image.match_descriptor(lbp, template)
  • if diff < min_diff:
  • min_diff = diff
  • recognized = folder
  • print(min_diff,recognized)
  • img_temp = img
  • else:
  • print("no dir:"+template_file)
  • if min_diff < THRESHOLD:
  • uart3.write('{}\n'.format(recognized))
  • print('{}\n'.format(recognized))
  • img_temp.draw_string(5, 120, "Match Found!", color=(255), scale=1)
  • else:
  • uart3.write('0\n')
  • print('0\n')
  • img_temp.draw_string(5, 120, "No Match Found", color=(255), scale=1)
  • # 显示识别结果
  • lcd.write(img_temp) # 显示带有识别结果的图像
  • # 主循环
  • def main():
  • img = sensor.snapshot()
  • lcd.write(img) # 拍照并显示图像。
  • while True:
  • data = uart3.read()
  • if data:
  • cmd = data.decode()[0]
  • if cmd == 'r':
  • face_recognition()
  • elif cmd.isdigit() and int(cmd) in range(1, 7):
  • capture_face(cmd)
  • if __name__ == '__main__':
  • main()

 

代码编辑好后就是做实验了。这个时候再找家人不停地拍照太麻烦了,我就想直接从网上找现成的照片进行测试也一样啊。经过资料查找,最终确定使用《CK表情分类数据集》。这个数据集中,包含多个人的各种表情图片,每种表情记录了几张到十几张图片不等,其中每个人图片总数都在几十张以上,我选取了7个人,使用每个人部分图片作为训练对比参考,剩余的作为测试图片,这样一下子解决了需要不同人拍照问题。
我只需在另外一个显示器上显示参考或测试图片,把摄像头调整好距离,就能完美测试了。下图是实际调试拍照,测试效果很好。
在OpenMV IDE输出调试信息显示程序运行正确无误。
在串口终端也完全实现了预期的发送指令和接收结果的功能。
通过以上测试,确认这个AI生成的程序完全实现了预期的功能。
从此之后,我又多了一个好帮手,编写简单程序,只需要把需求写清楚,让Kimi帮忙实现,不但效率高,还省脑细胞!

最新回复

请教楼主,你的产品如果售卖是否需要进行3C认证啊   详情 回复 发表于 2024-10-23 20:53
点赞 关注
 
 

回复
举报

22

帖子

1

TA的资源

一粒金砂(中级)

沙发
 

实时性好吗?

 

点评

oet
一秒以内识别完成,速度还可以  详情 回复 发表于 2024-10-20 20:00
 
 
 

回复

20

帖子

1

TA的资源

一粒金砂(中级)

板凳
 
JOEYCH 发表于 2024-10-20 13:42 实时性好吗?  

一秒以内识别完成,速度还可以

 
 
 

回复

701

帖子

5

TA的资源

纯净的硅(高级)

4
 

请教楼主,你的产品如果售卖是否需要进行3C认证啊

点评

oet
这个做着玩的,没打算销售 如果是用于销售的,最好是去过一下认证,市场适用范围更广。  详情 回复 发表于 2024-10-24 00:06
 
 
 

回复

20

帖子

1

TA的资源

一粒金砂(中级)

5
 
chejm 发表于 2024-10-23 20:53 请教楼主,你的产品如果售卖是否需要进行3C认证啊

这个做着玩的,没打算销售

如果是用于销售的,最好是去过一下认证,市场适用范围更广。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

开源项目 更多>>
    随便看看
    查找数据手册?

    EEWorld Datasheet 技术支持

    相关文章 更多>>
      关闭
      站长推荐上一条 1/10 下一条
      中星联华&ADI明日直播
      直播主题:大咖面对面,轻松玩转高速ADC性能测试
      直播时间:3月25日(周二)14:00
      活动奖励:京东卡、双肩包

      查看 »

       
      EEWorld订阅号

       
      EEWorld服务号

       
      汽车开发圈

       
      机器人开发圈

      About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

      站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 7

      北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

      电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
      快速回复 返回顶部 返回列表