关于图书馆识别书的编号并链接mysql库项目的代码解析和分析¶
(因为自己的代码实在拉跨所以请教了同学并仔细研究了他的代码)
findContours函数*1*用于查找给定二值图像
erosion中的轮廓,并以层次结构的形式返回轮廓及其关系。参数
RETR_TREE表示按照轮廓之间的父子关系构建树形结构,
CHAIN_APPROX_NONE`则保留每个轮廓的所有像素点信息。
对于找到的轮廓contours
,循环遍历它们,通过调用cv2.contourArea(contour)
2计算每个轮廓的面积。如果某个轮廓的面积小于100,说明它可能是噪声或较小的对象,程序会将其添加到fill
列表中。
最后,cv2.fillPoly()
函数用于填充图像(erosion),使用指定的颜色(这里是白色 (255, 255, 255)
)来填充那些满足条件(面积小于100)的轮廓。这一步可能用于分割图像,去除小物体或标记特定区域。
cv2.findContours
函数用于从二进制图像(阈值化的图像)中查找轮廓。参数说明如下:
thresh
是要分析的二值图像,通常是通过某种边缘检测或阈值化操作得到的。mode
设定轮廓检索的方式,这里是cv2.RETR_TREE
,意味着会返回一个层次结构的轮廓树,每个轮廓都有其父轮廓,表示轮廓之间的嵌套关系。method
决定了轮廓近似的方式,这里设置为cv2.CHAIN_APPROX_NONE
,表示保留轮廓上的每一个像素点,以便获得更精确的形状。
这段代码的作用是:
- 寻找
thresh
图像中的轮廓。 - 对于找到的每个轮廓(
contour
),计算它的面积(cv2.contourArea
)。 - 如果轮廓的面积在给定的阈值范围内(这里假设小于3000),则计算轮廓的边界框(
cv2.boundingRect
),这是围绕轮廓的一个最小矩形区域。 - 最后,它会在原始图像上绘制这个矩形框,颜色为绿色,线条宽度为2。12
执行这段代码后,你会看到thresh
图像中的小面积轮廓都被标记了出来,形成绿色的矩形框。
- 使用
os.path.join
创建当前文件夹的完整路径,如./moban/folder
。 - 判断该路径是否为实际存在的目录(即
isdir
返回True)。 - 如果是目录,使用列表推导式找出所有的.jpg文件,存入变量
files
。 - 对于找到的每个文件,读取成灰度图像(
cv2.imread
),并将其添加到与value
关联的模板列表中,如果value
对应的列表不存在则新建。
接着,对于每一个模板列表(template_list
):
- 循环遍历列表中的每个模板(
template
)。 - 对模板进行预处理操作,包括二值化(阈值处理)、腐蚀和膨胀(可选)、高斯模糊以及缩放。这些操作都是为了提高模板匹配的质量。
- 处理后的模板替换原列表中的对应项。
cv2.threshold()
用于二值化,cv2.dilate()
和cv2.erode()
用于形态学操作,cv2.GaussianBlur()
用于高斯滤波,cv2.resize()
用于缩放图像。cv2.imshow()
用于显示临时处理过的模板,但在这个上下文中并没有实际调用,因为cv2.waitKey(0)1
通常会在交互式环境中等待按键事件,而这里没有显示窗口。
img_thread = threading.Thread(target=self.recognize_wrapper, args=())
创建了一个新的线程 img_thread
,它的目标(target)是调用函数 self.recognize_wrapper
。setDaemon(True)
被用来设置这个线程为守护线程,这意味着当主线程(即最初的 if __name__ == '__main__':
中的部分)结束时,这个子线程也会随之结束。
img_thread.start()
启动了线程,而 img_thread.join()
是为了让主线程等待 img_thread
完成再继续执行后续操作。这样做的目的是保证主线程在处理结果之前,recognize_wrapper
已经完成了图像识别的工作。
self.result_queue.get()
用于从队列中获取 img_thread
的识别结果。之后对图片进行了腐蚀和缩小的操作(cv2.erode
和 self.reduce_img
),以及轮廓检测和模板匹配。
- 计算轮廓的面积(
area = cv2.contourArea(contour)
)1。 - 使用条件语句过滤掉面积太小(小于100像素)或过大(大于50000像素)的轮廓(
if 0 < area < 100 ... area > 50000:
)。 - 如果轮廓满足条件,绘制矩形框到
roi
区域(cv2.rectangle()
)。 - 提取并裁剪感兴趣的图像部分(
img = roi[y:y + h, x:x + w]
)。 - 可能保存这个裁剪的图片以便后续处理(
cv2.imwrite()
)。 - 对于每个裁剪的图片,尝试找到与某个模板的最佳匹配(这部分代码未完全展示,但提到
best_match
和best_score
用于评估匹配程度)。
具体来说,这部分代码可能是在进行物体检测或图像分割的过程中,筛选出感兴趣的部分,并对其进行单独处理或进一步的模板匹配分析。
- 使用
cv2.matchTemplate
函数计算原始图像img
与模板的相似度得分(这里使用的是TM_CCOEFF_NORMED方法,得分越接近1表示匹配度越高)。 - 找到匹配得分最高的部分(通过
cv2.minMaxLoc
),并更新best_score
和best_match
(模板值)。 - 如果未找到匹配,跳过该模板继续下一次迭代。
- 循环结束后,输出最终的最佳匹配模板值
best_match
,并在图像上标记这个位置。 - 将
best_match
添加到结果列表result
中,并将这些值组合成字符串result_str
,展示在文本编辑框中。 - 最后尝试连接数据库并将识别结果存储起来(这部分的具体行为依赖于
connect_sql
函数,但显然用于保存识别信息)。
完成识别之后就要匹配mysql数据库中的书籍名称¶
- 连接数据库:
使用pymysql库创建数据库连接,参数包括主机地址(host)、用户名(user)、密码(passwd)和要连接的数据库名(db2),以及字符集设置为’utf8’。
- 创建游标:
创建一个游标对象,用于执行SQL语句和获取查询结果。
- 构建SQL查询:
定义一个SQL查询语句,选择library表中bookid为\(result_str\)的bookname字段。
- 尝试执行查询:
尝试执行SQL查询,将\(result_str\)作为占位符插入查询中。
- 获取并处理查询结果:
results = cursor.fetchall()
for row in results:
print('查询结果:', row)
self.textEdit.append(f"查询结果:{row}")
执行查询后,获取所有结果,遍历每一行并打印查询结果到self.textEdit(UI组件)中。
-
错误处理:如果执行时发生错误,捕获
pymysql.Error
异常,并在控制台打印错误信息,并在self.textEdit中添加错误消息。 -
关闭连接:
最后无论查询是否成功,都会确保关闭与数据库的连接以释放资源。
### 如何录入数书籍
-
尝试连接数据库
try: db = pymysql.connect(host='8.147.233.239', user='root', passwd='team2111', db='ryp', charset='utf8') except pymysql.Error as e: print("数据库连接失败:", str(e)) return
使用
pymysql.connect()
函数尝试连接到指定的服务器(IP地址 ‘8.147.233.239’,用户名 ‘root’,密码 ‘team2111’),选择数据库 ‘ryp’,并设置字符集为 ‘utf8’。 -
创建游标:
获取数据库连接的游标,用于执行SQL命令。
-
构造SQL查询:
定义要插入数据的SQL语句,这里假设有一个 ‘book’ 表,有’id’ 和 ‘name’ 两个字段。
-
尝试执行SQL并提交事务:
try: cursor.execute(sql, (id, name)) db.commit() print("数据插入成功") except pymysql.Error as e: db.rollback() print("数据插入失败:", str(e))
使用
cursor.execute()
执行 SQL 插入操作,然后调用db.commit()
提交事务。如果在这个阶段发生错误,则回滚事务(db.rollback()
)并打印错误信息。 -
关闭数据库连接: