Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Once

#41
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
CitarSi quiero un lenguaje que combine POO (programacion orientada a objetos) con velocidad, elijo Python...
¿Velocidad? ¿python? Eso si que no es compatible xD
Python es un lenguaje interpretado y no tiene nada que hacer contra uno compilado en cuanto a velocidad.

Eso no es del todo cierto, aunque como ya dijiste, Pytohn es un lentguaje interpretado y los lenguajes interpretados son más lentos, Python te da la posibilidad de compilar (usando Cython) librerias con por decirlo de alguna forma, tres opciones: a) C, B) Algo que yo llamo Cython que es una mezcla de Python y C. Obtienes lo mejor de ambos mundos. y C) Pytohn puro y duro.

Yo usé Cython para los cuello de botella en un proyecto de visión artificial y al final no tenía nada que envidiarle a C.




Con respecto al debate, cuando intenté aprender C++ también encontré la sintaxis muy extraña (no sé que tan compatible sea con C) al punto que odio la sintaxis de C++.

Saludos!
#42
Python / Re:[Python3] Interfaces graficas #1 con QT4/5
Noviembre 30, 2017, 04:00:53 AM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
buen tutorial, pero no hay una forma de hacerlo sin PyCharm? No uso Pycharm por que cuesta un dineral, se que existe la version comunity que es gratis, pero te carcome toda la memoria RAM y mi pc solo tine 2GB, constantemente se cuelga por quedarse sin memoria.

Como menciona al inicio del post, se puede usar cualquier otro IDE. Es indiferencte a la hora de programar en Python. Ahora, si lo preguntas por el diseñador, ese es un software completamente diferente que no tiene nada que ver con el IDE. Si usas Windows, acá te dicen cómo instalarlo: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta si usas Linux, lo más seguro es que esté en los respositorios de la distroq ue estés usando.

Saludos!
#43
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Falso, nada de eso se basa en el concepto de éter.

Dices o refutas que entonces la criptomoneda no se llama así por ese quinto elemento ?
Se te ocurre asociar la palabra con alguna otra definición ?

Perdón, me refería a esto:

Citar- De tal forma que las ondas de radio, la carga inalámbrica
- El Bluetooth
- Y el mismo 802.11
- Se basan en Tesla y en sus conceptos del "ether"

Con respecto a la criptomoneda, no tengo idea.

Saludos!
#44
Es cierto que los físicos necesitanam una manera de explicar como se transportaba la luz en el vacío puesto que ya habían descubierto que la luz se transportaba como una onda y pensaron que justo como el resto de ondas conocidas hasta entonces (las mecánicas) la luz también necesitaba un medio en el cual transportarse. Así que inventaron el eter. Luego, el experimento de Michelson-Morley no pudo detectar la existencia del eter.

Simplemente por la naturaleza eletromagnética de la luz (donde el campo magnético alimenta al electromagnético y viceversa) éstas ondas pueden viajar por el vacio sin necesidad de un medio con propoedades extrañas como el éter.

Cuando analisas un espectro, estás midiendo ese espectro no al éter ni una propiedad de el.

No, no toda las formas de energía necesitan medios para propagarse.

Falso, nada de eso se basa en el concepto de éter.

Perdón por arruinar la diversión, pero me sentía en la obligación de corregir esas pequeñas impresiciones.

Saludos!
#45
Por dios, esto es asombroso, ya quisiera ver luchando este tipo de robots con los de MegaBots.

Saludos!
#47
Underc0de / Re:Desafio #9 - Viernes Negro
Noviembre 16, 2017, 02:35:53 PM
Bueno, a mí me tocó explicar el segundo:

Lo primero que notamos es que nos dan unas "palabras" algunas sin sentido y en la pista nos dicen "corner" (esquina en inglés) y una serie de letras que eliminado las repetidas nos quedamos con RULD lo que nos lleva a pensar en "direcciones" puesto que Right: derecha, Up: Arriba, Left: izquierda, Down: abajo.

Así, si nos paramos en la letra superior izquierda y seguimos las indicaciones, obtenemos el mensaje:

CRIPTOGRAFIACLASICA -> CRIPTOGRAFÍA CLÁSICA

Saludos!
#48
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Verás, en un principio intenté hacerlo con Instagram pero no logré nada. Y vi que el mecanismo era similar en twitter. Me explico:
Cuando accedes a un perfil en instagram o en twitter, para obtener más resultados debes scrollear hacia abajo. Sé más o menos algo de urllib y requests pero con eso sólo descargo el código de la página para los primeros elementos.
No sé si hay alguna forma de ejecutar javascript mediante esos módulos o de activar ese OnScroll de Javascript.
Y por eso ando algo perdido y recurrí a un módulo específico para esto ;D Pero ya seguiré investigando a ver si hay alguna otra manera  ;)

Exacto, por eso mencioné que lo ideal seria intentar simular un navegador, aunque por más que se use javascript ese contenido nuevo tiene que venir del servidor, solo hay que encontrar como hacer esas peticiones y replicarlas. Porque dudo que por la API se puede hacer algo.

Si descubres como hacerlo, te gradecería si lo publicas puesto que me interesa y hasta diciembre no tengo tiempo .

Saludos!
#49
Si estas limitado por el API, dudo mucho que puedas hacer algo.


Ahora, ¿intentaste simular un navegador, pedir la página y parsear la información?
Tenía a medias un proyecto así (justo pensando en esas posibles limitaciones) antes de entrar a la universidad y lo tuve que dejar tirado. Es lo único que se me ocurre.

Saludos!
#50
Hola bro,

Tomanste la captura de TODO menos del error. El error es lo que sale justo debajo de la captura que colocaste.

Ahora, por experiencia, diria que el error es que estás intentando correr el script diseñado para Python 3 en una versión de Python 2

Por favor, o avísame si estás corriendo en Python 2, o coloca el error completo que te tira Python.

PD: Olvidaste borrar tu usuario en la segunda línea de la captura.


Saludos!
#51
Hola,

Como te expliqué en mi primer respuesta, cuando guardas algo en un archivo de texto, ésta información se guarda como una cadena de caracteres (los archivos no conocen Python y por lo tanto no pueden almacenar objetos de Python ni de cualquier otro lenguaje). Por lo que el problema es que estás compararndo un string con una lista y es muy fácil comprobarlo, mira:

Código: python, 24, 25
def logon():
    while True:
        cmd_input = input("login: ")
   
        global login_name
        login_name = cmd_input

        cmd_input = int(input("password: "))

        global login_pass
        login_pass = cmd_input

        list_cr_input = [login_name, login_pass]

        file = open('boot_data.txt', 'r')
        for ln in file.readlines():
            list_cr_file = ln
            print(list_cr_input)
            print(list_cr_file)

        file.close()
        print("->")
        print(list_cr_file)
        print(type(list_cr_file))
        print(type(list_cr_input))
        if list_cr_file == list_cr_input:
            break
            print("Welcome %s!" % login_name)
            maincmd()
        else:
            print("login incorrect!")

def password():
    list_cr_file = ["n1sendev", 1234]
    file = open('boot_data.txt', 'w')
    file.write('\r%s' % list_cr_file)
    file.close()

password()
logon()


Vas a obtener algo así:

Citar<class 'str'>
<class 'list'>

Así que de nuevo te remito a mi primer comentario, si insistes en querer comparar dos listas la mejor opción es usar serialización. Si no quieres usar serialización, vas a tener que diseñar un "protocolo", que te permita parsear ese string que se PARECE a una lista y convertirlo a una lista de verdad en Python.

Saludos.
#52
Ok, mira las líneas que te seleccioné:

Código: python, 18, 14
def logon():
    cmd_input = input("login: ")
   
    global login_name
    login_name = cmd_input

    cmd_input = input("password: ")

    global login_pass
    login_pass = cmd_input

    file = open('boot_data.txt', 'r')
    for ln in file.readlines():
        name = ln

    file.close()

    if login_name == name and login_pass == password:
        print("Welcome %s!" % login_name)
        maincmd()
    else:
        print("login incorrect!")

def password():
    list_cr = ["n1sendev", 1234]
    file = open('boot_data.txt', 'w')
   
    for item in list_cr:
        file.write('\r%s' % item)
    file.close()

password()


En la 14, el problema es que estpás sobreescribiendo name, por lo que lee la primer línea y la guarda en name, pero luego lee la segunda y la guarda en name sobreescribiendo el valor anterior.

En la 18, el problema es que estás intentando comparar una variable (login_pass) con una función (password).

Saludos.
#53
Hola n1sendev sería de gran ayuda si puedieras colocar el código que estás usando, en especial para ver cómo estás guardando y qué formato estás usando.

