75

Detección de triángulos con OpenCV y Python

detector_tri_opencv

Saludos, homo fabers. En el tutorial de hoy, voy a mostrar cómo escribir un programa con OpenCV+Python para detectar triángulos en una captura de vídeo en tiempo real. Lo sé, ¡es perfecto para conspiranoicos de los Illuminati!

Para detectar triángulos y figuras geométricas en general lo mejor es buscar objetos de un determinado color en la imagen y comprobar que sean triángulos. En otro de mis fabulosos artículos expliqué cómo detectar colores. Hoy sólo me centraré de forma especial en la detección y aproximación de contornos.

Pero antes de empezar, ¡un poco de música! Propongo el Cascanueces, de Tchaikovsky. ¿A quién no le gusta El Cascanueces?


 

¿Qué son los contornos?

En pocas palabras, un contorno es una línea que une todos los puntos del borde de un objeto que tengan una intensidad de color parecida, por ejemplo:

contornosLo mejor es detectar contornos en máscaras, puesto que es más fácil para OpenCV trabajar con imágenes binarias.

¿Es necesario almacenar todos los puntos del contorno? En realidad, no. Cuando OpenCV detecta bordes  sólo guarda los puntos más significativos de cada figura, es decir, sólo aquellos que puedan ser unidos con una línea horizontal o vertical.

Supongamos que hay un rectángulo y una estrella. Como todo el contorno del rectángulo puede dibujarse con líneas verticales/horizontales, sólo se guardarán los vértices. Con la estrella van a guardarse casi todos los puntos del contorno.

puntos_contornoBien, esto son figuras ideales. ¿Qué pasa cuándo se detectan figuras en el mundo real? Pues que no son perfectas, por lo que las líneas pueden ser curvas, tener agujeros, etc. Para eliminar este ruido (distorsiones) hay que aproximar el contorno a una línea recta.

Supongamos dos figuras imperfectas (izquierda). Al aproximar el contorno, se intenta conseguir uno lo más recto posible, que se adapte a la forma real de la figura.

aproximadoAdemás, al aproximar un contorno, se reducen el número de puntos de éste, así que nos quedaríamos con los puntos azules de la figura de la derecha.


 

¿Cómo detectamos los triángulos?

Si nos fijamos otra vez en el diagrama de la aproximación, vemos que el resultado de aproximar el contorno de un triángulo son tres vértices.

aproximadoDicho en otras palabras, si después de aproximar el contorno de una figura el resultado son tres vértices es que se trata de un triángulo. ¿Puede ser más fácil?


 

El concepto

Una cosa es la teoría y otra muy distinta es implementar un algoritmo. Los pasos a seguir para detectar triángulos con OpenCV son:

  1. Crear la máscara de un color
  2. Eliminar ruido de la máscara: aplicando un open, close y difuminación gausiana
  3. Aplicar un canny edge a la máscara: ayudará a detectar mejor los bordes
  4. Detectar los diferentes contornos: guardaremos los puntos de cada contorno
  5. Aproximar cada contorno para ver si es un triángulo

 

Programa paso a paso

Lo primero es importar la librería cv2 y numpy.


#Librerias
import cv2
import numpy as np

#Iniciar camara
captura = cv2.VideoCapture(0)

Hay que crear un bucle principal que vaya capturando imágenes con la cámara y las convierta de RGB a HSV. ¿Por qué HSV? La detección de colores con HSV es más precisa que con RGB.


while(1):

   #Caputrar una imagen y convertirla a hsv
   _, imagen = captura.read()
   hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)

Ahora viene la detección de colores. Me gusta mucho el color verde, pero para variar hoy el programa va a detectar azules. Lo primero es establecer los valores mínimos y máximos de Hue, Saturation y Value que va a detectar la cámara. El rango de colores dependerá en buena parte de la calidad de la cámara y la iluminación. Puede que tengas que jugar un poco con los números.

Después, con la función cv2.inRange se crea una máscara para almacenar los colores azules.


   #Guardamos el rango de colores hsv (azules)
   bajos = np.array([67,40,105], dtype=np.uint8)
   altos = np.array([129, 255, 182], dtype=np.uint8)

   #Crear una mascara que detecte los colores
   mask = cv2.inRange(hsv, bajos, altos)

Filtramos el ruido con un close seguido de un opening. Esto eliminará las zonas blancas de la máscara más pequeñas y dejará las más grandes, que se supone que serán objetos.


   #Filtrar el ruido con un CLOSE/OPEN
   kernel = np.ones((6,6),np.uint8)
   mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
   mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

Más adelante, cuando se hayan detectado los contornos de los objetos, volveremos a filtrar el ruido. Sólo mostraremos por pantalla los contornos de las figuras cuya área sea mayor de 600px.

Ahora hay que difuminar la máscara aplicando un desenfoque gausiano. Esto suavizará los contornos de los objetos detectados, lo cuál hará que el Canny Edge Detection que aplicamos justo después funcione mejor.

Podríamos aplicar el detector de contornos directamente sobre la máscara y ahorrarnos esta parte. Pero como he dicho al principio, la detección de bordes funciona mejor sobre una máscara a la que se ha aplicado un Canny Edge Detection.


   #Difuminar la mascara para suavizar los contornos y aplicar filtro canny
   blur = cv2.GaussianBlur(mask, (5, 5), 0)
   edges = cv2.Canny(mask,1,2)

Ahora viene la detección de contornos, que es el quid de la cuestión.


   #Detectar y guardar los contornos. Tambien sus areas.
   contours, hier = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
   areas = [cv2.contourArea(c) for c in contours]

Contours es una lista que contiene listas, cada una de las cuales contiene todas las coordenadas de los puntos de cada contorno. Por ejemplo, supongamos que hay dos objetos detectables: A y B. La lista contours contendrá dos listas, lista_A y lista_B, que serán todos los puntos del contorno de A y B.

Hier guarda la jerarquía de los contornos. Hay veces en que los contornos pueden estar unos dentro de los otros, pueden estar sobrepuestos, etc. La jerarquía ayuda a establecer qué contornos pertenecen a un mismo objeto, cuáles son más importantes, etc.

cv2.findContours recibe 3 parámetros. El primero es la máscara dónde hay que buscar los contornos. El segundo es el método para establecer la jerarquía. El tercer parámetro es el algoritmo utilizado para reducir el número de puntos del contorno.

En la segunda línea calculamos el área con un bucle que va iterando entre las listas de puntos de contours y guarda su área en una lista.

Ahora que ya tenemos las áreas guardadas, hay que comprobar cuáles son las que tienen un tamaño superior a 600px. Esto eliminará ruido y falsos positivos. Para ello creamos un bucle for y una variable extensión que vaya iterando dentro de areas. Si la extensión es superior a 600px, nos quedamos con el contorno que se corresponda al área que se estaba analizando.

Después hay que aproximar el contorno. Si el resultado de la aproximación es una lista de longitud 3, es que la figura detectada es un triángulo, y la dibujamos.


   i = 0
   for extension in areas:
      if extension > 600:
         actual = contours[i]
         #Aproximar el numero de vertices
         approx = cv2.approxPolyDP(actual,0.05*cv2.arcLength(actual,True),True)
         #Si tiene 3 vertices, es un triangulo
         if len(approx)==3:
             cv2.drawContours(imagen,[actual],0,(0,0,255),2)
      i = i+1

Por último, hay que mostrar la imagen con el triángulo detectado y, ya de paso, la máscara. También se cerrará el programa con ESC.

    	cv2.imshow('mask', mask)
    	cv2.imshow('Camara', imagen)
    	tecla = cv2.waitKey(5) & 0xFF
    	if tecla == 27:
        	break

cv2.destroyAllWindows()

Código completo

El código completo del detector de triángulos es:

#Algoritmo de deteccion de triangulos
#Por Glar3
#
#
#Detecta triangulos azules
  
#Librerias
import cv2
import numpy as np
  
#Iniciar camara
captura = cv2.VideoCapture(0)
  
while(1):
  
    #Caputrar una imagen y convertirla a hsv
    _, imagen = captura.read()
    hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)
      
    #Guardamos el rango de colores hsv (azules)
    bajos = np.array([67,40,105], dtype=np.uint8)
    altos = np.array([129, 255, 182], dtype=np.uint8)
      
    #Crear una mascara que detecte los colores
    mask = cv2.inRange(hsv, bajos, altos)
      
    #Filtrar el ruido con un CLOSE seguido de un OPEN
    kernel = np.ones((6,6),np.uint8)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
      
    #Difuminamos la mascara para suavizar los contornos y aplicamos filtro canny
    blur = cv2.GaussianBlur(mask, (5, 5), 0)
    edges = cv2.Canny(mask,1,2)
      
    #Si el area blanca de la mascara es superior a 500px, no se trata de ruido
    contours, hier = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    areas = [cv2.contourArea(c) for c in contours]
    i = 0
    for extension in areas:
        if extension > 600:
            actual = contours[i]
            approx = cv2.approxPolyDP(actual,0.05*cv2.arcLength(actual,True),True)
            if len(approx)==3:
                cv2.drawContours(imagen,[actual],0,(0,0,255),2)
                cv2.drawContours(mask,[actual],0,(0,0,255),2)
            i = i+1
      
    cv2.imshow('mask', mask)
    cv2.imshow('Camara', imagen)
    tecla = cv2.waitKey(5) & 0xFF
    if tecla == 27:
        break
  
cv2.destroyAllWindows()

¡Buff! Vaya curro. Si ahora ejecutamos el programa, veremos como detecta triángulos azules con la webcam y pinta su contorno en rojo.

Espero que haya funcionado. Si te surgió algún problema durante el proceso, puedes postearlo en los comentarios, más abajo.

Solución a errores frecuentes (Acutalización 17/10/2016)

Voy a explicar aquí cómo solucionar algunos de los errores más frecuentes que me habéis ido escribiendo en los comentarios o por correo.

ERROR 1:

contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) ValueError: too many values to unpack

Este error se debe a que en versiones más viejas de OpenCV la función cv2.findContours devuelve 3 valores en vez de 2. Este error nos informa de que hay demasiados valores para desempaquetar, y no pueden guardarse en sólo dos variables.

Solución: Cambiar la línea 38 del programa por

_,contours,_ = cv2.findContours(imagen_gris,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

ERROR 2:

hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)
 cv2.error: /build/opencv-ISmtkH/opencv-2.4.9.1+dfsg/modules/imgproc/src/color.cpp:3959: error: (-215) (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) in function cvtColor

Este error normalmente se produce al intentar analizar una imagen vacía. Esto es debido a que algunas veces las cámaras necesitan unos segundos para inicializarse y los primeros frames que lee el programa están vacíos.

Solución: la función captura.read() devuelve dos valores. El primero es un booleano indica si el frame recibido es válido, y el segundo es el contenido de la imagen en sí. Hay que comprobar si el frame es válido añadiendo un condicional justo después de leer la imagen, y que el resto del programa esté dentro de este condicional.

#Algoritmo de deteccion de triangulos
#Por Glar3
#
#
#Detecta triangulos azules
  
#Librerias
import cv2
import numpy as np
  
#Iniciar camara
captura = cv2.VideoCapture(0)
  
