人脸识别窗口无法从MySQL数据库获取姓名等用户信息求助
解决人脸识别无法从MySQL获取用户信息的问题
问题概述
人脸识别系统可正常检测人脸,但无法从MySQL数据库中读取姓名、ID、学号(Roll No)及部门(Department)信息,相关绘制人脸坐标与文本的代码如下:
def face_recog(self): def draw_boudary(img, classifier, scaleFactor, minNeigbors, color, text, clf): if img is not None and img.shape[0] > 0 and img.shape[1] > 0: gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) features = classifier.detectMultiScale(gray_image, scaleFactor, minNeigbors) coord = [] for (x, y, w, h) in features: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3) id, predict = clf.predict(gray_image[y:y + h, x:x + w]) confidence = int((100 * (1 - predict / 300))) conn = mysql.connector.connect(host="localhost", user="root", password="08052002H@ck", database="face_recognizer") my_cursor = conn.cursor() my_cursor.execute("select name from student where ID=" + str(id)) n = "+".join(my_cursor) my_cursor.execute("select Dep from student where ID=" + str(id)) d = "+".join(my_cursor) my_cursor.execute("select Roll_No from student where ID=" + str(id)) r = "+".join(my_cursor) my_cursor.execute("select ID from student where ID=" + str(id)) i = "+".join(my_cursor) if confidence > 77: cv2.putText(img, f"ID:{i}", (x, y - 80), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) cv2.putText(img, f"Roll No:{r}", (x, y - 55), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) cv2.putText(img, f"Department:{d}", (x, y - 30), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255),3) cv2.putText(img, f"Name:{n}", (x, y - 5), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) else: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 3) cv2.putText(img, "Unknown Face", (x, y - 30), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) coord = [x, y, w, h] return coord
问题原因分析
- 游标结果处理错误:MySQL游标执行查询后返回的是元组迭代器,直接用
"+".join(my_cursor)无法正确提取字段值,会导致变量n、d、r、i为空或出现异常。 - 重复创建数据库连接:在人脸检测循环内每次创建连接,既降低效率,也可能引发连接资源泄露问题。
- SQL注入风险:直接拼接
str(id)到SQL语句中,存在SQL注入漏洞,同时若id格式异常会导致SQL执行失败。 - 未处理空查询结果:当数据库中无对应
id的记录时,未做任何处理,会导致文本显示为空。
修正后的代码
def face_recog(self): def draw_boudary(img, classifier, scaleFactor, minNeigbors, color, text, clf): if img is None or img.shape[0] <= 0 or img.shape[1] <= 0: return [] gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) features = classifier.detectMultiScale(gray_image, scaleFactor, minNeigbors) coord = [] # 提前创建数据库连接,避免循环内重复创建 try: conn = mysql.connector.connect(host="localhost", user="root", password="08052002H@ck", database="face_recognizer") my_cursor = conn.cursor() for (x, y, w, h) in features: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3) id, predict = clf.predict(gray_image[y:y + h, x:x + w]) confidence = int((100 * (1 - predict / 300))) n = "Unknown" d = "Unknown" r = "Unknown" i = "Unknown" if confidence > 77: # 使用参数化查询避免SQL注入,同时一次查询所有字段提升效率 my_cursor.execute("select ID, Roll_No, Dep, name from student where ID = %s", (id,)) result = my_cursor.fetchone() if result: i, r, d, n = result cv2.putText(img, f"ID:{i}", (x, y - 80), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) cv2.putText(img, f"Roll No:{r}", (x, y - 55), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) cv2.putText(img, f"Department:{d}", (x, y - 30), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255),3) cv2.putText(img, f"Name:{n}", (x, y - 5), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) else: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 3) cv2.putText(img, "Unknown Face", (x, y - 30), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 255), 3) coord.append([x, y, w, h]) except mysql.connector.Error as err: print(f"数据库错误: {err}") finally: # 确保关闭连接和游标 if 'my_cursor' in locals(): my_cursor.close() if 'conn' in locals(): conn.close() return coord
关键修改说明
- 优化游标结果处理:使用
fetchone()获取单条查询结果,直接解构赋值到对应变量,若无结果则保留默认的"Unknown"。 - 统一数据库操作:将数据库连接移到循环外,且一次查询所有需要的字段,减少数据库交互次数,提升效率。
- 参数化查询:使用
%s作为占位符传递id参数,避免SQL注入,同时保证SQL语句的正确性。 - 异常处理与资源释放:添加数据库异常捕获,确保游标和连接在操作完成后正常关闭,避免资源泄露。
- 初始化默认值:为用户信息变量设置默认值,避免无查询结果时文本显示为空。
额外检查项
- 确认MySQL数据库中
student表的字段名与查询语句一致(如Dep是否为部门字段的实际名称,Roll_No、name、ID是否匹配表结构)。 - 确认
id值与数据库中ID字段的类型一致(如均为整数类型)。
内容的提问来源于stack exchange,提问作者Rambo7153
相关产品推荐
相关产品推荐