Ahora, hay un par de cosas que no quedan claras, por ejemplo, quieres validar también tipos, es decir, "1234" es distinto a 1234?. Si es así, usar un simple archivo de texto no te va a servir, porque en él se guardan siempre cadenas, entonces no podras saber si lo que está en el archivo originalmente fue un número o un string. (Tendrías que implementar una especie de  protocolo para diferencias entre tipos)

Ahora, una solución, que te puedo dar y que te haría la vida mucho más fácil es que uses serialización (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta) que te permite guardar un objeto en un archivo de texto y luego recuperar. En Python tienes dos opciones, Pickle y cPickle No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Usando serialización, solo tienes que escribir la lista en el archivo de texto, luego la lees y lo que te retorna no es un string, sino la lista como tal y ahí, las puedes comparar.

Para la comparación, necesitamos más información, porque si no te importa el tipo de los datos, y asumiendo que guardas cada lista en una línea separada, puedes leer toda la línea, hacer un split (para separar por espacios) y luego comparar estos datos separados con la lista. Pero acá hay otro problema y es cómo quieres hacer la comparación: ¿el orden importa?

Saludos.

#54
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Según este enlace de arriba, dicen que ya es posible decifrar rsa privada. Con esto ya seria posible desbpoquear bios firmadas de laptops como HP?

Hola, no soy  un experto en la materia y ojalá alguien me corrija si digo lo que no es:

El problema del link que posteas más arriba es que el fallo está en la implementación del cifrado RSA en algunos chips, más no en RSA como tal. Que son dos cosas completamente distintas.

Ahora, respondiendo a tu pregunta, si se puede, siempre y cuando el chip que use el PC al que quieres acceder sea vulnerable.

Las buenas noticias es que podemos dormir tranquilos porque el fallo no implica que rempieron RSA, solo una implementación.

Saludos.
#55
Para mí depende, por ejemplo,si es para leer sólo por diversión (literatura) los prefiero en formato físico, pero los de la universidad los prefiero dígitales puesto que son muchos y muy voluminosos. Sólo los temas más difíciles para mí los imprimo porque me permiten hacer anotaciones más fácil.

Saludos.
#56
Muy buen post brother, me alegra ver más gente trabajando con Python e imágenes, el potencial es enorme.

Tu post me dio una idea para una aplicación.

Saludos! y buen trabajo.
#57
Matemáticas, si te quieres dedicar seriamente a la criptografía vas a necesitas un buen nivel de matemáticas.

Como libro, te recomiendo  "Information Security Principles and Practice" de Mark Stamp

Saludos.
#58
Hola Jack-C0de gracias por la respuesta, lo del photoshop no sabía que se podía hacer. Los otros dos, supongo que fue por el calor del momento que decidí programar casi todo yo mismo, pero sí, que salía más fácil y rápido como tu lo propones.

Saludos!
#59
Fuente: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


Aunque en la entrada anterior ([Parte II: visión artificial] Primeros pasos con OpenCV y Numpy) se habló un poco sobre numpy éste se merece una entrada completa (y más) debido a que el corazón de la visión artificial son las operaciones matriciales lo que hace de numpy una parte imprescindible incluso cuando usamos librerias que hacen gran parte del trabajo como OpenCV. El objetivo de ésta entrada es familiarizarnos un poco más con NumPy y así poder dejar sentado el terreno para comenzar a hacer visión artificial.

¿Cómo recorrer una matriz?
Uno de los principales problemas/confusiones que he notado es a la hora de recorrer una matriz. La confusión es simple, suelen tratar a las matices como sistemas coordenados...

Figura: estructura de una matriz.

Por convención a cada sección horizontal de la matriz la llamamos una fila (verde) y a cada sección vertical una columna (azul). Además, la numeración de las filas y columnas comienza desde la esquina superior izquierda (el origen), las filas crecen hacía abajo y las columnas hacía la derecha.

Para acceder a un elemento, se debe especificar la fila y la columna (generalmente en ese orden exacto) donde se encuentra el elemento.

Y acá está el problema, cuando accedemos a un elemento de una matriz lo hacemos mediante dos coordenadas (fila, columna) por lo que debemos tener en cuenta que las filas nos mueven por la matriz verticalmente y que las columnas nos mueven por la matriz horizontalmente. Contrario a como nos movemos en un sistema coordenado donde por lo general la primer componente nos mueve horizontalmente (el eje de las x), y la segunda verticalmente (el eje de las y).

