使用 Open CV 删除水平线

Gor*_*rka 10 python opencv image-processing computer-vision

我试图从女儿的画中删除水平线,但不太正确。

我遵循的方法是创建一个带有水平线的掩码(/sf/answers/4018733001/),然后从原始掩码中删除该掩码(https://docs.opencv.org/3.3.1/ ) df/d3d/tutorial_py_inpainting.html)。

正如您在下面的图片中看到的,这仅部分删除了水平线,并且还产生了一些扭曲,因为一些原始绘图的水平线也最终出现在蒙版中。

任何改进这种方法的帮助将不胜感激!

创建带有水平线的蒙版

来自/sf/answers/4018733001/

import cv2
import numpy as np

img = cv2.imread("input.png", 0)

if len(img.shape) != 2:
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
    gray = img

gray = cv2.bitwise_not(gray)
bw = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, 
cv2.THRESH_BINARY, 15, -2)

horizontal = np.copy(bw)

cols = horizontal.shape[1]
horizontal_size = cols // 30

horizontalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (horizontal_size, 1))

horizontal = cv2.erode(horizontal, horizontalStructure)
horizontal = cv2.dilate(horizontal, horizontalStructure)

cv2.imwrite("horizontal_lines_extracted.png", horizontal)

  
Run Code Online (Sandbox Code Playgroud)

使用蒙版去除水平线

来自https://docs.opencv.org/3.3.1/df/d3d/tutorial_py_inpainting.html

import numpy as np
import cv2
mask = cv2.imread('horizontal_lines_extracted.png',0)
dst = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)
cv2.imwrite("original_unmasked.png", dst)
Run Code Online (Sandbox Code Playgroud)

图片

原图

原图

面具

在此输入图像描述

部分清洁:

部分清洁

Esr*_*oud 9

因此,我发现将绘图与纸张分开进行工作会产生更好的结果。我使用 MORPH_CLOSE 处理纸张,使用 MORPH_OPEN 处理内部的线条。我希望你的女儿喜欢它:)

img = cv2.imread(r'E:\Downloads\i0RDA.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Remove horizontal lines
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV,81,17)
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1))

# Using morph close to get lines outside the drawing
remove_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, horizontal_kernel, iterations=3)
cnts = cv2.findContours(remove_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
mask = np.zeros(gray.shape, np.uint8)
for c in cnts:
    cv2.drawContours(mask, [c], -1, (255,255,255),2)

# First inpaint
img_dst = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

gray_dst = cv2.cvtColor(img_dst, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray_dst, 50, 150, apertureSize = 3)
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,1))

# Using morph open to get lines inside the drawing
opening = cv2.morphologyEx(edges, cv2.MORPH_OPEN, horizontal_kernel)
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
mask = np.uint8(img_dst)
mask = np.zeros(gray_dst.shape, np.uint8)
for c in cnts:
    cv2.drawContours(mask, [c], -1, (255,255,255),2)

# Second inpaint
img2_dst = cv2.inpaint(img_dst, mask, 3, cv2.INPAINT_TELEA)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 在此输入图像描述

  • 棒极了!你让我很高兴戈尔卡!我从小就喜欢画画,所以我明白这对她来说有多重要。❤️ (4认同)
  • @esraa-abdelmaksoud 这太棒了!我可以毫无问题地将其复制到这张图上。我女儿对有多少优秀的人在这方面提供帮助而失去了理智。<3 (3认同)