如何基于OpenCV按列统计图像中字符矩形框的数量?
按列统计字符矩形框数量的实现方案
原始字符图像:
已实现单个字符矩形框选的代码:
img = cv2.imread('/content/drive/MyDrive/project/t2.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 img = cv2.imread('/content/drive/MyDrive/project/t2.jpg') image = cv2.resize(img, None, None, 0.4, 0.4) result_img = image.copy() 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]) # 收集有效矩形框的中心x坐标及位置信息 valid_rects = [] for ctr in sorted_ctrs: x, y, w, h = cv2.boundingRect(ctr) if w > 2 and h > 2: center_x = x + w // 2 valid_rects.append((center_x, x, y, w, h)) # 按列分组:设定阈值判断同列 col_threshold = 15 # 可根据图像实际情况调整 columns = [] for rect in valid_rects: cx = rect[0] placed = False for col in columns: avg_cx = np.mean([r[0] for r in col]) if abs(cx - avg_cx) < col_threshold: col.append(rect) placed = True break if not placed: columns.append([rect]) # 按列的左x坐标排序,保证从左到右顺序 columns.sort(key=lambda col: col[0][1]) # 绘制框选和列统计数 for col_idx, col in enumerate(columns): col_count = len(col) col_left_x = col[0][1] # 绘制当前列所有矩形框 for rect in col: x, y, w, h = rect[1], rect[2], rect[3], rect[4] cv2.rectangle(result_img, (x, y), (x+w, y+h), (36,255,12), 2) # 在列上方标注数量 cv2.putText(result_img, str(col_count), (col_left_x, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2) cv2_imshow(result_img) # 控制台输出各列数量 print("各列字符数:", [len(col) for col in columns])
核心逻辑说明
- 过滤无效轮廓:先筛掉宽高小于2的小轮廓,避免噪声干扰统计
- 同列判断:用矩形框的中心x坐标均值做参考,设定阈值(
col_threshold),中心x差值小于阈值则归为同一列 - 排序与标注:对列按左x坐标排序后,在列的上方用红色字体标注该列的矩形框数量
内容的提问来源于stack exchange,提问作者Nara Nart
相关产品推荐
相关产品推荐