Tener esto en cuenta nos va a ahora MUCHOS dolores de cabeza en un futuro.

¿Cómo crear una matriz?

Numpy nos proporciona varios métodos para crear matrices:

A partir de una lista
Para crear una matriz a partir de una lista tenemos el método numpy.array() que recibe como parametro una lista (que puede ser una lista de lista en el caso de las matrices)

Código: python
>>> import numpy as np
>>> x = np.array([1, 2, 3])  # Vector
>>> x
array([1, 2, 3])
>>> X = np.array([[1, 2, 3], [4, 5, 6]])  # Matriz 2x3
>>> X
array([[1, 2, 3],
       [4, 5, 6]])


Métodos predefinidos
Numpy también nos proporciona unos métodos predefinidos para crear matrices, por ejemplo la matriz identidad, matrices de unos o de ceros:

Código: python
>>> import numpy as np
>>> identidad = np.identity(3)
>>> identidad
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> ceros = np.zeros((3, 3))
>>> ceros
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
>>> unos = np.ones((3, 3))
>>> unos
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])


El método numpy.identity(n) genera la matriz identidad de dimensiones nxn
Los métodos numpy.zeros(tamaño), numpy.ones(tamaño) crean matrices de ceros y unos respectivamente.

¿Operaciones con matrices?
Una de las cosas que más conmociona a las personas cuando se enfrentan por primer vez con numpy es que éste usa los mismos operadores de Python.
Así que veamos un repaso de éstos operadores:


Operador   Uso   Operación
+   a + b   Suma
-   a - b   Resta
*   a * b   Multiplicación
/   a / b   División
//   a // b   División entera
**   a ** b   Potencia
%   a % b   Módulo
<   a < b   Menor que
<=   a <= b   Menor o igual que
==   a == b   Igualdad
>   a > b   Mayor que
>=   a >= b   Mayor o igual que
!=   a != b   Distinto

Éstos son sólo algunos de los operadores de Python que además podemos usar con objetos de numpy. Esto se logra sobreescribiendo los operadores (algo de lo que hablaremos luego en una entrada aparte).

Hay dos cosas que debemos tener en cuenta:


  • Al menos uno de los operandos debe ser un objeto numpy: Así es, no es necesario que los dos operandos sean objetos de numpy, basta con se sólo a, o sólo b sean objetos de numpy para que se pueda realizar la operación sin errores.
  • Éstas operaciones son elemento a elemento: Acá tenemos dos casos:

    • Tanto a como b son objetos de numpy: En este caso, las operaciones se realizan elemento a elemento, es decir, el primero de a con el primero de b, el segundo de a con el segundo de b... por lo que debemos tener en cuenta que tanto a, como b deben tener las mismas dimensiones.
    • Hay un objeto de numpy y un número: En este caso, se aplica la operación deseada a toda la matriz con el número indicado.
      El resultado va a ser una nueva matriz con el resultado de aplicar la operación indicada.


Si queremos la multiplicación habitual de matrices, a partir de Python 3.5 se introdujo el operador @ (PEP 465) que nos permite justo eso, realizar la multiplicación "real" entre matrices.

Un pequeño ejemplo
Código: python
>>> import numpy as np
>>> a = np.ones((3, 3))  # Crea una matriz de unos 3x3
>>> a
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> a = a * 2  # Multiplica cada componente de a por 2
>>> a
array([[ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.]])
>>> b = np.ones((3, 3)) ** 5  # Eleva cada componente a la quintapotencia
>>> b
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> b = b + 5  # Suma a cada componente de b 5
>>> b
array([[ 6.,  6.,  6.],
       [ 6.,  6.,  6.],
       [ 6.,  6.,  6.]])
>>> a @ b  # Multiplicación matricial entre a y b
array([[ 36.,  36.,  36.],
       [ 36.,  36.,  36.],
       [ 36.,  36.,  36.]])
>>> b > 5  # Componentes mayores que 5
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]], dtype=bool)
>>> b < 3  # Componentes menores que 3
array([[False, False, False],
       [False, False, False],
       [False, False, False]], dtype=bool)
>>>


Indexing y slicing
Al igual que las lista en Python, los objetos de numpy también soportan tanto el indexing, como el slicing.

Indexing
El indexing nos permite acceder a un elemento indicando sus coordenadas.

