如图所示,我有一张二进制图像,包含一些文字,我想将每个字符裁剪成不同的图像。输出应包含k、7、2、f、5和m的不同图像。我尝试使用Python中的OpenCV,但由于某些原因无法提取。如果能在每个文本上绘制一个框,那也足够了。
回答:
这是一个简单的方法:
- 转换为灰度图
- 使用Otsu阈值
- 查找轮廓,从左到右排序轮廓,并使用轮廓面积进行过滤
- 提取感兴趣区域(ROI)
通过Otsu阈值处理获得二进制图像后,我们使用imutils.contours.sort_contours()
从左到右排序轮廓。这确保了当我们遍历每个轮廓时,字符顺序正确。此外,我们使用最小阈值面积来过滤掉小的噪声。以下是检测到的字符
我们可以使用Numpy的切片提取每个字符。以下是保存的每个字符的ROI
如果你想要相反的结果,只需反转它
ROI = 255 - image[y:y+h, x:x+w]
import cv2from imutils import contoursimage = cv2.imread('1.png')gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1]cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts = cnts[0] if len(cnts) == 2 else cnts[1]cnts, _ = contours.sort_contours(cnts, method="left-to-right")ROI_number = 0for c in cnts: area = cv2.contourArea(c) if area > 10: x,y,w,h = cv2.boundingRect(c) ROI = 255 - image[y:y+h, x:x+w] cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI) cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 1) ROI_number += 1cv2.imshow('thresh', thresh)cv2.imshow('image', image)cv2.waitKey()