我有大约2个不同的文本在上面的100+图像。图片如下所示。一个是占用的,另一个是空闲的。
那么,在python中,有没有什么方法可以使用一些代码来检测其中的文本来区分这些图像呢?
如果是这样,我想要识别已占用的图像并删除未占用的图像。因为我是python的新手,有人能帮我做到这一点吗?
发布于 2018-08-11 08:18:49
这个答案是基于假设图像上只有两个不同的文本,如您在问题中发布的。因此,我假设文本的字符数和颜色总是相同的("Room status: Unoccupied“和"Room status”of“in red color”)。也就是说,我会尝试一种更简单的方法来区分这两种不同的类型。这些图像包含彼此非常接近的字符,所以在我看来,将每个字符分开并用OCR识别它是非常困难的。我会尝试一种更简单的方法,比如找到包含文本的区域,然后找到文本的纯长度--“未占用”在文本中多了两个字符作为“占用”,因此在长度上有更大的距离。因此,您可以将图像转换到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)
结果:
occupied
unoccupied
发布于 2018-08-10 15:59:05
使用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上测试过这一点。当然,我假设文本在每个图像中都出现在相同的位置(从您的示例中看,似乎确实是这样)。否则,你需要找到一种更好的裁剪机制。
https://stackoverflow.com/questions/51778926
复制相似问题