Si estamos trabajando con un vector (matriz con solo una columna o solo una fila) para acceder a un elemento sólo necesitamos su índice:
Código: python
>>> import numpy as np
>>> x = np.array([1, 2, 3])
>>> x[0]
1
>>> x[1]
2
>>> x[-1]
3
>>>


El indexing para vectores funciona igual que para listas.

Si estamos trabajando con matrices, para acceder a un elemento, necesitamos dos coordenadas (a veces tres) la fila y la columna donde se encuentra el elemento que necesitamos:

Código: python
>>> import numpy as np
>>> a = np.identity(3)
>>> a
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> a[1, 1]
1.0
>>> a[1,-1]
0.0
>>> a[0,0]
1.0


Los índices negativos seleccionan un elemento comenzando desde el final del array, siendo -1 la posición del último elemento, -2 la del penultimo y así...

Es por eso que en el caso del array, x[-1] devuelve 3 ya que este es el último elemento del array; y en el caso de la matriz, a[1, -1] devuelve 0.0 ya que éste es el elemento que se encuentra en la primer fila y en la última columna.

Slicing
El slicing es una variación del indexing en la que en lugar de obtener un solo elemento, nos permite obtener un rango de elementos.

La sintaxis es igual a la del slicing para listas:
Código: python

>>> import numpy as np
>>> x = np.arange(10)
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x[:5]
array([0, 1, 2, 3, 4])
>>> x[5:]
array([5, 6, 7, 8, 9])
>>> x[-1:0:-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1])
>>> x[-1:0:-2]
array([9, 7, 5, 3, 1])


Se indica el rango que se quiere obtener usando a:b (dos puntos) donde tanto a como b son enteros. a indica el inicio, si se omite, se toma 0 y b indica el final, si se omite, se toma -1.

Hay que tener en cuenta que el rango que devuelve el slicing va desde a hasta  b - 1.

Además, hay un tercer parámetro opcional, también separado por : (dos puntos) que indica el paso (o salto).

Para las matrices la sintaxis es la misma, solo que debemos hacer el slicing tanto para las filas como para las columnas, separadas por una , (coma):


Código: python
>>> import numpy as np
>>> a = np.identity(3)
>>> a
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> a[1:, 1:]
array([[ 1.,  0.],
       [ 0.,  1.]])
>>> a[:1, :1]
array([[ 1.]])
>>> a[:2, :2]
array([[ 1.,  0.],
       [ 0.,  1.]])
>>>


Estos son solo ejemplos de indexing y slicing básicos, para ver operaciones más avanzadas y aclarar posibles dudas, referirse a la documentación oficial


Modificar los valores de una matriz
Para modificar los valores de una matriz podemos hacerlo de a un solo elemento usando indexing, o de a varios elementos usando slicing.

Eso sí, siempre debemos tener en cuenta el tamaño de los datos que queremos escribir coincidan con el tamaño seleccionado en la matriz de destino.

Código: python
>>> import numpy as np
>>> a = np.identity(3)
>>> a
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> a[1, 1] = 10
>>> a
array([[  1.,   0.,   0.],
       [  0.,  10.,   0.],
       [  0.,   0.,   1.]])
>>> a[1:, 1:] = np.ones((3, 3))
Traceback (most recent call last):
  File "", line 1, in
ValueError: could not broadcast input array from shape (3,3) into shape (2,2)
>>> a[1:, 1:] = np.ones((2, 2))
>>> a
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  1.],
       [ 0.,  1.,  1.]])


En éste caso, en la línea 12 ocurre un error porque estamos intentando asignar una matriz 3x3 a una zona de la matriz a de tamaño 2x2.

Uso de máscaras
Otra forma de modificar los elementos de una matriz es mediante el uso de máscaras.

Una máscara es una matriz booleana (de falsos y verdaderos) donde las componentes verdaderas indican los elementos que van a ser modificados.

La máscara se pasa como si ésta fuera un índice:

Código: python
>>> x = np.arange(25)  # Crea un vector
>>> X = x.reshape(5, 5)  # Convierte el vector a matriz de 5x5
>>> X
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
>>> mascara = (X % 2 == 0)  # Genera máscara posición de los elementos pares
>>> mascara
array([[ True, False,  True, False,  True],
       [False,  True, False,  True, False],
       [ True, False,  True, False,  True],
       [False,  True, False,  True, False],
       [ True, False,  True, False,  True]], dtype=bool)
>>> X[mascara] = 0  # Cambia todos los pares por cero
>>> X
array([[ 0,  1,  0,  3,  0],
       [ 5,  0,  7,  0,  9],
       [ 0, 11,  0, 13,  0],
       [15,  0, 17,  0, 19],
       [ 0, 21,  0, 23,  0]])


¿Paso de matrices como valor o referencia?
Otro de los inconvenientes (más que inconveniente es un dolor de trasero) en especial para quien apenas está comenzando con Python e incluso para los distraidos es que, a veces, despues de llamar a una función y de pasarle a esta una matriz sobre la que realizaremos una operación suceden cosas extrañas. (brujería podrian pensar algunos) y el culpable está en como Python pasa los parametros por valor y por referencia.

Parametros por valor
Decimos que un parametro se pasa por valor cuando a una función se le pasa el valor (valga la redundancia) de una variable, o en otras palabras, una copia de una variable. Por lo tanto los cambios que se hagan sobre este parametro se hacen sobre la copia.

Parametros por referencia
Decimos que un parametro se pasa por referencia cuando a una función se le pasa la dirección en memoria de una variable en lugar de una copia de la variable. Por lo tanto los cambios que se hagan sobre este parametro, se hacen en la dirección de memoria a la que apunta y por lo tanto se hacen sobre la variable original.


Teniendo ésto en cuenta, ahora debemos comprender como toma Python los parametros por valor y por referencia.

Parametros por valor y referencia en Python
A Python no podemos especificarle explícitamente que valores queremos pasar por valor y cuales por referencia, en su lugar debemos recordar:

Los objetos mutables se pasan por referencia.
Los objetos inmutables se pasan por valor.

Los objetos mutables son aquellos que pueden cambiar su valor.
Los objetos inmutables son aquellos que no pueden cambiar su valor.

Aunque ésta definición no está completa (no es el objetivo de la entrada) es suficiente para comprender la "magía negra" que está por ocurrir. (Eso sí, teniendo en cuenta que las matrices de numpy son objetos mutables).

Código: python
import numpy as np

def funcion(matriz):
    matriz[1, 1] = 10

mi_matriz = np.ones((3, 3))
print("Antes de llamar la función:")
print(mi_matriz)
funcion(mi_matriz)
print("Después de llamar la función:")
print(mi_matriz)


CitarAntes de llamar la función:
[[ 1.  1.  1.]
[ 1.  1.  1.]
[ 1.  1.  1.]]
Después de llamar la función:
[[  1.   1.   1.]
[  1.  10.   1.]
[  1.   1.   1.]]

Ésto significa que los cambios que realizamos a la matriz (incluso con distinto nombre) dentro de la función son visibles (afectan a la variable fuera de la función) fuera de la función.

Si no queremos que esto suceda debemos crear explícitamente una copia de la matriz y pasar a la función ésta copia en lugar de la matriz original.

Para copiar una matriz, podemos hacer uso del método copy() que tienen los objetos de numpy:

Código: python
import numpy as np

def funcion(matriz):
    matriz[1, 1] = 10

mi_matriz = np.ones((3, 3))
print("Antes de llamar la función:")
print(mi_matriz)
funcion(mi_matriz.copy())
print("Después de llamar la función:")
print(mi_matriz)


CitarAntes de llamar la función:
[[ 1.  1.  1.]
[ 1.  1.  1.]
[ 1.  1.  1.]]
Después de llamar la función:
[[  1.   1.   1.]
[  1.   1.   1.]
[  1.   1.   1.]]

Ésta vez pasamos una copia de la matriz y no la matriz como tal, por lo que aunque se sigue pasando la copia de la matriz por referencia se está modificando la copia pero no la original.

Algunos métodos interesantes de numpy
numpy.amin(matriz): Devuelve el menor elemento de la matriz.
numpy.amax(matriz): Devuelve el mayor elemento de la matriz.
numpy.arange(matriz): Similar a range()
numpy.sum(matriz): Suma todos los elementos de la matriz.

Algunos métodos de las matrices (objetos ndarray)
matriz.ravel(): Devuelve un vector con los elementos de la matriz.
matriz.copy(): Copia la matriz.
matriz.reshape(tamaño): Cambia el tamaño de la matriz.

Referirse a la documentación para una lista completa de los métodos y propiedades: ir

Saludos!
Once.

Fuente: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#60
Fuente: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Una introducción a OpenCV y Numpy


En esta segunda entrega sobre visión artificial con Python trataremos una introducción a OpenCV y Numpy. Crearemos imágenes desde cero y abriremos imágenes ya existentes.

¿Qué es OpenCV?

OpenCV (Open source Computer Vision) es un libreria bajo la licencia BSD diseñada y optimizada para hacer visión por computador y aprendizaje automático. Está disponible para los lenguajes C, C++, Java y Python. Además puede correr sobre Windows, Linux, MAC, IOS y Android.

La documentación de esta libreria se puede consultar (y descargar) desde acá.

¿Qué es NumPy?

Numpy es una libreria optimizada para hacer computación científica con Python, especialmente algebra lineal (matricial) que es lo que nos interesará para hacer visión por computador.

¿Es necesario usar estas librerias?

No, la respuesta es un rotundo no. La visión por computar es básicamente operaciones matriciales, operaciones que podemos implementar no solo en Python puro y duro, sino que en casi cualqueir otro lenguaje.

La ventaja, entonces, está en que estas librerias fueron creadas y son mantenidas por verdaderos expertos en el tema (científicos de la computación, matemáticos, etc) lo que da como resultado algoritmos realmente optimizados.

Configurando el entorno

Durante esta serie de entregas necesitaremos básicamente tres librerias:

OpenCV: Para hacer visión por computador.
Numpy: Para hacer operaciones matriciales.
Matplotlib: Para graficar (especialmente histogramas)

Todas estas librerias están disponibles para descargar usando pip.

Instalando los paquetes necesarios


Código: bash
# pip install python-opencv

# pip install numpy

# pip install matplotlib


¿Estamos listos? Entonces... comencemos

Como vimos en la entrega anterior, una imagen no es más que un sistema de matrices donde cada entrada representa un nivel de gris para cada píxel.

Creando nuestra primer imagen

Como ya hemos mencionado antes una imagen no es más que una matriz de valores numéricos. Demostremos esto con un simple ejemplo.

Código: python
import numpy as np
import cv2

# Creamos una matriz de unos de 100 filas y 100 columnas
imagen = np.ones((100, 100, 3), np.uint8)
# Mostramos la imagen
cv2.imshow("Mi primer imagen", imagen)
# Guardamos la imagen donde esta el script
cv2.imwrite("Mi primer imagen.png", imagen)
cv2.waitKey()  # Pausa la ejecuación hasta que se presione una tecla
cv2.destroyAllWindows()  # Cierra todas las ventanas abiertas


Una vez ejecutamos el script anterior tenemos que el resultado es el siguiente:


Imagen creada con Numpy

En las primeras dos líneas importamos numpy (y le asignamos el alias np, para no tener que estar escribiendo numpy todo el rato) y OpenCV (cv2).

Luego creamos una matriz de unos con la función ones de numpy. Si imprimimos imagen (print(numpy)) veremos que, efectivamente, es una matriz llena de unos.

Citarnumpy.ones(shape, dtype=None): Crea un array de dimensión sahape donde cada entrada es del tipo dtype.

shape: es la forma que tendrá el array, si solo tiene un elemento será una lista, dos elementos (n, m) representan una matriz con n filas y m columnas. Y con tres elementos  (n, m, z) n filas, m columnas y z representa la cantidad de matrices o canales que tendrá el array.

En este ejemplo creamos una matriz llena de unos con 100 filas, 100 columnas y un solo canal donde todas las entradas son números enteros de 8 bits.

Citarcv2.imshow(nombre, img): Muestra la imagen img. nombre es una cadena que representará la ventana donde se muestra la imagen. img debe ser una matriz.

cv2.imwrite(nombre, img): Guarda en el disco duro la matriz img como una imagen con el nombre nombre

Entonces... ¿cómo se representa una imagen a color?.

En el ejemplo anterior creamos una imagen de un solo canal (una sola matriz) lo que significa que solo podemos representar un color. Para este caso el gris o escala de grises.

Si queremos representar una imagen a color, vamos a necesitar más canales (ya no solo una matriz) dependiendo del modelo de color con el que queremos trabajar.

Código: python
import numpy as np
import cv2

