我正在尝试编写一个函数,该函数将获取房屋平面图的jpg并使用OCR提取写在图像上某个地方的平方英尺
import requests
from PIL import Image
import pytesseract
import pandas as pd
import numpy as np
import cv2
import io
def floorplan_ocr(url):
""" a row-wise function to use pytesseract to scrape the word data from the floorplan
images, requires tesseract
to be installed https://github.com/tesseract-ocr/tesseract/wiki"""
if pd.isna(url):
return np.nan
res = ''
response = requests.get(url, stream=True)
if response.status_code == 200:
img = response.raw
img = np.asarray(bytearray(img.read()), dtype="uint8")
img = cv2.imdecode(img, cv2.CV_8UC1)
img = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,2)
#img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
res = pytesseract.image_to_string(img, lang='eng', config='--remove-background')
del response
del img
else:
return np.nan
#print(res)
return res
但是我没有获得太多成功。实际上,只有大约四分之一的图像输出包含平方尺的文本。
例如当前
floorplan_ocr(https://i.imgur.com/9qwozIb.jpg)
输出'K\'Fréfiéfimmimmuuéé\n2|; apprnxx 135 max\nGArhaPpmxd1m max\n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\nTOTAL APPaux noon AREA 523 so Fr, us. a 50. M )\nav .Wzms him "a! m m... mi unwary mmnmrmm mma y“ mum“;\n‘ wmduw: reams m wuhrmmm mm“ .m nanspmmmmy 3 mm :51\nmm" m mmm m; wan wmumw- mm my and mm mm as m by any\nwfmw PM” rmwm mm m .pwmwm m. mum mud ms nu mum.\n(.5 n: ma undammmw an we Ewen\nM vagw‘m Mewpkeem'
(花费很长时间)
floorplan_ocr(https://i.imgur.com/sjxMpVp.jpg)
输出' '
。
我认为我面临的一些问题是:
我陷入困境,并努力改善自己的成绩。我只想提取“ XXX平方英尺”(以及所有可能写入的方式)
有更好的方法吗?
非常感谢。
答案 0 :(得分:1)
文本周围的所有像素化使Tesseract难以执行其操作。 我用一个简单的brightness/contrast algorithm from here使点消失了。我没有做任何阈值/二值化。但是我没有必须缩放图像以获得任何字符识别。
import pytesseract
import numpy as np
import cv2
img = cv2.imread('floor_original.jpg', 0) # read as grayscale
img = cv2.resize(img, (0,0), fx=2, fy=2) # scale image 2X
alpha = 1.2
beta = -20
img = cv2.addWeighted( img, alpha, img, 0, beta)
cv2.imwrite('output.png', img)
res = pytesseract.image_to_string(img, lang='eng', config='--remove-background')
print(res)
修改 上面的代码可能与平台/版本有关。它在我的Linux机器上运行,但不在我的Windows机器上运行。为了使其在Windows上运行,我将最后两行修改为
res = pytesseract.image_to_string(img, lang='eng', config='remove-background')
print(res.encode())
tesseract的输出(我加粗以强调平方英尺)
TT xs?
IN
大约内部总面积= 50.7平方米/ 546平方英尺
所有尺寸仅是估计值,可能不是精确的测量计划 是主题更改吗? renderngs图matenala,熔岩, 观点
开发人员,管理公司,所有者和其他关联企业 删除所有的主要离散内容,并且没有任何异常jejes Araxs是近似的
处理后的图像:
答案 1 :(得分:1)
通过应用以下几行来调整并调整第二张图像上的对比度/亮度,在后裁剪图像的底部四分之一:
nameof()
我设法得到了这个结果:
总约数。面积528 SQ.FT. (49.0平方米)
尽一切努力确保地板的准确性 这里包含的平面图,尺寸:门,窗,房间和任何 其他项目均为近似值,因此不承担任何责任 错误,遗漏或错误陈述。该计划适用于@ustrative 仅供参考,任何潜在的购买者都应将其作为本产品使用。 显示的服务,系统和设备尚未测试,没有 保证可以给出a8的可操作性或效率 Metropix©2019
由于您的图像结构互不相同,因此我没有对图像进行保护,并且由于图像不仅是文本,因此OTSU阈值找不到正确的值。
回答所有问题:Tesseract实际上最适合灰度图像(白色背景上的黑色文本)。
关于DPI /分辨率问题,确实存在一些争论,但也有一些经验性的事实:DPI值并不重要(因为相同DPI的文本大小可能有所不同)。为了使Tesseract OCR发挥最佳效果,您的字符需要被(编辑:) 30-33像素(高度),再减小几px会使Tesseract几乎无用,而较大的字符实际上会降低准确性,尽管并不明显。 (编辑:找到了来源-> https://groups.google.com/forum/#!msg/tesseract-ocr/Wdh_JJwnw94/24JHDYQbBQAJ)
最后,文本格式并没有真正改变(至少在您的示例中)。因此,这里的主要问题是文本大小,以及您解析整个页面的事实。如果您想要的文本行始终位于图像的底部,则只需提取(切片)原始图像,以便仅向Tesseract输入相关数据,这样也可以使其速度更快。
编辑: 如果您还在寻找一种从文本中提取平方英尺的方法:
img = cv2.imread("download.jpg")
img = cv2.resize(img, (0, 0), fx=2, fy=2)
img = cv2.convertScaleAbs(img, alpha=1.2, beta=-40)
text = pytesseract.image_to_string(img, config='-l eng --oem 1 --psm 3')
5471平方英尺