Python 消除图像中的倾斜水平线

Python 消除图像中的倾斜水平线,python,image,opencv,image-processing,line,Python,Image,Opencv,Image Processing,Line,我有一个图像,在文本下面有一条水平线;在通过各种技术应用后,顺序a。HoughLineP和HoughLine以及此代码 image = cv2.imread('D:\\detect_words.jpg') gray = 255 - cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) for row in range(gray.shape[0]): avg = np.average(gray[row, :] > 16) if avg >

我有一个图像,在文本下面有一条水平线;在通过各种技术应用后,顺序a。HoughLineP和HoughLine以及此代码

 image = cv2.imread('D:\\detect_words.jpg')
 gray = 255 - cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 for row in range(gray.shape[0]):
    avg = np.average(gray[row, :] > 16)
    if avg > 0.25:
        cv2.line(image, (0, row), (gray.shape[1]-1, row), (0, 0, 255))
        cv2.line(gray, (0, row), (gray.shape[1]-1, row), (0, 0, 0), 1)
  cv2.imwrite('D:\\words\\final_removed.jpg',image)
我能做到这一点

在这一阶段之后;我正在应用腐蚀和膨胀

kernel = np.ones((3,3), np.uint8) 
img_erosion = cv2.erode(255-gray, kernel, iterations=1) 
img_dilation = cv2.dilate(img_erosion, kernel, iterations=1) 
cv2.imwrite('D:\\words\\final_removed4.jpg',255-img_dilation)

我的问题是,;删除水平线虽然删除了文字,但有像素损失;并不是所有的水平线都被移除。是否有一种新的方法可以将这种损失降到最低,并删除所有水平线(此处仍存在年龄以上的水平线)。

以下是一种方法:

  • 将图像转换为灰度
  • 大津阈值法获取二值图像
  • 创建水平内核和变形打开以检测线
  • 查找轮廓并绘制检测到的线

在转换为灰度后,我们使用大津阈值来获得二值图像

现在我们创建一个特殊的水平内核来检测水平线,然后变形打开以获得检测到的线的掩码

这是在原始图像上绘制的检测线

从这里,我们找到这个面具上的轮廓,并把它们画进去,以有效地去除水平线,从而得到我们的结果

现在,水平线已被删除,要修复文本,您可以尝试使用
cv2.MORPH\u CLOSE
cv2.MORPH\u CROSS
内核并尝试各种内核大小。由于文本中的细节将丢失,因此在放大过多以闭合孔之间存在折衷。另一种方法是使用填充孔。我把这一步留给你

完整代码

import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (45,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)

cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), 3)

cv2.imshow('thresh', thresh)
cv2.imshow('detected_lines', detected_lines)
cv2.imshow('image', image)
cv2.waitKey()

降低平均值>0.25中的0.25,以便t过滤掉较小长度的线。或根据实际行长度进行筛选。删除行后,您可以尝试打开形态学以填补文本中的空白。OP detect_words.jpg中的顶部图像是它的一部分还是它的一部分?您绘制的白线的线厚似乎不足以完全擦除底线。遗憾的是,线厚是一个整数,因此增加到2可能太多。因此,您可能需要缩放整个图像,以使厚度2正好合适。可能的副本非常感谢您的回复。我如何连接缺失A的点,就像我正在做的腐蚀和扩张,但为了平滑它,要传递什么矩阵。你可以使用
cv2.morphologyEx()
,尝试使用不同的内核大小进行实验
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (45,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), 3)
import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (45,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)

cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), 3)

cv2.imshow('thresh', thresh)
cv2.imshow('detected_lines', detected_lines)
cv2.imshow('image', image)
cv2.waitKey()