2011-09-25 11 views
20

画像処理クラスでは、モノクロ画像に対して点操作を行っています。ピクセルはuint8 [0,255]です。numpy uint8ピクセルラッピングソリューション

numpy uint8は折り返します。たとえば、235 + 30 = 9です。ラッピングの代わりにピクセルを飽和(max = 255)または切り捨て(min = 0)する必要があります。

私の解決策では、ポイントの計算にint32ピクセルを使用し、次にイメージを保存するためにuint8に変換します。

これが最善の方法ですか?または、より速い方法がありますか?

#!/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") 

入力画像:
Riemann

出力画像:
Output

答えて

27

使用numpy.clip

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

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

np.clip()はまさに私です必要だった。ありがとう! ImageEnhanceも読み上げます。宿題は自分自身で行うのではなく、他のやり方を学ぶことができます。 –

1

基本的には、追加する前にチェックすることになります。たとえば、あなたはこのように関数を定義することができます:

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

あなたがOpenCVのaddsubtract機能(追加説明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! 

残念ながら、それはので、各画像チャネルのためのインプレース計算は、この中で実施することができる、効率が悪く、途中、出力配列のインデックスを使用することは不可能です:

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