当前位置: 首页 > 知识库问答 >
问题:

如何从图像中提取不同边缘强度的矩形?

夹谷星纬
2023-03-14

我正试图从一张支票的图像中提取帐号。我的逻辑是,我试图找到包含帐号的矩形,对边框进行切片,然后将切片输入到OCR中,从中获取文本。

我面临的问题是,当矩形不是非常突出和浅色,我不能得到矩形的轮廓,因为边缘不是完全相连的。

如何克服这一点?我试过但不起作用的事情是

  1. I不能增加侵蚀迭代,以侵蚀它更多,因为这样边缘与周围的黑色像素连接并形成不同的形状。
  2. 减小阈值偏移量可能会有所帮助,但似乎效率不高。因为代码必须处理几种类型的图像。我可以从偏移量10开始,不断增加偏移量,并检查是否找到了矩形。这将增加很多时间的支票与突出的矩形工作在20或更多的偏移量。因为我没有条件来检查矩形的边缘是否突出,所以必须在所有支票中应用循环。

记住以上几点。有人能帮我解决这个问题吗?

scikit-image==0.13.1
opencv-python==3.3.0.10
from skimage.filters import threshold_adaptive, threshold_local
import cv2
image = cv2.imread('cropped.png')

第2步:

使用自适应阈值从skimage去除背景,使我可以得到帐号矩形框。这对矩形较明显的支票很有效,但当矩形边缘较薄或颜色较浅时,阈值会导致边缘不相连,因此我无法找到轮廓。我在问题的后面附上了这方面的例子。

account_number_block = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
account_number_block = threshold_adaptive(account_number_block, 251, offset=20)
account_number_block = account_number_block.astype("uint8") * 255

第3步:

kernel = np.ones((3,3), np.uint8)

account_number_block = cv2.erode(account_number_block, kernel, iterations=5)
(_, cnts, _) = cv2.findContours(account_number_block.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# cnts = sorted(cnts, key=cv2.contourArea)[:3]
rect_cnts = [] # Rectangular contours 
for cnt in cnts:
    approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
    if len(approx) == 4:
        rect_cnts.append(cnt)


rect_cnts = sorted(rect_cnts, key=cv2.contourArea, reverse=True)[:1]

1.原始图像

第二步:阈值化后去除背景。

第三步:找轮廓找到矩形框的账号。

共有1个答案

姚昊焱
2023-03-14
import numpy as np
import cv2
import pytesseract as pt
from PIL import Image


#Run Main
if __name__ == "__main__" :

    image = cv2.imread("image.jpg", -1)

    # resize image to speed up computation
    rows,cols,_ = image.shape
    image = cv2.resize(image, (np.int32(cols/2),np.int32(rows/2)))

    # convert to gray and binarize
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    binary_img = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 9)

    # note: erosion and dilation works on white forground
    binary_img = cv2.bitwise_not(binary_img)

    # dilate the image to fill the gaps
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    dilated_img = cv2.morphologyEx(binary_img, cv2.MORPH_DILATE, kernel,iterations=2)

    # find contours, discard contours which do not belong to a rectangle
    (_, cnts, _) = cv2.findContours(dilated_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    rect_cnts = [] # Rectangular contours 
    for cnt in cnts:
        approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
        if len(approx) == 4:
            rect_cnts.append(cnt)

    # sort contours based on area
    rect_cnts = sorted(rect_cnts, key=cv2.contourArea, reverse=True)[:1]

    # find bounding rectangle of biggest contour
    box = cv2.boundingRect(rect_cnts[0])
    x,y,w,h = box[:]

    # extract rectangle from the original image
    newimg = image[y:y+h,x:x+w]

    # use 'pytesseract' to get the text in the new image
    text = pt.image_to_string(Image.fromarray(newimg))
    print(text)

    cv2.namedWindow('Image', cv2.WINDOW_NORMAL)
    cv2.imshow('Image', newimg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

结果:03541140011724

结果:34785736216

 类似资料:
  • 我使用了Canny边缘检测器来检测边缘,下面是输出。我需要检测图像中边缘的密度,并选择密度较高的区域。如何在opencv中实现这一点。如何使用opencv查找高强度像素的密度? 如何获得以下输出?

  • 我想提取图像的轮廓,用点坐标序列表示。 使用,我能够生成一个只包含图像边缘的二进制图像。然后,我尝试使用来提取轮廓。不过,结果并不好。 对于每一条边,我通常得到两条线,就像它被认为是一个非常薄的区域一样。我想简化我的轮廓,这样我可以把它们画成单线。或者用不同的函数提取它们,直接产生正确的结果会更好。 我查看了OpenCV的文档,但没有找到任何有用的东西,但我想我不是第一个遇到类似问题的人。有什么功

  • 在openCV中,在应用canny边缘检测后,我想进一步处理结果(仅显示水平线,删除短线等)。但是canny的结果只是另一张图像。我想得到一个描述检测到的边缘的线条数组 我知道著名的霍夫线变换,但结果并不总是好的,这就是为什么我想手动处理精明的结果。输入: 仅输出精明: 输出canny-then-Hough线变换 这是用于检测楼梯边缘的Hough线变换结果(红线)。虽然canny edge检测到一

  • 本文向大家介绍openCV提取图像中的矩形区域,包括了openCV提取图像中的矩形区域的使用技巧和注意事项,需要的朋友参考一下 改编自详解利用OpenCV提取图像中的矩形区域(PPT屏幕等) 原文是c++版,我改成了python版,供大家参考学习。 主要思想:边缘检测—》轮廓检测—》找出最大的面积的轮廓—》找出顶点—》投影变换 运行效果 用到的图片 以上就是本文的全部内容,希望对大家的学习有所帮助

  • 我已经了解了如何使用PIL检测图像中的边缘(图像大部分是白色背景和黑色绘图标记)。如何检测包含这些边的矩形,以便裁剪图像。 例如,我想裁剪如下内容: 成: 或者这个: 成: 我熟悉PIL中的裁剪,但不知道如何围绕对象自动居中。 我已通过执行以下操作来检测边缘: 如何得到包含所有这些边的矩形?

  • 我不熟悉Python中的图像处理,我正在尝试解决一个常见问题。我有一张有人签名的照片。我想找到边缘并裁剪它以适合图像中的签名。 我尝试了Canny边缘检测和使用现有解决方案列表裁剪图像 我尝试了一些解决方案: > https://www.quora.com/How-can-I-detect-an-object-from-static-image-and-crop-it-from-the-image