简体   繁体   English

如何使用 Python OpenCV 裁剪图像上的每个字符?

[英]How to crop each character on an image using Python OpenCV?

I have generated OpenCV image like this我已经生成了这样的 OpenCV 图像

在此处输入图像描述

From the last line of code, how do I crop and show each character in the current image separately?从最后一行代码开始,如何分别裁剪和显示当前图像中的每个字符?

Code代码

    labels = measure.label(thresh, connectivity=2, background=0)
    charCandidates = np.zeros(thresh.shape, dtype="uint8")

    for label in np.unique(labels):

        if label == 0:
            continue

        labelMask = np.zeros(thresh.shape, dtype="uint8")
        labelMask[labels == label] = 255
        cnts = cv2.findContours(labelMask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours(cnts)

        if len(cnts) > 0:
            c = max(cnts, key=cv2.contourArea)
            (boxX, boxY, boxW, boxH) = cv2.boundingRect(c)

            aspectRatio = boxW / float(boxH)
            solidity = cv2.contourArea(c) / float(boxW * boxH)
            heightRatio = boxH / float(crop_frame.shape[0])

            keepAspectRatio = aspectRatio < 1.0
            keepSolidity = solidity > 0.15
            keepHeight = heightRatio > 0.4 and heightRatio < 0.95


        if keepAspectRatio and keepSolidity and keepHeight:
            hull = cv2.convexHull(c)
            cv2.drawContours(charCandidates, [hull], -1, 255, -1)

    charCandidates = segmentation.clear_border(charCandidates)
    cnts = cv2.findContours(charCandidates.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    cv2.imshow("Original Candidates", charCandidates)

    thresh = cv2.bitwise_and(thresh, thresh, mask=charCandidates)
    cv2.imshow("Char Threshold", thresh)

Thank you very much.非常感谢。

Here's a simple approach:这是一个简单的方法:

  • Convert to grayscale转换为灰度
  • Otsu's threshold 大津的门槛
  • Find contours, sort contours from left-to-right, and filter using contour area查找等高线,从左到右对等高线进行排序,并使用等高线区域进行过滤
  • Extract ROI提取投资回报率

After Otsu's thresholding to obtain a binary image, we sort contours from left-to-right using imutils.contours.sort_contours() .在 Otsu 阈值化以获得二值图像后,我们使用imutils.contours.sort_contours()从左到右对轮廓进行排序。 This ensures that when we iterate through each contour, we have each character in the correct order.这确保当我们遍历每个轮廓时,我们以正确的顺序获得每个字符。 In addition, we filter using a minimum threshold area to remove small noise.此外,我们使用最小阈值区域进行过滤以去除小噪声。 Here's the detected characters这是检测到的字符

在此处输入图片说明

We can extract each character using Numpy slicing.我们可以使用 Numpy 切片提取每个字符。 Here's each saved character ROI这是每个保存的角色投资回报率

在此处输入图片说明

import cv2
from imutils import contours

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1]

# Find contours, sort from left-to-right, then crop
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 = 0
for 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), 2)
        ROI_number += 1

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM