Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

658
Visualizações
Eliminar líneas horizontales con Open CV

Estoy tratando de eliminar las líneas horizontales de los dibujos de mi hija, pero no puedo hacerlo del todo bien.

El enfoque que sigo es crear una máscara con líneas horizontales ( https://stackoverflow.com/a/57410471/1873521 ) y luego eliminar esa máscara del original ( https://docs.opencv.org/3.3.1/ df/d3d/tutorial_py_inpainting.html ).

Como puede ver en las imágenes a continuación, esto solo elimina parcialmente las líneas horizontales y también crea algunas distorsiones, ya que algunas de las líneas horizontales del dibujo original también terminan en la máscara.

¡Cualquier ayuda para mejorar este enfoque sería muy apreciada!

Crear máscara con líneas horizontales

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

Eliminar líneas horizontales usando máscara

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

Fotos

imagen original

imagen original

Máscara

ingrese la descripción de la imagen aquí

Parcialmente limpiado:

Parcialmente limpiado

over 4 years ago · Santiago Trujillo
4 Respostas
Responde à pergunta

0

  1. Obtener los bordes

  2. Dilatar para cerrar las líneas.

  3. Línea de Hough para detectar las líneas.

  4. Filtrar las líneas no horizontales

  5. Repintar la máscara

  6. Conseguir los bordes

 gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray,50,150,apertureSize=3)

ingrese la descripción de la imagen aquí

  1. Dilatar para cerrar las líneas.
 img_dilation = cv2.dilate(edges, np.ones((3,3), np.uint8), iterations=1)

ingrese la descripción de la imagen aquí

  1. Línea de Hough para detectar las líneas.
 lines = cv2.HoughLinesP( img_dilation, # Input edge image 1, # Distance resolution in pixels np.pi/180, # Angle resolution in radians threshold=100, # Min number of votes for valid line minLineLength=5, # Min allowed length of line maxLineGap=10 # Max allowed gap between line for joining them )
  1. Filtre las líneas no horizontales usando la pendiente.
 lines_list = [] for points in lines: x1,y1,x2,y2=points[0] lines_list.append([(x1,y1),(x2,y2)]) slope = ((y2-y1) / (x2-x1)) if (x2-x1) != 0 else np.inf if slope <= 1: cv2.line(mask,(x1,y1),(x2,y2), color=(255, 255, 255),thickness = 2)
  1. Repintar la máscara
 result = cv2.inpaint(image,mask,3,cv2.INPAINT_TELEA)

ingrese la descripción de la imagen aquí

Código completo:

 import cv2 import numpy as np # Read image image = cv2.imread('input.jpg') mask = np.zeros((image.shape[0], image.shape[1]), dtype=np.uint8) # Convert image to grayscale gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) # Use canny edge detection edges = cv2.Canny(gray,50,150,apertureSize=3) # Dilating img_dilation = cv2.dilate(edges, np.ones((3,3), np.uint8), iterations=1) # Apply HoughLinesP method to # to directly obtain line end points lines = cv2.HoughLinesP( img_dilation, # Input edge image 1, # Distance resolution in pixels np.pi/180, # Angle resolution in radians threshold=100, # Min number of votes for valid line minLineLength=5, # Min allowed length of line maxLineGap=10 # Max allowed gap between line for joining them ) lines_list = [] for points in lines: x1,y1,x2,y2=points[0] lines_list.append([(x1,y1),(x2,y2)]) slope = ((y2-y1) / (x2-x1)) if (x2-x1) != 0 else np.inf if slope <= 1: cv2.line(mask,(x1,y1),(x2,y2), color=(255, 255, 255),thickness = 2) result = cv2.inpaint(image,mask,3,cv2.INPAINT_TELEA)
over 4 years ago · Santiago Trujillo Relatório

0

Entonces, vi que trabajar el dibujo separado del papel daría un mejor resultado. Usé MORPH_CLOSE para trabajar en el papel y MORPH_OPEN para las líneas en la parte interna. Espero que a tu hija le guste :)

 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)

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

 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)

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo Relatório

0

