用python检测图像中的文本

2024-04-26 22:03:52 发布

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

我有大约100多张图片,上面有两种不同的文字。图片如下。一个有人,另一个没人。

那么,在python中有没有什么方法可以使用一些代码来检测这些图像中的文本来区分这些图像呢?

如果是这样的话,我想识别被占用的图像并删除未占用的图像。 既然我是python新手,有人能帮我做这个吗?

enter image description here

enter image description here


Tags: 方法代码图像图片区分文字新手
2条回答

使用tesseract OCR Engine和python包装器pytesseract,这只是几行的任务:

import pytesseract
from PIL import Image

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files (x86)\Tesseract-OCR\tesseract.exe"
img = Image.open('D:\\tmp2.jpg').crop((0,0,250,35))
print(pytesseract.image_to_string(img, config='--psm 7'))

我已经在Windows7上测试过了。当然,我假设文本出现在每个图像的同一位置(从您的示例来看,确实是这样)。否则,你需要找到一个更好的种植机制。

这个答案是基于这样一个假设:当你在问题中发布图片时,图片上只有两个不同的文本。所以我假设字符的数量和文本的颜色总是相同的(“房间状态:未占用”和“房间状态”为红色)。也就是说,我会尝试一种更简单的方法来区分这两种不同的类型。这些图像包含的字符彼此非常接近,所以在我看来,将每个字符分开并用OCR识别是非常困难的。我会尝试一种更简单的方法,比如找到包含文本的区域,然后找到文本的纯长度-“uncocuped”在文本中还有两个字符是“composed”,因此在长度上有更大的距离。因此,您可以将图像转换为HSV颜色空间,并使用cv2.inRange()函数提取文本(红色)。然后您可以使用cv2.morphologyEx()将字符合并到一个轮廓,并使用cv2.minAreaRect()获取其长度。希望它能对你有所帮助,或者至少能给你一个新的视角去寻找你的解决方案。干杯!

示例代码:

import cv2
import numpy as np

# Read the image and transform to HSV colorspace.
img = cv2.imread('ocupied.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Extract the red text.
lower_red = np.array([0,150,50])
upper_red = np.array([40,255,255])
mask_red = cv2.inRange(hsv, lower_red, upper_red)

# Search for contours on the mask.
_, contours, hierarchy = cv2.findContours(mask_red,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

# Create a new mask for further processing.
mask = np.ones(img.shape, np.uint8)*255

# Draw contours on the mask with size and ratio of borders for threshold (to remove other noises from the image).
for cnt in contours:
    size = cv2.contourArea(cnt)
    x,y,w,h = cv2.boundingRect(cnt)
    if 10000 > size > 50 and w*2.5 > h:
        cv2.drawContours(mask, [cnt], -1, (0,0,0), -1)

# Connect neighbour contours and select the biggest one (text).
kernel = np.ones((50,50),np.uint8)
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
gray_op = cv2.cvtColor(opening, cv2.COLOR_BGR2GRAY)
_, threshold_op = cv2.threshold(gray_op, 150, 255, cv2.THRESH_BINARY_INV)
_, contours_op, hierarchy_op = cv2.findContours(threshold_op, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours_op, key=cv2.contourArea)

# Create rotated rectangle to get the 4 points of the rectangle.
rect = cv2.minAreaRect(cnt)

# Create bounding and calculate the "lenght" of the text.
box = cv2.boxPoints(rect)
a, b, c, d = box = np.int0(box)
bound =[]
bound.append(a)
bound.append(b)
bound.append(c)
bound.append(d)
bound = np.array(bound)
(x1, y1) = (bound[:,0].min(), bound[:,1].min())
(x2, y2) = (bound[:,0].max(), bound[:,1].max())

# Draw the rectangle.
cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0),1)

# Identify the room status.   
if x2 - x1 > 200:
    print('unoccupied')
else:
    print('occupied')

# Display the result
cv2.imshow('img', img)

结果:

enter image description here

occupied

enter image description here

unoccupied

相关问题 更多 >