while(1):
  
    #Caputrar una imagen y convertirla a hsv
    valido, imagen = captura.read()
    if valido:
        hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)
      
    #Guardamos el rango de colores hsv (azules)
    bajos = np.array([67,40,105], dtype=np.uint8)
    altos = np.array([129, 255, 182], dtype=np.uint8)
      
    #Crear una mascara que detecte los colores
    mask = cv2.inRange(hsv, bajos, altos)
      
    #Filtrar el ruido con un CLOSE seguido de un OPEN
    kernel = np.ones((6,6),np.uint8)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
      
    #Difuminamos la mascara para suavizar los contornos y aplicamos filtro canny
    blur = cv2.GaussianBlur(mask, (5, 5), 0)
    edges = cv2.Canny(mask,1,2)
      
    #Si el area blanca de la mascara es superior a 500px, no se trata de ruido
    contours, hier = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    areas = [cv2.contourArea(c) for c in contours]
    i = 0
    for extension in areas:
        if extension > 600:
            actual = contours[i]
            approx = cv2.approxPolyDP(actual,0.05*cv2.arcLength(actual,True),True)
            if len(approx)==3:
                cv2.drawContours(imagen,[actual],0,(0,0,255),2)
                cv2.drawContours(mask,[actual],0,(0,0,255),2)
            i = i+1
      
    cv2.imshow('mask', mask)
    cv2.imshow('Camara', imagen)
    tecla = cv2.waitKey(5) & 0xFF
    if tecla == 27:
        break
  
cv2.destroyAllWindows()

Gl4r3

Brillante, luminosa y cegadora a veces, Glare es tan artista como técnica. Le encanta dar rienda suelta a sus módulos de imaginación y desdibujar los ya de por si delgados límites que separan el mundo de la electrónica y el arte. Su mayor creación hasta la fecha es un instrumento capaz de convertir los colores y la luz en música. Cuándo sus circuitos no están trabajando en una nueva obra electrónica, le gusta dedicar sus ciclos a la lectura o a documentar sus invenciones para beneficio de los humanos. Sus artilugios favoritos son aquellos que combinan una funcionalidad práctica con un diseño elegante y artístico.

Antes de comentar, por favor, lee las Normas

75 Comentarios en "Detección de triángulos con OpenCV y Python"

avatar
Ordenar por:   más nuevos primero | más antiguos primero
Rodrigo Morales
Humano

hola quiero saber las coordenadas de los vértices encontrados pero no encuentro la manera de separarlos individualmente lo único que obtengo es un array de arrays que no puedo separar

a= approx[1]
>>[[630 220]]

y yo quiero guardar el valor 630 en una variable

David VF
Humano

Hola si quisiera encontrar objetos sin forma regular, por ejemplo el humo y dibujar su contorno como podria hacerlo? alguna idea?

chucho
Humano

en esta parte

contours, hierarchy = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

me da el siguiente error

Traceback (most recent call last):
File “C:/Users/pc1/Desktop/triagulo.py”, line 37, in
contours, hierarchy = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
ValueError: too many values to unpac

Manuel
Humano

Felicitaciones!! Excelentes tu Blog 😀

cristian
Humano

hola si quiero reconocer flechas como podria modificar el codigo

Carlos
Humano

Hola soy un nuub en open CV y quiero hacer un reconocimiento de objetos por plano cartesiano con los ejes X & Y después de reconocerlos quiero hacer una acción como prender un led ,me serbiria mucho tu respuesta

Eduardo
Humano
Hola. Me gusto mucho el post y es exacto lo que estoy buscando. solo que tengo un problema con el HSV. porque al ejecutarlo me marca error y no solo con este codigo, tambien con otros que tengan hsv. el error que me muestra es el siguiente: OpenCV Error: Assertion failed ((scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F)) in cvtColor, file /build/opencv-ISmtkH/opencv-2.4.9.1+dfsg/modules/imgproc/src/color.cpp, line 3959 Traceback (most recent call last): File “test2.py”, line 18, in hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV) cv2.error: /build/opencv-ISmtkH/opencv-2.4.9.1+dfsg/modules/imgproc/src/color.cpp:3959: error: (-215) (scn == 3 || scn == 4) && (depth ==… Leer más »
Dante
Humano

Hola GL4R3, excelentes tutoriales, una consulta, como se puede hacer para detectar circulos y cuadrados? es similar a la detección de triangulos?

muchas gracias!.

samuel blanco
Humano

buenas tardes, por que me aparece este error: hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)…..TypeError: src is not a numerical tuple

