2011-09-25 22 views
20

Para una clase de procesamiento de imágenes, estoy haciendo operaciones de puntos en imágenes monocromáticas. Los píxeles son uint8 [0,255].numpy uint8 solución de ajuste de píxeles

numpy uint8 se ajustará. Por ejemplo, 235 + 30 = 9. Necesito los píxeles para saturar (max = 255) o truncar (min = 0) en lugar de envolver.

Mi solución utiliza píxeles int32 para el punto matemático y luego se convierte en uint8 para guardar la imagen.

¿Es esta la mejor manera? ¿O hay una manera más rápida? imagen

#!/usr/bin/python 

import sys 
import numpy as np 
import Image 

def to_uint8(data) : 
    # maximum pixel 
    latch = np.zeros_like(data) 
    latch[:] = 255 
    # minimum pixel 
    zeros = np.zeros_like(data) 

    # unrolled to illustrate steps 
    d = np.maximum(zeros, data) 
    d = np.minimum(latch, d) 

    # cast to uint8 
    return np.asarray(d, dtype="uint8") 

infilename=sys.argv[1] 
img = Image.open(infilename) 
data32 = np.asarray(img, dtype="int32") 
data32 += 30 
data_u8 = to_uint8(data32) 
outimg = Image.fromarray(data_u8, "L") 
outimg.save("out.png") 

Entrada: Imagen
Riemann

Salida:
Output

Respuesta

27

Uso numpy.clip:

import numpy as np 
np.clip(data32, 0, 255, out=data32) 
data_u8 = data32.astype('uint8') 

Tenga en cuenta que también se puede iluminar las imágenes sin numpy esta manera:

Import ImageEnhance 
enhancer=ImageEnhance.Brightness(img) 
outimg=enhancer.enhance(1.2) 
outimg.save('out.png') 
+0

np.clip() es exactamente lo que yo He estado necesitando ¡Gracias! También leeré en ImageEnhance. La tarea se trataba de hacer operaciones puntuales, pero será bueno aprender de otras maneras. –

1

Básicamente, todo se reduce a la comprobación antes de agregar. Por ejemplo, se podría definir una función como esta:

def clip_add(arr, amt): 
    if amt > 0: 
     cutoff = 255 - amt 
     arr[arr > cutoff] = 255 
     arr[arr <= cutoff] += amt 
    else: 
     cutoff = -amt 
     arr[arr < cutoff] = 0 
     arr[arr >= cutoff] += amt 
3

Puede utilizar OpenCV add o subtract funciones (explicación adicional here).

>>> import numpy as np 
>>> import cv2 
>>> arr = np.array([100, 250, 255], dtype=np.uint8) 
>>> arr 
Out[1]: array([100, 250, 255], dtype=uint8) 
>>> cv2.add(arr, 10, arr) # Inplace 
Out[2]: array([110, 255, 255], dtype=uint8) # Saturated! 
>>> cv2.subtract(arr, 150, arr) 
Out[3]: array([ 0, 105, 105], dtype=uint8) # Truncated! 

Por desgracia, es imposible utilizar los índices de matriz de salida, por lo que los cálculos in-situ para cada canal de imagen se pueden realizar en este, menos eficiente, así:

arr[..., channel] = cv2.add(arr[..., channel], 40) 
Cuestiones relacionadas