Cálculo del umbral

Como se ha visto en el código, las fotos al Sol hay que recortarlas para poder incluirlas en una composición. Para ello hay que aplicarles un umbral que defina el valor, a partir del cual, todos los píxeles pasan a ser de color blanco (valor = 255).

La calidad y cantidad de información de las fotos, van a depender de la hora en que se tomaron y de la nubosidad que había en ese momento. Es por ello que no se puede aplicar el mismo umbral a todas las fotos.

En la siguiente imagen están comparadas distintas fotos, de mayor a menor tamaño, indicando la suma total de los valores contenidos en todos sus píxeles (cada píxel, de la foto convertida en escala de grises, puede tener un valor entre 0 y 255 en 3280x2464 píxeles), mostrando el resultado de aplicar distintos valores del umbral:

  1. umbral máximo de 240 (el máximo valor de los píxeles es de 255)
  2. umbral mínimo de 100
  3. umbral aplicado según media ponderada

 

 

Como se puede observar, al aplicar el valor ponderado, todos los soles se igualan en tamaño (las imágenes de la última columna). La foto de la última fila, por ejemplo, no obtiene ningún resultado al aplicarle un umbral de 240. Esto quiere decir que no hay ningún píxel mayor o igual a ese valor. El factor se ha calculado estudiando el número de píxeles contenido en las fotos de ejemplo de mayor y menor tamaño, y ponderando la media al valor de 140 (100+140=240). El estudio me dió un factor de 0.15 aproximadamente. De esta forma, al aplicar este factor, las fotos cuya suma de los valores contenidos en sus píxeles es más alta (un sol con más píxeles cercanos al blanco) se acercarían al umbral de 240 y las de menor valor (un sol con muy poca intensidad) al valor de 100.

Así quedaría el código, incluyendo el factor de obtención del umbral:

# limpia las fotos con sol para recortar su imagen
def recortar_imagen(img_bruto):
    # leemos la imagen con cv2
    imagen = cv2.imread(img_bruto)

    # modificamos el umbral para recortar el sol dependiendo del num de pixeles
    sought = [120, 120, 120]
    npixeles = np.count_nonzero(np.all(imagen > sought, axis=2))
    umbral = 100 + (npixeles * 0.15)
    if umbral > 240:
        umbral = 240

    # cambiamos a escala de grises
    imagen_gris = cv2.cvtColor(imagen, cv2.COLOR_BGR2GRAY)

    # aplicamos el umbral en la foto en escala de grises
    ret, imagen_recortada =\
        cv2.threshold(imagen_gris, umbral, 255, cv2.THRESH_BINARY)

    # devolvemos la foto abierta con cv2
    return(imagen_recortada)