Question: I am trying to remove horizontal lines from my daughter's drawings, but can't get it quite right. The approach I am following is creating a mask with horizontal lines (https://stackoverflow.com/a/57410471/1873521) and then removing that mask from the original (https://docs.opencv.org/3.3.1/df/d3d/tutorial_py_inpainting.html). As you can see in the pics below, this only partially removes the horizontal lines, and also creates a few distortions, as some of the original drawing horizontal-ish lines also end up in the mask. Any help improving this approach would be greatly appreciated! Create mask with horizontal lines From https://stackoverflow.com/a/57410471/1873521 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)  Remove horizontal lines using mask From 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)  Pics Original picture  Mask  Partially cleaned: 

Answer: So, I saw that working on the drawing separated from the paper would lead to a better result. I used MORPH_CLOSE to work on the paper and MORPH_OPEN for the lines in the inner part. I hope your daughter likes it :) 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)    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)