Un enfoque es definir una máscara HSV que solo oculte los detalles necesarios (en este caso, son la persona, los destellos y la firma) .

Después de obtener la máscara adecuada, simplemente desenfoca la imagen en las partes no enmascaradas. Aquí está el resultado con la máscara HSV de límites inferiores 0, 0, 160 y límites superiores 116, 30, 253 :

ingrese la descripción de la imagen aquí

Aquí está el procesamiento de la imagen, en este orden:

(Imagen original), (Máscara),
(Imagen borrosa), (Imagen enmascarada resultante):

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Código:

 import cv2 import numpy as np img = cv2.imread("input.jpg") img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) lower = np.array([0, 0, 160]) upper = np.array([116, 30, 253]) mask = cv2.inRange(img_hsv, lower, upper) img_blurred = cv2.GaussianBlur(img, (31, 31), 10) img_blurred[mask == 0] = img[mask == 0] cv2.imshow("Result", img_blurred) cv2.waitKey(0)

Como puede ver, las líneas onduladas en el cabello de la persona resultaron más delgadas de lo que se suponía. Esto se puede solucionar con algunas iteraciones de erosión de la máscara binaria (simplemente agregue mask = cv2.erode(mask, np.ones((3, 3)), 3) al código bajo la definición de la variable mask ) :

 import cv2 import numpy as np img = cv2.imread("input.jpg") img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) lower = np.array([0, 0, 160]) upper = np.array([116, 30, 253]) mask = cv2.inRange(img_hsv, lower, upper) mask = cv2.erode(mask, np.ones((3, 3)), 3) img_blurred = cv2.GaussianBlur(img, (31, 31), 10) img_blurred[mask == 0] = img[mask == 0] cv2.imshow("Result", img_blurred) cv2.waitKey(0)

Producción:

ingrese la descripción de la imagen aquí

El proceso en el mismo orden de nuevo:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

He agregado una publicación aquí para incluir el programa que puede usar para modificar los valores y ver los resultados en tiempo real, en caso de que tenga otras imágenes a las que desee aplicar el mismo método.

over 4 years ago · Santiago Trujillo Relatório

0

Una extensión de esta respuesta, aquí está el programa que le permitirá aplicar el mismo método (de enmascarar los detalles necesarios de la imagen, aplicar desenfoque a la imagen y reemplazar las partes enmascaradas de la imagen con la imagen original ) en cualquier imagen:

 import cv2 import numpy as np def show(imgs, win="Image", scale=1): imgs = [cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) \ if len(img.shape) == 2 \ else img for img in imgs] img_concat = np.concatenate(imgs, 1) h, w = img_concat.shape[:2] cv2.imshow(win, cv2.resize(img_concat, (int(w * scale), int(h * scale)))) d = {"Hue Min": (0, 179), "Hue Max": (116, 179), "Sat Min": (0, 255), "Sat Max": (30, 255), "Val Min": (160, 255), "Val Max": (253, 255), "k1": (31, 50), "k2": (31, 50), "sigma": (10, 20)} img = cv2.imread(r"input.jpg") cv2.namedWindow("Track Bars") for i in d: cv2.createTrackbar(i, "Track Bars", *d[i], id) img = cv2.imread("input.jpg") img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) while True: h_min, h_max, s_min, s_max, v_min, v_max, k1, k2, s = (cv2.getTrackbarPos(i, "Track Bars") for i in d) lower = np.array([h_min, s_min, v_min]) upper = np.array([h_max, s_max, v_max]) mask = cv2.inRange(img_hsv, lower, upper) mask = cv2.erode(mask, np.ones((3, 3))) k1, k2 = k1 // 2 * 2 + 1, k2 // 2 * 2 + 1 img_blurred = cv2.GaussianBlur(img, (k1, k2), s) result = img_blurred.copy() result[mask == 0] = img[mask == 0] show([img, mask], "Window 1", 0.5) # Show original image & mask show([img_blurred, result], "Window 2", 0.5) # Show blurred image & result if cv2.waitKey(1) & 0xFF == ord("q"): break

Demostración de ejecución del programa:

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda