easyocr未检测到整数值

2024-06-16 11:46:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图检测在我的sqares中找到的数字,我想我可以使用库easyocr,但出于某种原因,我读取了错误的值

这是控制台输出: console

这里我有我所有的照片(它们是分开的,这只是为了展示它们) boxes ¨ 我怎么会找不到任何数字

from PIL import Image
from operator import itemgetter
import numpy as np 
import easyocr
import cv2 
import re
import imutils
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'
reader = easyocr.Reader(['ch_sim','en']) # need to run only once to load model into memory

#Define empty array
Cubes = []

def getNumber(ROI):
    img = cv2.imread(ROI)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret,thresh = cv2.threshold(gray,127,255,0)

    #cv2.imshow(thresh)
    #cv2.imshow('Thresholded original',thresh)
    #cv2.waitKey(0)

    ## Get contours
    contours,h = cv2.findContours(thresh,cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)


    ## only draw contour that have big areas
    imx = img.shape[0]
    imy = img.shape[1]
    lp_area = (imx * imy) / 10

    tmp_img = img.copy()

    for cnt in contours:
        approx = cv2.approxPolyDP(cnt,0.01 * cv2.arcLength(cnt, True), True)
        
        if cv2.contourArea(cnt) > lp_area:

            # Draw box corners and minimum area rectangle
            rect = cv2.minAreaRect(cnt)
            box = cv2.boxPoints(rect)
            box = np.int0(box)
            #cv2.drawContours(tmp_img, [box], 0, (0, 50, 255), 3)
            #cv2.circle(tmp_img, tuple(box[0]), 8, (0, 255, 0), -1)
            #cv2.circle(tmp_img, tuple(box[1]), 8, (0, 255, 0), -1)
            #cv2.circle(tmp_img, tuple(box[2]), 8, (0, 255, 0), -1)
            #cv2.circle(tmp_img, tuple(box[3]), 8, (0, 255, 0), -1)
            #cv2.imshow(tmp_img)
            #cv2.imshow('Minimum Area Rectangle', tmp_img)
            #cv2.waitKey(0)

            ## Correct orientation and crop
            # Link, https://jdhao.github.io/2019/02/23/crop_rotated_rectangle_opencv/
            width = int(rect[1][0])
            height = int(rect[1][1])
            src_pts = box.astype("float32")
            dst_pts = np.array([[0, height-1],
                                [0, 0],
                                [width-1, 0],
                                [width-1, height-1]], dtype="float32")
            M = cv2.getPerspectiveTransform(src_pts, dst_pts)
            warped = cv2.warpPerspective(img, M, (width, height))


            # Run OCR on cropped image
            # If the predicted value is digit print else rotate first
            result = reader.readtext(warped)
            print(result)
            predicted_digit = result[0][1]

            if np.char.isdigit(predicted_digit) == True:
                cv2.imshow("warped " + ROI,warped)
            else: 
                rot_img = warped.copy()
                for i in range(0, 3):
                    rotated_image = cv2.rotate(rot_img, cv2.cv2.ROTATE_90_CLOCKWISE)
                    result = reader.readtext(rotated_image)
                    #if np.array(result).size == 0: 
                    #  continue
                    if not result:
                        rot_img = rotated_image 
                        continue
                    #if len(result) == 0:
                    #  continue
                    predicted_digit = result[0][1]
                    #print(result)
                    #print(predicted_digit)
                    #cv2.imshow(rotated_image)
                    if np.char.isdigit(predicted_digit) == True:
                        cv2.imshow("Image " + ROI, rotated_image)
                        break
                    rot_img = rotated_image                

    return predicted_digit

def sortNumbers(Cubes):

    Cubes = sorted(Cubes, key=lambda x: int(x[2]))

    #Cubes.sort(key=itemgetter(2))  # In-place sorting
    #Cubes = sorted(Cubes, key=itemgetter(2))  # Create a new list

    return Cubes
        

#img = cv2.imread('gulRecNum.jpg') 
img = cv2.imread('boxes.jpg') 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 


# convert to HSV, since red and yellow are the lowest hue colors and come before green
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# create a binary thresholded image on hue between red and yellow
#Change these if cube colours changes?
lower =(20, 100, 100)
upper = (30, 255, 255)
#lower = (0,240,160)
#upper = (30,255,255)
thresh = cv2.inRange(hsv, lower, upper)

