用GPT零负担学单片机之点亮一颗cpu
第4节 GPT写代码效果验证
大家好,我是小杰学长
如果你是大学生 遇到电子技术 学习 成长 入行难题
我曾经通过大学比赛赚钱 从事嵌入式AI 航天军工
用特别的学习和求职方法线下半年带60+学弟学妹入行开发
主页佳喔威信,给你提供一定资源和战略方法上的帮助
相信我的职业经历的专业性,一定能帮到你
我的gitee仓库分享 海量嵌入式资源入行求职技巧-->
目录
1. 概述
在第三期博客中我们用Cursor这个GPT工具写了人脸比对代码
第三期博客 链接
但是实际运行起来肯定是有区别的
因为我们的嵌入式环境是microPython
而cursor是用的通用python的系统函数
所以需要人工debug一下
最后改完bug,人脸注册和识别的运行效果已经拍摄成短视频了
大家可以看看效果
用gpt0负担学开发 ai工具大显神威 嵌入式就业末日来了 链接
2. 代码改动对比
先给大家放一下人脸注册的代码
但是。。。
我在复制的时候想起来注册的代码已经被我改掉了。。。。
那只能放改完的了
没事我们比对识别的代码就能知道cursor多好用了
import sensor
import os
import time
import image
import lcd
from machine import Pin
import machine
#from led import LED_BLACK,LED_WHITE,LED_RED,LED_BLUE,LED_GREEN
led_green = machine.LED("LED_GREEN")
led_red = machine.LED("LED_RED")
led_blue = machine.LED("LED_BLUE")
def LED_BLACK():
led_green.off()
led_blue.off()
led_red.off()
def LED_WHITE():
led_green.on()
led_blue.on()
led_red.on()
def LED_RED():
led_green.off()
led_blue.off()
led_red.on()
def LED_BLUE():
led_blue.on()
led_green.off()
led_red.off()
def LED_GREEN():
led_blue.off()
led_green.on()
led_red.off()
# 初始化LCD
lcd.init()
# 全局变量
key_flag = 0
face_count = 0
# 按键中断处理函数
def key0_func(v):
global key_flag
if key_flag == 0:
LED_WHITE()
key_flag = 1
else:
LED_BLACK()
key_flag = 0
# 按键初始化
key_0 = Pin(("key_0", 0x907))
key_0.irq(trigger=Pin.IRQ_RISING, handler=key0_func)
# 加载Haar级联分类器
face_cascade = image.HaarCascade("frontalface", stages=25)
# 创建新的人脸文件夹
rootpath = "/orl_faces"
person_name = "Zhu"
#文件夹初始化
try:
os.mkdir(rootpath)
except:
print(os.listdir("/"))
person_folder = rootpath + '/' + person_name
if person_name not in os.listdir(rootpath):
try:
os.mkdir(person_folder)
except:
print(os.listdir(rootpath))
print(os.listdir(person_folder))
def save_face_descriptor(descriptor, person_folder, index):
# 保存人脸特征到文件
filename = f"descriptor{index}.bin"
# filepath = os.path.join(person_folder, filename)
filepath = person_folder + '/' + filename
image.save_descriptor(descriptor, filepath)
print(f"Saved descriptor {index} to {filepath}")
# 相机初始化
sensor.reset()
sensor.set_contrast(3)
sensor.set_gainceiling(16)
sensor.set_framesize(sensor.HQVGA)
sensor.set_pixformat(sensor.RGB565)
sensor.set_vflip(True)
sensor.set_hmirror(True)
sensor.skip_frames(time=2000)
clock = time.clock()
while True:
clock.tick()
img = sensor.snapshot()
if key_flag == 1:
key_flag = 0
# 倒计时显示
for i in range(5, 0, -1):
LED_BLUE()
img.draw_string(0, 16, f"Ready in {i}...", color=(0, 255, 0), scale=2)
lcd.display(img)
time.sleep(1)
img = sensor.snapshot()
# 寻找人脸
img_gray = img.copy().to_grayscale()
objects = img_gray.find_features(face_cascade, threshold=0.75, scale_factor=1.25)
if len(objects) == 1:
LED_GREEN()
# 绘制人脸框
# img.draw_rectangle(objects[0], color=(0, 255, 0))
# 提取LBP特征
face_descriptor = img_gray.find_lbp(objects[0])
# 保存特征
save_face_descriptor(face_descriptor, person_folder, face_count + 1)
face_count += 1
if face_count >= 3:
# 注册完成
print("Registration Complete!")
lcd.display(img)
LED_WHITE()
time.sleep(2)
LED_BLACK()
break
else:
# img.draw_string(0, 0, f"Got face {face_count}/3", color=(0, 255, 0), scale=2)
# lcd.display(img)
# time.sleep(1)
print("Got face {face_count}/3")
break
else:
print("Registration fail")
# else:
# img.draw_string(0, 0, "No face detected", color=(255, 0, 0), scale=2)
# else:
# img_gray = img.copy().to_grayscale()
# 显示状态信息
status = f"FPS:"+str(int(clock.fps()))
if person_folder:
status += f"Registering {person_name}: {face_count}/3"
else:
status += "Press KEY0 to start"
img.draw_string(0, 0, status, color=(0, 255, 0), scale=1)
lcd.display(img)
2.1 识别代码对比
cursor生成的识别代码在上一章节的结尾
我把改完的识别代码完整放出来
生成的大家去看上一章节就行
import sensor
import os
import time
import image
import lcd
from machine import Pin
import machine
from led import LED_BLACK,LED_WHITE,LED_RED,LED_BLUE,LED_GREEN
LED_WHITE()
time.sleep(1)
LED_BLACK()
time.sleep(1)
LED_WHITE()
time.sleep(1)
LED_BLACK()
# Initialize the lcd screen.
lcd.init()
#文件夹初始化
rootpath = "/orl_faces"
print(os.listdir(rootpath))
#按键初始化
key_flag = 0
def key0_func(v):
global key_flag
if key_flag == 0:
LED_WHITE()
key_flag = 1
else:
LED_BLACK()
key_flag = 0
key_0 = Pin(("key_0", 0x907))
key_0.irq(trigger=Pin.IRQ_RISING, handler=key0_func)
sensor.reset() # Reset and initialize the sensor.
# Sensor settings
sensor.set_contrast(3)
sensor.set_gainceiling(16)
# HQVGA and GRAYSCALE are the best for face tracking.
sensor.set_framesize(sensor.HQVGA)
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_vflip(True)
sensor.set_hmirror(True)
sensor.skip_frames(time=2000) # Wait for settings take effect.
# Load Haar Cascade
# By default this will use all stages, lower satges is faster but less accurate.
face_cascade = image.HaarCascade("frontalface", stages=25)
# ----------------------
# 在文件开头添加全局变量
face_descriptors = {} # 格式: {'person_name': [descriptor1, descriptor2, descriptor3]}
def str_endswith(s, suffix):
return s[-len(suffix):] == suffix
# 修改加载人脸特征描述符的函数
def load_face_descriptors():
global face_descriptors
for person_name in os.listdir(rootpath):
person_path = rootpath + '/' + person_name
face_descriptors[person_name] = []
# 遍历文件夹中的所有描述符文件
for face_file in os.listdir(person_path):
if str_endswith(face_file,'.bin'):
descriptor_path = person_path + '/' +face_file #os.path.join(person_path, file)
# print(descriptor_path)
descriptor = image.load_descriptor(descriptor_path)
face_descriptors[person_name].append(descriptor)
print(f"Loaded {len(face_descriptors[person_name])} descriptors for {person_name}")
# 在主循环开始前添加
load_face_descriptors() # 程序启动时加载所有已存储的人脸特征
facenamelist = list(face_descriptors.keys())
# -------------
# 修改人脸匹配函数
def match_face(src_lbp):
min_diff = 6000 # 差异度阈值
i = 0
# matched_name = "NONE"
for name, descriptors in face_descriptors.items():
# 对每个人的所有特征描述符进行匹配
for descriptor in descriptors:
diff = image.match_descriptor(src_lbp, descriptor)
print(f"diff={diff}")
if diff < min_diff:
return i
# min_diff = diff
# matched_name = name
i = i+1
return -1
res = 0
recg_face = 'none'
clock = time.clock() # Create a clock object to track the FPS.
while True :
clock.tick() # Update the FPS clock.
img = sensor.snapshot() # Take a picture and return the image.
img_gray = img.copy().to_grayscale()
# Find objects.
# Note: Lower scale factor scales-down the image more and detects smaller objects.
# Higher threshold results in a higher detection rate, with more false positives.
objects = img_gray.find_features(face_cascade, threshold=0.75, scale_factor=1.25)
# 首先找到人脸
if len(objects) == 1: # 有脸亮绿灯
# Draw objects
LED_GREEN()
img.draw_rectangle( objects[0], color=(0,255,0))
if key_flag == 1:
LED_WHITE()# 有按下白灯
src_lbp = img_gray.find_lbp(objects[0])
res = match_face(src_lbp)
print("face"+str(res))
# 识别完成后关闭识别功能
if res != -1:
recg_face = facenamelist[res]
key_flag = 0
else:
# 没脸亮红灯
LED_RED()
drawstr = "FPS"+str(int(clock.fps()))+" "+recg_face
img.draw_string(0, 0, drawstr, color=(0,255,0), scale=1)
lcd.display(img) # Take a picture and display the image.
看的出来cursor很用心的会给代码注释
然后给大家看我改动的部分的对比图
红色是我们改动以后的
黄色是cursor生成的
基本相同 除了字符串的拼接和字符串的结尾判断
这时候就需要人工实现micropython的string.endswith()
这里修改了阈值及其判断结果
可能当时觉得他的返回值没能达到我想要的效果
但是看的出来他99%完美的实现了我想要的逻辑
这一段是主函数的主循环代码
一直循环查找人脸和识别人脸
可以看到改动的变化是
我们会在找到人脸后再检查是否要识别
再做相应的业务逻辑
我估计是当时我和cursor表达的业务逻辑先后有出入
最后便是在屏幕上显示相关文字
3. 结语
2 3周没更新
还记得我刚出第一期的时候
各自媒体平台搜下去才2 3人发布cursor使用和教学心得
2个二月过后
再一看
已经有许多人都开始用上天了
泼天的流量算是被我错过了
哈哈哈
(如果我认真做这个主题的话)
后面我会把一直给大家鸽的机器学习基础放出来
水水文章和短视频
所以 新年见
太叼了!!!
我估计是当时我和cursor表达的业务逻辑先后有出入
[外链图片转存中...(img-74WRwIxE-1736668788308)]
最后便是在屏幕上显示相关文字
[外链图片转存中...(img-x3zeiVDR-1736668788308)]
3. 结语
2 3周没更新
还记得我刚出第一期的时候
各自媒体平台搜下去才2 3人发布cursor使用和教学心得
2个二月过后
再一看
已经有许多人都开始用上天了
泼天的流量算是被我错过了
哈哈哈
(如果我认真做这个主题的话)
后面我会把一直给大家鸽的机器学习基础放出来
水水文章和短视频
所以 新年见