import cv2 as cv import numpy as np from matplotlib import pyplot as plt import number_processing def cv_show(name, img): """定义cv_show函数,用于显示图像""" cv.namedWindow(name, cv.WINDOW_NORMAL) # 窗口大小可调 cv.resizeWindow(name, img.shape[1], img.shape[0]) # 窗口大小可调 cv.imshow(name, img) cv.waitKey(0) cv.destroyAllWindows() def cv_info(name, img): """ 定义cv_info函数,确认图像是否成功读取,并且打印图像的基本信息 """ print(f"图像 {name} 信息如下:") if img is None: print("无法读取图像") else: print("图像数据类型:", img.dtype) print("图像类型:", type(img)) print("图像尺寸:", img.shape) print("图像行数:", img.shape[0]) print("图像列数:", img.shape[1]) print() def find_line(img): """ 定义find_line函数,用于寻找分界线 返回一段图像的宽度 """ for i in range(img.shape[1]): # 遍历 a 列 if np.all(img[0, i] >= [230, 230, 230]): # 求该列像素均值,判断是否为白色 mean = np.mean(img[:, i]) if mean >= 240: # 像素均值大于 230 判断为白色 print(f"分界线位置:{i}, 像素均值:{mean}", end="\n\n") return i return -1 # 如果没有找到符合条件的分界线,则返回图像的宽度 def split_img(img): """ 定义split_img函数,用于将图像分割并保存 无返回值 """ img_width = find_line(img) # 返回图像的宽度 n = 0 # 用于计数分割得到的图像数 for i in range(0, img.shape[1], img_width + 1): # 遍历 img 的每一列 image = img[:, i: i + img_width] n += 1 cv.imwrite(f"data/saved_img/image_{n}.PNG", image) # 保存图片 无损压缩格式 PNG def split_num(img): """ 定义split_num函数,用于分割数字并保存 返回数字 """ # 将彩色图像转化为灰度图像 img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 二值化处理,你可以根据需要调整阈值 _, thresh = cv.threshold(img_gray, 128, 255, cv.THRESH_BINARY_INV) # 查找轮廓 contours, _ = cv.findContours(thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) # 对轮廓进行排序,以便从左到右处理数字(可选) contours = sorted(contours, key=lambda x: cv.boundingRect(x)[0]) # 用于存储识别出的数字字符串 recognized_digits = [] # 遍历每个轮廓,并保存每个数字的图片 for i, contour in enumerate(contours): x, y, w, h = cv.boundingRect(contour) digit = thresh[y:y + h, x:x + w] # print(f"第{i+1}个数字的尺寸:{digit.shape[0]}") if digit.shape[0] < 5: # 小数点的轮廓太小,跳过 break recognized_digits.append(str(number_processing.num_list.index(digit.tolist()))) # # 保存数字图片 # cv.imwrite(f'data/saved_img/digit_{i}.png', digit) return int("".join(recognized_digits))