如何使用Python OpenCV裁剪图像上的每个字符? [英] How to crop each character on an image using Python OpenCV?

查看:99
本文介绍了如何使用Python OpenCV裁剪图像上的每个字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经生成了这样的OpenCV图像

I have generated OpenCV image like this

在代码的最后一行,我如何裁剪和显示当前图像中的每个字符?

From the last line of code, how do I crop and show each character in the current image separately?

代码

    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)

非常感谢您.

推荐答案

这是一种简单的方法:

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

在Otsu阈值化后获得二进制图像后,我们使用

After Otsu's thresholding to obtain a binary image, we sort contours from left-to-right using 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

我们可以使用Numpy切片来提取每个字符.这是每个保存的角色的投资报酬率

We can extract each character using Numpy slicing. 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()

这篇关于如何使用Python OpenCV裁剪图像上的每个字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