如何改进OpenCV代码实现图像字符数字按列分类分文件夹有序保存
带字母和数字的图片

我已通过以下代码将每个字母和数字裁剪出来,效果如下:
使用的代码:
import cv2 import numpy as np import glob from google.colab.patches import cv2_imshow img = cv2.imread('/content/drive/MyDrive/Dataset/S__23363591.jpg') image = cv2.resize(img,None,None,0.4,0.4) #cv2_imshow(image) gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(gray,190,255,cv2.THRESH_BINARY_INV) kernel = np.ones((1,1), np.uint8) img_dilation = cv2.dilate(thresh, kernel, iterations=1) ctrs,_= cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0]) for i, ctr in enumerate(sorted_ctrs): x, y, w, h = cv2.boundingRect(ctr) roi = image[y:y+h, x:x+w] cv2.rectangle(image,(x,y),( x + w, y + h ),(36,255,12),2) if w >2 and h > 2: #os.chdir('{}'.format(folder_out)) roi = cv2.resize(roi,(224,224)) #cv2.imwrite('letter{}.jpg'.format(i), roi) cv2_imshow(image)
我希望实现以下功能:
- 将同一列的图像保存到同一个文件夹,效果如下:

- 每个列文件夹下再分别创建字母和数字子文件夹,对应保存两类图像,效果如下:

- 图像按顺序命名,效果如下:

请提供能实现上述图像按列分类分文件夹、有序命名功能的改进代码。
改进后的代码
import cv2 import numpy as np import os from google.colab.patches import cv2_imshow import pytesseract # Colab环境需先执行安装命令 # !pip install pytesseract # !sudo apt install tesseract-ocr # 读取并缩放图像 img = cv2.imread('/content/drive/MyDrive/Dataset/S__23363591.jpg') image = cv2.resize(img, None, None, 0.4, 0.4) # 图像预处理 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 190, 255, cv2.THRESH_BINARY_INV) kernel = np.ones((1, 1), np.uint8) img_dilation = cv2.dilate(thresh, kernel, iterations=1) # 查找轮廓并按X坐标排序 ctrs, _ = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0]) # 按列分组轮廓(X坐标差值阈值可根据实际调整) column_groups = [] current_group = [] prev_x = None x_threshold = 20 for ctr in sorted_ctrs: x, _, _, _ = cv2.boundingRect(ctr) if prev_x is None or abs(x - prev_x) <= x_threshold: current_group.append(ctr) else: column_groups.append(current_group) current_group = [ctr] prev_x = x if current_group: column_groups.append(current_group) # 创建根保存目录 root_save_dir = '/content/drive/MyDrive/Dataset/char_columns' os.makedirs(root_save_dir, exist_ok=True) # 处理每一列字符 for col_idx, col_ctrs in enumerate(column_groups, start=1): # 创建列文件夹及子文件夹 col_dir = os.path.join(root_save_dir, f'column_{col_idx}') letters_dir = os.path.join(col_dir, 'letters') digits_dir = os.path.join(col_dir, 'digits') os.makedirs(col_dir, exist_ok=True) os.makedirs(letters_dir, exist_ok=True) os.makedirs(digits_dir, exist_ok=True) # 按Y坐标排序(从上到下) sorted_col_ctrs = sorted(col_ctrs, key=lambda ctr: cv2.boundingRect(ctr)[1]) # 逐个处理字符 for char_idx, ctr in enumerate(sorted_col_ctrs, start=1): x, y, w, h = cv2.boundingRect(ctr) if w > 2 and h > 2: roi = image[y:y+h, x:x+w] roi_resized = cv2.resize(roi, (224, 224)) # 识别字符并分类 roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) _, roi_thresh = cv2.threshold(roi_gray, 190, 255, cv2.THRESH_BINARY_INV) char_text = pytesseract.image_to_string(roi_thresh, config='--psm 10 --oem 3 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').strip() # 保存到对应文件夹 if char_text.isdigit(): save_path = os.path.join(digits_dir, f'{char_idx}.jpg') elif char_text.isalpha(): save_path = os.path.join(letters_dir, f'{char_idx}.jpg') else: continue # 无法识别的字符跳过 cv2.imwrite(save_path, roi_resized) cv2.rectangle(image, (x, y), (x + w, y + h), (36, 255, 12), 2) cv2_imshow(image)
代码说明
- 列分组逻辑:通过判断轮廓X坐标的差值,将同一列的字符归为一组,阈值
x_threshold可根据图像实际间距调整 - 字符分类:使用Tesseract OCR识别字符,通过白名单限定识别范围,区分字母和数字后分别保存
- 文件夹结构:自动创建
column_N列文件夹,每个列文件夹下生成letters和digits子文件夹 - 有序命名:每列内的字符按从上到下顺序命名为
1.jpg、2.jpg等
内容的提问来源于stack exchange,提问作者Nara Nart
相关产品推荐
相关产品推荐