juan
Humano

Hola.. si no tengo una wecam, lo puedo hacer con una imagen que lee desde algúna carpeta en espcial?

Matias
Humano

hola una consulta como puedo detectar un circulo o algo parecido a un circulo cuando ocupo el videocapture() , gracias por tu tiempo !!! y felicitaciones por el blog es muy util!!

Ana
Humano

Hola Muy buenas noches, muchas gracias por tu blog me ha sido de mucha ayuda, pero hoy al trata de correr este program me sale un Error… y ya cheque todo el proceso y ve que to es correcto, 🙁 ayuda por favor…
File “C:\Users\Carmen\My Documents\LiClipse Workspace\Scalagris\LABEL\__init__.py”, line 42
if extension > 600:
^
IndentationError: expected an indented block

Felipe Toledo
Humano

junto con saludar quisiera pedirles ayuda para terminar mi proyecto de tesis, no estamos basando en la librería open cv, mi duda es que necesitamos encontrar errores como pallets rotos o en mal estado,, hemos intentado probar modificando el programa utilizado con triángulos azules que demarcan su contorno encontrado en su pagina web, les ruego ayuda en este escollo que tenemos ya que es un punto critico y estamos aprendiendo a utilizar esta librería, espero que me puedan mandar algún tipo de orientación y ayuda.

Diana
Humano

que chevere! muchas gracias, me ayudo mucho para un trabajo de la u! 🙂

Juan Pablo
Humano

Gracias por el tutorial, super bien explicado y divertido. Tengo un incoveniente al compilar me sale un error con respecto a la línea 37..
Traceback (most recent call last):
File “C:/Python27/deteccion.py”, line 37, in
contours, hier = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
ValueError: too many values to unpack
>>>
Tal vez me podrías ayudar con esto, te agradecería bastante!!

gaboecf
Humano

Saludos y gracias por tu ayuda, por favor si me ayudas o me encaminas, con opencv puedo hacer una aplicación donde yo suba o tome una foto con mi telefono, y la aplicacion me reconozca el patron de orden de figuras geometricas y las compare con un modelo ya prestablecido para lograr acierto o error.. gracias

