• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
    • Questions
    • Teachers
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

1.1K
Views
¿Cómo completar/cerrar un contorno en python opencv?

Tengo una cámara Pi apuntando a una tarjeta sobre un fondo blanco. Sin embargo, las sombras locales parecen estar impidiendo el cierre de los contornos que utilizo para la detección de tarjetas, lo que significa que la detección falla en general. Aquí hay una captura de pantalla de lo que quiero decir:

Captura de pantalla de contornos abiertos

Puede ver que se rasga alrededor de las esquinas inferiores en particular. Este es el código que estoy usando para llegar tan lejos:

 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.blur(gray, (5,5)) gray = cv2.bilateralFilter(gray, 11, 17, 17) #blur. very CPU intensive. cv2.imshow("Gray map", gray) edges = cv2.Canny(gray, 30, 120) cv2.imshow("Edge map", edges) #find contours in the edged image, keep only the largest # ones, and initialize our screen contour # use RETR_EXTERNAL since we know the largest (external) contour will be the card edge. _, cnts, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:1] screenCnt = None # loop over our contours for c in cnts: # approximate the contour peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.3 * peri, True) cv2.drawContours(image, [cnts[0]], -1, (0, 255, 0), 2) # if our approximated contour has four points, then # we can assume that we have found our card if len(approx) == 4: screenCnt = approx; break

¿Hay alguna forma de obligarlo a cerrar contornos específicos? Si desenfoco más la imagen para suavizar las sombras, tampoco funciona, ya que simplemente ignora esas esquinas por no tener un borde. Es molesto que solo esté a unos pocos píxeles de cerrar los contornos, pero nunca lo hace...

editar: ahora tengo una configuración más realista donde el fondo es de color beige y con muchas más sombras interfiriendo. El beige es necesario porque hay algunas tarjetas con bordes blancos, por lo que el blanco no funcionaría. La detección de bordes falla principalmente en el lado izquierdo donde están las sombras.

ingrese la descripción de la imagen aquí

almost 3 years ago · Santiago Trujillo
1 answers
Answer question

0

Como mencioné en mi comentario a su respuesta, una de las formas más fáciles de "conectar" las líneas en el borde es usar operadores morfológicos. En el siguiente código, los bordes de la imagen se dilatan usando una forma de elipsoide. Esta técnica nos permite fusionar las líneas que están cerca y llenar algunos de los espacios vacíos. Puedes tener más información sobre este tema en la Documentación de OpenCV .

 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(9,9)) dilated = cv2.dilate(image, kernel) _, cnts, _ = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

Aquí puede ver la imagen del borde original, la imagen dilatada y el contorno obtenido usando los bordes dilatados (imagen obtenida usando una región recortada de su captura de pantalla original):

Pero, como puede ver y también imaginar, resolver este problema para casos más generales es más complejo y requerirá el uso de otros enfoques, y probablemente sea más amplio que una pregunta SO (o al menos en la forma en que se formula ahora).

Al observar su caso más difícil, podría recomendarle que use otras representaciones de imagen para reemplazar la imagen de entrada en escala de grises (como el canal H del espacio de color HSV) para reducir o atenuar los efectos que tiene con las sombras. También podría explorar algunas de las restricciones en su problema: las tarjetas siempre tienen líneas rectas como bordes y usan un método capaz de manejar formas paramétricas, como el detector de líneas de Hough. Eche un vistazo a esta pregunta, puede darle algunas ideas sobre cómo mejorar sus resultados: ¿Cómo identificar un cuadrado o un rectángulo con longitudes y anchos variables usando javacv?

Observación : el filtrado bilateral es muy costoso computacionalmente, especialmente si está utilizando un RPi para ejecutar su aplicación. Recomendaría invertir en otras alternativas, como un filtrado gaussiano, para reducir la cantidad de ruido en la imagen (suponiendo que realmente necesite hacerlo).

almost 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error