Opencv 如何基于白色区域水平剪切图像

Opencv 如何基于白色区域水平剪切图像,opencv,opencv3.0,Opencv,Opencv3.0,我正在为teseract到ocr准备图像。到目前为止,我所做的是将我的图像转换为以下内容: 我基本上想要的是基于白色区域将图像剪切成水平部分。一般来说: 我最关心的是左侧和中间的文本区域。 如果我只选择左区域的问题是,我找不到一种方法来选择中间的部分而不删除某些部分。 我面临的另一个问题是,如果我给出tesseract所有区域(我已经成功地提取了每个包含文本的区域),那么它给了我垃圾,因为pic既有拉丁语言,也没有拉丁语言 另一个重要的问题是没有预定义的大小,因此假设此图片中的大小为标准

我正在为
teseract
ocr
准备图像。到目前为止,我所做的是将我的图像转换为以下内容:

我基本上想要的是基于白色区域将图像剪切成水平部分。一般来说:

我最关心的是左侧和中间的文本区域。

如果我只选择左区域的问题是,我找不到一种方法来选择中间的部分而不删除某些部分。 我面临的另一个问题是,如果我给出
tesseract
所有区域(我已经成功地提取了每个包含文本的区域),那么它给了我垃圾,因为pic既有拉丁语言,也没有拉丁语言

另一个重要的问题是没有预定义的大小,因此假设此图片中的大小为标准大小是错误的


重述:如何基于白色区域水平剪切图像

您可以使用参数增加或减少行数。我跟着

加载和反转图像:

import cv2
import numpy as np

img = cv2.imread('lic.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = 255 - img
获取边缘:

edges = cv2.Canny(gray,50,150,apertureSize = 5)
minLineLength = 10
maxLineGap = 30
使用概率Hough变换查找直线:

lines = cv2.HoughLinesP(edges,.7,np.pi/180, 100,minLineLength,maxLineGap)

for line in lines:
    for x1,y1,x2,y2 in line:
        if x2-x1 == 0:
            continue
检查坡度是否介于-45度和45度之间(您可以根据需要进行调整):

dy=(y2-y1)
dx=(x2-x1)
如果-1
这张照片是由谁拍摄的:


我查阅了文档,看看是否有什么需要。是的,我发现了一个有趣的特性,叫做从

轮廓的范围定义为轮廓面积与该轮廓边界矩形面积的比值。因此,该值越接近1,轮廓越像矩形

对于您提供的图像,它不会检测到看起来像阿拉伯语的单词。但如果在此之前进行一些形态学操作,它将起作用

代码:

path = 'C:/Users/Desktop/Stack/contour/'
im = cv2.imread(path + 'lic.png')

#--- resized because the image was to big ---
im = cv2.resize(im, (0, 0), fx = 0.5, fy = 0.5)
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

ret2, th2 = cv2.threshold(imgray, 0, 255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)

im2 = im.copy()
_, contours, hierarchy = cv2.findContours(th2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
count = 0

#--- It all begins here ---
for cnt in contours:
        area = cv2.contourArea(cnt)
        x, y, w, h = cv2.boundingRect(cnt)
        rect_area = w * h
        extent = float(area) / rect_area
        if (extent > 0.5) and (area > 100):      #--- there were some very small rectangular regions hence I used the area criterion ---
            count+=1
            cv2.drawContours(im2, [cnt], 0, (0, 255, 0), 2)

cv2.imshow(path + 'contoursdate.jpg', im2)

print('Number of possible words : {}'.format(count))
结果:

path = 'C:/Users/Desktop/Stack/contour/'
im = cv2.imread(path + 'lic.png')

#--- resized because the image was to big ---
im = cv2.resize(im, (0, 0), fx = 0.5, fy = 0.5)
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

ret2, th2 = cv2.threshold(imgray, 0, 255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)

im2 = im.copy()
_, contours, hierarchy = cv2.findContours(th2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
count = 0

#--- It all begins here ---
for cnt in contours:
        area = cv2.contourArea(cnt)
        x, y, w, h = cv2.boundingRect(cnt)
        rect_area = w * h
        extent = float(area) / rect_area
        if (extent > 0.5) and (area > 100):      #--- there were some very small rectangular regions hence I used the area criterion ---
            count+=1
            cv2.drawContours(im2, [cnt], 0, (0, 255, 0), 2)

cv2.imshow(path + 'contoursdate.jpg', im2)

print('Number of possible words : {}'.format(count))


在这种情况下,我只是画了轮廓。另一方面,您可以通过拟合一个边界矩形来裁剪这些区域,并将它们分别提供给OCR引擎。

您看过这个吗?我认为默认情况下它是在寻找黑线,但您可以轻松地反转图像。@Zev很好,但在此之前,OP想知道在哪里绘制这些线。@MimirLind是否也可以添加原始图像?我正在尝试使用Zev提供的链接。没错@Jeru,我首先要知道在哪里画线。原始图像是我的身份证。我编辑了一点以隐藏我的个人信息,我希望我没有打扰它。@MimirLind足够好。我正在尝试一种不同的方法。不需要画线的人。我不想要阿拉伯语,如果可以消除它,你知道如何继续吗?你可以尝试在
if(extent>0.5)和(area>100)中改变
extent
参数