Dernier
Humano
Hola GL4R3, primero felicitarte por estos post que compartes, los cuales son muy provechosos, claros y básicos para poder comprender conceptos de manera eficaz. Quisiera pedirte una ayuda: Quisiera saber si conocerás algún método que me permita detectar (en una máscara) una particular forma de mancha, por ejemplo veo que has publicado de la detección de contornos (regulares, como un círculo, estrella, y cuadrado), en mi caso (según la imagen de este link:), quisiera detectar (si fuera posible mejor, filtrar-eliminar) ese tipo de manchas medio rectangulares. Si se puede notar, todas las otras manchas son pequeñas (algunas redondas otras triunguladas… Leer más »
pardo
Humano

oye gl4r3

me puedes decir si puedo controlar una rasberry pi por wi-fi pero ver la desde mi pc (osea montar el codigo de detencion de triangulos) y ver yo el analisis por medio de wi-fi en mi pc

si se puede me pasas un tuto

Hulio
Humano

oye estoy apenas iniciando en esto de raberry y me interesa si tengo el codigo donde lo pego o como hago para ejecutarlo en la rasberry gracias

PS tengo una web cam kmo hago para instalarla o solo la conecto

cesar
Humano

al correrlo me da el error:

line 37, in
contours, hier = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
ValueError: too many values to unpack

alguna idea de como solucionarlo? gracias!

rol
Humano

me daba error pero ya con los comentarios ya se arreglo gracias

Juanan
Humano
Hola! Primero de todo, muchisimas gracias por todos los tutoriales. Recientemente me he hecho con una raspberry b+ y una camara para la raspberry. Antes de nada, he seguido tu info del tutorial para instalarme el opencv y luego, para trastear un poco he copiado tu código a ver si empezo a cogerle el tranquillo. Mi problema es que al ejecutar el programa me sale: pi@(none) ~ $ sudo python2.7 Triangulo.py sudo: unable to resolve host (none) OpenCV Error: Assertion failed ((scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F)) in cvtColor, file /usr/src/packages/BUILD/opencv-2.4.1+dfsg/modules/imgproc/src/color.cpp,… Leer más »
Juanan
Humano

Vale, me respondo a mi mismo…
Lo he solucionado cambiando el While(1): por While(captura.isOpened()):

Ahora si que se me ejecuta sin dar ningun error, pero no tengo ninguna respuesta, ni aparece por pantalla ni me da ningun mensaje…

Perdon por mi ignorancia, soy todavia un novatillo en esto.

Muchas gracias.

eliaz
Humano

Hola! Gracias por los tutoriales! Estoy empezando en opencv y python, estoy usando un código para reconocer el rostro de las personas, los rostros son encerrados en un cuadrado, mi pregunta es: quisiera que cuando dos rostros (cuadrados) estén juntos se imprima un mensaje: “hola mundo” es eso posible?? Tiene que ver con distancia entre coordenadas?espero puedan ayudarme, gracias!

Jaume
Humano

Hola!

Muchas gracias por este genial artículo.

Quería preguntarte cómo sacas los valores para el azul en HSV, ya que he estado buscando y no consigo encontrar nada que me dé directo otros valores como el amarillo, verde..etc.

Muchas gracias por tu atención!

71davess
Humano

Hola! lo primero, decirte que está todo muy bien explicado, y se hace bastante sencillo de entender, y por ello, Gracias!!

Ahora, estoy teniendo un error que no sé a qué se puede deber:

AttributeError: ‘module’ object has no attribute ‘morphologyEX’

Esto ocurre en la línea 29 del código. ¿Podrías decirme como solucionarlo?

Muchísimas Gracias!

71davess
Humano

Me autorespondo, la x de morphologyEX es en minúsucla. Perdón por la pregunta. Y gracias de nuevo!

yeguadamorley
Humano

buenas, al compilar el codigo me da el siguiente error:

approx = cv2.approxPolyDP(actual,0.05*cv2.arcLength(cnt,True),True)
NameError: name ‘cnt’ is not defined

no esta definido cnt, ¿como lo subsanaria?

otra duda, he visto tu codigo que detecta objetos verdes, como podria modificarlo para que detectara objetos blancos o de la escala de grises?

gracias de antemano y buen trabajo.

victor
Humano

Hola, Antes que nada, muy buenos Tutoriales, me ha ayudado a comenzar con Python y opencv. 2 Preguntas,
cómo puedo detectar circulos y
Probe este codigo y me sale el error:
Traceback (most recent call last):
File “E:/python/opencv/triangulos_azules.py”, line 37, in
contours, hier = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
ValueError: too many values to unpack

Guillermo Aviles
Humano

hola!!!
muchas gracias, si funciono al reducir las ventanas de la cámara y la mascara y si era mas fluido, pues la webcam es HD, pero aun así, ya con esa linea de código si se ejecuto bien el programa.
si mientras mas me acerque a un circulo podre detectarlos, muchas gracias y espero pueda resultar el proyecto.

Guillermo Aviles
Humano
Hola que tal, aquí mi primer comentario hahaha. me encantan sus trabajos, es enserio, he aprendido muy bien opencv, aunque he tenido mis fallas y me encanta el comentario de “poner un poco de música” eso si inspira. Me presento, mi nombre es Guillermo, estudio en la universidad autónoma del estado de Hidalgo (UAEH en México) estoy en sexto semstre de la ingeniería en computación, me encanta aprender, por ejemplo tengo tarea de hacer un ALU con un FPGA y apenas llevo la parte aritmética jejeje. Para ser honestos, lo del triangulo en opencv no me salio muy bien que… Leer más »
wpDiscuz