首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用python检测图像中的文本

使用python检测图像中的文本
EN

Stack Overflow用户
提问于 2018-08-10 12:20:50
回答 2查看 9.8K关注 0票数 -1

我有大约2个不同的文本在上面的100+图像。图片如下所示。一个是占用的,另一个是空闲的。

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

如果是这样,我想要识别已占用的图像并删除未占用的图像。因为我是python的新手,有人能帮我做到这一点吗?

EN

回答 2

Stack Overflow用户

发布于 2018-08-11 08:18:49

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

示例代码:

代码语言:javascript
复制
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)

结果:

代码语言:javascript
复制
occupied

代码语言:javascript
复制
unoccupied
票数 3
EN

Stack Overflow用户

发布于 2018-08-10 15:59:05

使用tesseract OCR Engine和python包装器pytesseract,只需几行代码即可完成任务:

代码语言:javascript
复制
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上测试过这一点。当然,我假设文本在每个图像中都出现在相同的位置(从您的示例中看,似乎确实是这样)。否则,你需要找到一种更好的裁剪机制。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51778926

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档