# Creamos la matriz de uno 100 filas
# 100 columnas y 3 canales
imagen = np.ones((100, 100, 3), np.uint8)
# agregamos color a la imagen
# A todas las columas pero primeras 25 filas
# Asigna el valor (255, 0, 0)
imagen[:, 0:25] = (255, 0, 0)
# A todas las columnas pero desde la fila
# 25 hasta la 50 asigna el valor (0, 255, 0)
imagen[:, 25:50] = (0, 255, 0)
# A todas las columnas pero desde la fila
# 50 hasta la 75 asigna el valor (0, 0, 255)
imagen[:, 50:75] = (0, 0, 255)

# Guardamos la imagen en el disco duro
cv2.imwrite("imagen_color.png", imagen)
# Mostramos la imagen
cv2.imshow("imagen", imagen)
# Esperamos que se presione una tecla
cv2.waitKey()
# Cerramos todas las ventanas
cv2.destroyAllWindows()


El resultado es el siguiente:



Imagen a color generada con Numpy.

Y ahora sí obtenemos una imagen a color usando solamente numpy.

El cambio en este código está en la forma del array shape (100, 100, 3) donde el tres representa la cantidad de canales de la imagen, como trabajamos con el modelo RGB necesitamos tres canales, uno para el rojo, otro para el verde y un último para el azul.

OpenCV por defecto trabajo con el modelo BGR que es el mismo modelo RGB, pero con los valores invertidos.

Otra cosa nueva es la forma de asignar los colores a la imagen, esta forma se llama indexing y es muy parecido al slicing solo que para arrays multidimencionales. El formato es el siguiente:

Citarmatriz[a:b, c:d] = tupla

Donde a representa la primer fila a seleccionar y b la última fila a seleccionar. c representa la primer columa a seleccionar y d la última columna a seleccionar.

Si no se especifica a o c se selecciona desde el primer elemento.
Si no se especifica b o d se selecciona hasta el último elemento.

tupla debe ser una tupla o lista de elemetos a asignar a la matriz en la posicion señanala. Debe tener la misma longitud que canales la imagen. El primer elemento es asignado a la primer matriz y así sucesivamente hasta el último valor que es asignado a la última matriz.

Leer una imagen con OpenCV

OpenCV cuenta con una función que nos permite leer una imagen desde el disco y nos devuelve un array de numpy.

Citarcv2.imread(name, flag): Lee la imagen name y devuelve una matriz.

Si el parámetro flag es positivo OpenCV interpretará la imagen como si tuviera tres canales y por lo tanto devolvera una matriz con tres canales.

Si el parámetro es cero  OpenCV leerá la imagen en esacala de grises y por lo tanto devolverá una matriz de un solo canal.

Si el parámetro es negativo OpenCV leerá la imagen tal cual como es y los canales de la matriz resultante dependen de la imagen a leer.


Obteniendo el tamaño de una imagen


Luego de abrir una imagen con OpenCV, el resultado es un array de numpy, por lo que tenemos todas las ventajas que nos brinda los objetos de numpy, uno de ellos es la propiedad shape.

La propiedad shape devuelve una lista que indica la cantidad de filas, columnas y canales que tiene un array respectivamente. Si la lista solo contiene dos elementos, indica que el array solo tiene un solo canal.

Su uso es muy simple:
Código: python

import numpy as np
import cv2

#  Leemos la imagen
img = cv2.imread("imagen.jpg")
#  Imprimimos el tamanio
print(img.shape)


Comprendiendo el flag de la función cv2.imread()

Haciendo un par de cambios al ejemplo anterior, podemos comprender mejor el significado del falg en la función cv2.imread()
Código: python

import numpy as np
import cv2

img = cv2.imread("logo.png")
print("Sin flag:", img.shape)

img = cv2.imread("logo.png", -1)
print("flag negativo:", img.shape)

img = cv2.imread("logo.png", 0)
print("flag cero:", img.shape)

img = cv2.imread("logo.png", 1)
print("flag positivo:", img.shape)


El resultado será algo así:

CitarSin flag: (99, 82, 3)
flag negativo: (99, 82, 4)
flag cero: (99, 82)
flag positivo: (99, 82, 3)

En todos los casos tenemos una matriz de 99 filas y 82 columnas, pero con distintos canales. Analicemos el significado.

flag negativo: La imagen se interpreta tal cual como es, por lo que tenemos tres canales para el color y uno más para la transparencia.
flag cero: La imagen se interpreta a escala de grises y por lo tanto sólo se necesita un canal.
flag positivo: La imagen se interpreta como si sólo tuviera tres canales (elimina la transparencia).


Diferencias según el flag.

Saludos.
Once.