为了账号安全,请及时绑定邮箱和手机立即绑定

使用 pytesseract 和 OpenCV 对平面图屏幕截图进行 OCR

使用 pytesseract 和 OpenCV 对平面图屏幕截图进行 OCR

肥皂起泡泡 2022-06-02 16:31:11
我正在尝试编写一个函数,该函数将获取房屋平面图的 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,, 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)输出' '。我认为我面临的一些问题是:文本可能是灰度的图像是低 DPI(如果这实际上很重要,或者如果它是总分辨率,似乎有些争论)文本格式不一致我被困住了,正在努力提高我的成绩。我想提取的只是“XXX sq ft”(以及所有可能的写法)有一个更好的方法吗?
查看完整描述

2 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

在裁剪图像的底部四分之一后,通过应用这几行来调整第二张图像的大小和更改对比度/亮度:


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')

我设法得到了这个结果:


总约。楼层面积 528 平方英尺。(49.0 平方米)


尽管已尽一切努力确保此处包含的平面图的准确性,但门、窗、房间和任何其他项目的尺寸均为近似值,不对任何错误、遗漏或错误陈述承担任何责任。该计划仅用于@ustraative 目的,任何潜在购买者都应按此使用。所示服务、系统和设备未经测试,无法保证 a8 的可操作性或效率 Made with Metropix ©2019


我没有对图像进行阈值处理,因为您的图像结构彼此不同,并且由于图像不仅是文本,因此 OTSU Thresholding 找不到正确的值。


回答所有问题:Tesseract 实际上最适合灰度图像(白色背景上的黑色文本)。


关于 DPI/分辨率问题,确实存在一些争论,但也有一些经验事实:DPI 值并不重要(因为相同 DPI 的文本大小可能会有所不同)。为了使 Tesseract OCR 发挥最佳效果,您的角色需要(已编辑 :) 30-33 像素(高度),小几 px 会使 Tesseract 几乎无用,而更大的字符实际上会降低准确性,尽管不会显着。(编辑:找到来源-> https://groups.google.com/forum/#!msg/tesseract-ocr/Wdh_JJwnw94/24JHDYQbBQAJ)


最后,文本格式并没有真正改变(至少在你的例子中)。所以你这里的主要问题是文本大小,以及你解析整个页面的事实。如果您想要的文本行始终位于图像的底部,只需提取(切片)您的原始图像,以便您只向 Tesseract 提供相关数据,这也将使其更快。


编辑:如果您还在寻找一种从您的 ocr'ed 文本中提取平方英尺的方法:


text = "some place holder text 5471 square feet some more text"

# store here all the possible way it can be written

sqft_list = ["sq ft", "square feet", "sqft"]

extracted_value = ""


for sqft in sqft_list:

    if sqft in text:

        start = text.index(sqft) - 1

        end = start + len(sqft) + 1

        while text[start - 1] != " ":

            start -= 1

        extracted_value = text[start:end]

        break


print(extracted_value)

5471平方英尺


查看完整回答
反对 回复 2022-06-02
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

文本周围的所有像素化使得 Tesseract 更难做它的事情。我从这里使用了一个简单的亮度/对比度算法来使这些点消失。我没有做任何阈值/二值化。但我确实必须缩放图像才能获得任何字符识别。


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,, config='--remove-background')

print(res)

编辑 上面的代码可能有一些平台/版本依赖。它在我的 Linux 机器上运行,但不在我的 Windows 机器上。为了让它在 Windows 上运行,我将最后两行修改为


res = pytesseract.image_to_string(img,, config='remove-background')

print(res.encode())

tesseract 的输出(我添加了粗体以强调平方英尺):


TT xs?



近似总内部面积 = 50.7 平方米 / 546 平方英尺


所有尺寸仅为估计值,可能不准确。 测量计划可能会发生变化。渲染图 matenala,熔岩,apectes


ne 开发商、管理公司、业主和其他附属公司重新获得所有 ma ther sole discrebon 并且没有 enor scbioe


jements Araxs 是近似值


处理后的图像:

//img1.sycdn.imooc.com//629875870001dd0a08641197.jpg

查看完整回答
反对 回复 2022-06-02
  • 2 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号