24

NumPy と PIL を使用して 2 つの画像を追加しようとしています。MATLABでこれを行う方法は次のようになります。

>> M1 = imread('_1.jpg');
>> M2 = imread('_2.jpg');
>> resM = M1 + M2;
>> imwrite(resM, 'res.jpg');

私はこのようなものを得る:

代替テキスト http://www.deadlink.cc/matlab.jpg

合成プログラムを使用して画像を追加すると、MATLAB の結果は正しいようです。

Python では、次のように同じことをしようとしています。

from PIL import Image
from numpy import *

im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im2 = Image.open('/Users/rem7/Desktop/_2.jpg')

im1arr = asarray(im1)
im2arr = asarray(im2)

addition = im1arr + im2arr

resultImage = Image.fromarray(addition)
resultImage.save('/Users/rem7/Desktop/a.jpg')

そして、私は次のようなものを取得します:

代替テキスト http://www.deadlink.cc/python.jpg

ファンキーな色がたくさん出てくるのはなぜですか? も使用してみImageMath.eval("a+b", a=im1, b=im2)ましたが、RGB unsupported のエラーが出ます。

またImage.blend()、アルファが必要な but があることもわかりました。

私が探しているものを達成するための最良の方法は何ですか?

ソース画像 (画像は削除されています):

代替テキスト http://www.deadlink.cc/_1.jpg 代替テキスト http://www.deadlink.cc/_2.jpg

画像の追加アイコンを使用してソース画像を追加したところ、投稿を編集しているときにソース画像が表示されましたが、何らかの理由で画像が投稿に表示されません。

(画像は削除されました) 2013 05 09

4

5 に答える 5

34

誰もがすでに示唆しているように、あなたが観察している奇妙な色は溢れています. そして、schnaaderの回答のコメントで指摘したように、次のように画像を追加すると、まだオーバーフローします:

addition=(im1arr+im2arr)/2

このオーバーフローの理由は、NumPy 配列 ( im1arr im2arr ) がuint8型 (つまり 8 ビット) であるためです。これは、配列の各要素が 255 までの値しか保持できないことを意味するため、合計が 255 を超えると、0 付近にループバックします。

>>>array([255,10,100],dtype='uint8') +  array([1,10,160],dtype='uint8')
array([ 0, 20,  4], dtype=uint8)

オーバーフローを回避するには、配列に 255 を超える値を含めることができる必要があります。たとえば、配列を float に変換し、ブレンド操作を実行して、結果を uint8 に戻す必要があります。

im1arrF = im1arr.astype('float')
im2arrF = im2arr.astype('float')
additionF = (im1arrF+im2arrF)/2
addition = additionF.astype('uint8')

これを行うべきではありません:

addition = im1arr/2 + im2arr/2

ブレンディング情報を実行する前に、画像のダイナミクスを押しつぶすことにより(画像を効果的に7ビットにします)、情報が失われるためです。

MATLAB 注: MATLAB でこの問題が発生しない理由は、おそらく MATLAB が関数の 1 つでオーバーフローを暗黙的に処理するためです。

于 2009-02-08T17:05:45.870 に答える
20

アルファ値 0.5 で PIL の blend() を使用すると、(im1arr + im2arr)/2 と同等になります。Blend では、画像にアルファ レイヤーが含まれている必要はありません。

これを試して:

from PIL import Image
im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im2 = Image.open('/Users/rem7/Desktop/_2.jpg')
Image.blend(im1,im2,0.5).save('/Users/rem7/Desktop/a.jpg')
于 2009-02-08T03:58:33.760 に答える
2

numpy 配列値をクランプするには:

>>> c = a + b
>>> c[c > 256] = 256
于 2009-02-08T09:54:53.260 に答える
2

投稿したコードは値を合計するだけで、256 より大きい値がオーバーフローしているようです。「(a + b) / 2」または「min(a + b, 256)」のようなものが必要です。後者は、あなたのMatlabの例がそれを行う方法のようです。

于 2009-02-08T01:28:27.573 に答える
0

サンプル画像が表示されないので、少し推測します。

numpy から pil への変換がどのように機能するか正確には思い出せませんが、2 つのケースが考えられます。私はそれが 1 であると 95% 確信していますが、私が間違っている場合に備えて 2 を与えています。1) 1 im1Arr は整数 (ARGB) の MxN 配列であり、コンポーネント b1+b2>255 の場合、im1arr と im2arr を一緒に追加すると、1 つのチャネルから次のチャネルにオーバーフローします。私は、matlab が画像を MxNx3 配列として表していると推測しているため、各カラー チャネルは分離されています。これは、PIL 画像チャネルを分割してから numpy 配列を作成することで解決できます

2) 1 im1Arr はバイトの MxNx3 配列であり、im1arr と im2arr を一緒に追加すると、コンポーネントがラップされます。

また、表示する前に範囲を 0 ~ 255 に戻す必要があります。選択肢は、2 で割る、255/array.max() でスケーリングする、またはクリップすることです。私はmatlabが何をするのか分かりません

于 2009-02-08T01:32:40.043 に答える