# apply morphology
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
clean = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15,15))
clean = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# get external contours
contours = cv2.findContours(clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

result2 = img.copy()

mask = np.zeros(result2.shape, dtype=np.uint8)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
ROI_number = 0

for c in contours:
    cv2.drawContours(result2,[c],0,(0,0,0),2)
    # get rotated rectangle from contour
    rot_rect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rot_rect)
    box = np.int0(box)
    # draw rotated rectangle on copy of img
    cv2.drawContours(result2,[box],0,(0,0,0),2)
    # Gør noget hvis arealet er større end 1.
    # Whats the area of the component?
    areal = cv2.contourArea(c)
    if(areal > 1):
        # get the center of mass
        M = cv2.moments(c)
        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])
        center = (cx, cy)
        print("\nx: ",cx,"\ny: ",cy)
        color = (0, 0, 255)

        cv2.circle(result2, center, 3, color, -1)
        cv2.putText(result2, "center", (int(cx) - 10, int(cy) - 20),
        cv2.FONT_HERSHEY_SIMPLEX, 1.2, color, 2)

        x,y,w,h = cv2.boundingRect(c)
        ROI = 255 - thresh[y:y+h, x:x+w]
        cv2.drawContours(mask, [c], -1, (255,255,255), -1)
        cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI)

        #Read saved image (number)
        result = getNumber('ROI_{}.png'.format(ROI_number))
        print("ROI_number: ", result)
        Cubes.append([cx, cy, result])
        ROI_number += 1

# save result
cv2.imwrite("4cubes_result2.png",result2)   

# display result
imS = cv2.resize(result2, (600, 400))
cv2.imshow("result2", imS)
#cv2.imshow('mask', mask)
#cv2.imshow('thresh', thresh)
SortedCubes = sortNumbers(Cubes)
print("\nFound array [x, y, Cube_num] = ", Cubes)
print("Sorted array [x, y, Cube_num] = ", SortedCubes)
cv2.waitKey(0)
cv2.destroyAllWindows()

编辑

我还拿了这两张照片试试

4

5

编辑2

y:  160
shape:  rectangle 
areal:  723.0
['ta'] : image should have been 4

x:  269 
y:  155
shape:  rectangle 
areal:  637.5
['1'] : image should have been 1

x:  64 
y:  149
shape:  rectangle 
areal:  748.5
['20'] : image should have been 2

x:  125 
y:  141
shape:  rectangle 
areal:  714.5
['5.'] : image should have been 5

x:  222 
y:  127
shape:  rectangle 
areal:  662.5
['3'] : image should have been 3

x:  165 
y:  101
shape:  rectangle 
areal:  666.5
['40'] : image should have been 7

x:  58 
y:  96
shape:  rectangle
areal:  782.5
['L', 'RJ'] : image should have been 8

x:  279
y:  90
shape:  rectangle
areal:  653.5
['EJ'] : image should have been 9

x:  107
y:  84
shape:  rectangle
areal:  717.5
['C'] : image should have been 6

所有图像都是从该图像中剪切的

4412537896


Tags: imageboximghaveresultcv2shapeimshow
1条回答
网友
1楼 · 发布于 2024-06-16 11:46:32

您可能需要不同的处理方法,并且可能需要为tesseract设置页面分段模式(psm

这里,当您使用bitwise_not操作应用adaptive-thresholdingat)时

enter image description here

现在,当您使用psm模式6读取图像时(假设一个统一的文本块)

结果将是:

['34', '215', '28', '7', '5']

不幸的是69未被检测到,如果更改at参数,可能会找到更好的结果

代码:


import cv2
import pytesseract

img = cv2.imread("u3ZTw.png")
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.adaptiveThreshold(gry, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
                            cv2.THRESH_BINARY_INV, 59, 88)
bnt = cv2.bitwise_not(thr)
txt = pytesseract.image_to_string(bnt, config=" psm 6 digits")
txt = txt.strip().split("\n")
print(txt)
cv2.imshow("bnt", bnt)
cv2.waitKey(0)

对于编辑中的照片:


必须为每个不同的图像更改adaptive-threshold参数

更具体地说,您必须更改blockSizeC参数以获得预期的结果

例如,对于数字4和5,我更改了:

  • blockSize:31(以前为59)

  • C:30(以前是88)

  • import cv2
    import pytesseract
    
    img = cv2.imread("num5.png")
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    thr = cv2.adaptiveThreshold(gry, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
                                 cv2.THRESH_BINARY_INV, 31, 30)
    bnt = cv2.bitwise_not(thr)
    txt = pytesseract.image_to_string(bnt, config=" psm 6 digits")
    txt = txt.strip().split("\n")
    print(txt)
    cv2.imshow("bnt", bnt)
    cv2.waitKey(0)
    
  • 图像:

    • enter image description hereenter image description here
  • 结果:

    • ['4']
      
    • ['5']
      
      

相关问题 更多 >