【DigiKey创意大赛】家庭共享智能药盒04+人脸分辨程序设计
本帖最后由 oet 于 2024-10-18 20:57 编辑<div> </div>
<div>上一贴介绍了设计PCB和调试BME280,给OPENMV增加了显示模块和传感器。本帖介绍人脸分辨程序的设计过程。</div>
<div>基于OPENMV的人脸分辨程序设计在星瞳官网有一个专门的教程,链接如下:</div>
<div><a href="https://book.openmv.cc/image/face.html">https://book.openmv.cc/image/face.html</a></div>
<div>里面还有对应的视频,将原理讲解的比较明白。主要是使用OPENMV系统自带的LBP算法实现人脸分辨。</div>
<div>最开始我使用官网例程进行学习,请家人做模特照相,调试程序。如下图是试验的文件。</div>
<div></div>
<div>效果基本和官网视频介绍的相当,但是需要手工在TF卡上建立文件,然后分别录入图片,整个操作流程繁琐,结构松散,想整合到我这次作品中,有点无从下手。</div>
<div>思虑后我打算参考例程自己从新写个程序,实现我这次特定的功能。我先把程序需求想好了,然后备忘就在记事本上记下来了。恰好当时正在给孩子处理作业的事情,使用Kimi找算术题,造句等,借助AI给孩子辅导作业很方便。这个弄完我突然想到,何不让AI帮我写程序呢,试试又不花钱,说干就干。</div>
<div>我把之前写好的需求直接输入Kimi,经过它的一通查询,果然给我弄出一篇代码,我仔细读后发现有些问题,开始手动修改代码。然后出来第一版能凑合运行的框架程序,但是距离能用还差很远。</div>
<div>本来打算放弃了,但是又有点不甘心,就又尝试告诉Kimi,指明它生成的代码有哪些不足,让它自己修改,然后我就发现它果然能改好,这让我大喜,我就按照和同事沟通一样,不停的多次沟通,它就不停的迭代生成的代码。如下图是某次沟通截图。</div>
<div></div>
<div>使用Kimi关键是文字需求描述要清晰准确,下图是我三次更改描述语句,让Kimi进行程序生成。</div>
<div></div>
<div>经过七次大版本迭代,终于搞出一版在程序结构,功能实现上基本都能满足要求的代码。下图是我保存的历次大版本代码。</div>
<div></div>
<div>直接生成的代码,在编译运行时还是有些问题的,下面是直接生成的代码,大家可以看看有什么问题。</div>
<div>代码1:</div>
<div>
<pre>
<code class="language-python">#带显示功能
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()
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()
if cmd == 'r':
face_recognition()
elif cmd.isdigit() and int(cmd) in range(1, 7):
capture_face(cmd)
if __name__ == '__main__':
main()</code></pre>
<p> </p>
</div>
<div>经过我的修改,最终能运行的代码:</div>
<div>代码2:</div>
<div>
<pre>
<code class="language-python">#带显示功能
#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("startok")
# 阈值设置
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()
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()
if cmd == 'r':
face_recognition()
elif cmd.isdigit() and int(cmd) in range(1, 7):
capture_face(cmd)
if __name__ == '__main__':
main()
</code></pre>
<p> </p>
</div>
<div>代码编辑好后就是做实验了。这个时候再找家人不停地拍照太麻烦了,我就想直接从网上找现成的照片进行测试也一样啊。经过资料查找,最终确定使用《CK表情分类数据集》。这个数据集中,包含多个人的各种表情图片,每种表情记录了几张到十几张图片不等,其中每个人图片总数都在几十张以上,我选取了7个人,使用每个人部分图片作为训练对比参考,剩余的作为测试图片,这样一下子解决了需要不同人拍照问题。</div>
<div>我只需在另外一个显示器上显示参考或测试图片,把摄像头调整好距离,就能完美测试了。下图是实际调试拍照,测试效果很好。</div>
<div></div>
<div>在OpenMV IDE输出调试信息显示程序运行正确无误。</div>
<div></div>
<div>在串口终端也完全实现了预期的发送指令和接收结果的功能。</div>
<div></div>
<div>通过以上测试,确认这个AI生成的程序完全实现了预期的功能。</div>
<div>从此之后,我又多了一个好帮手,编写简单程序,只需要把需求写清楚,让Kimi帮忙实现,不但效率高,还省脑细胞!</div>
<p><!--importdoc--></p>
<p>实时性好吗?</p>
<p> </p>
JOEYCH 发表于 2024-10-20 13:42
实时性好吗?
<p>一秒以内识别完成,速度还可以</p>
<p>请教楼主,你的产品如果售卖是否需要进行3C认证啊</p>
chejm 发表于 2024-10-23 20:53
请教楼主,你的产品如果售卖是否需要进行3C认证啊
<p>这个做着玩的,没打算销售<img height="52" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/titter.gif" width="48" /></p>
<p>如果是用于销售的,最好是去过一下认证,市场适用范围更广。</p>
页:
[1]