web-dev-qa-db-ja.com

numpyを使用して画像をパターンでマスクしますか?

Numpyを使用してピクセル配列を作成しています。 800x600画像は、uint8、800x600x3の3次元配列です。固定パターンの同様の配列もあります(チェッカーボード、 ここ を参照)。別の配列、800x600のマスク値があります。マスクがゼロの場合、パターンピクセルをイメージピクセルにコピーしたいと思います。マスクがゼロでない場合は、画像のピクセルをそのままにしておきます。

>>> image.shape
(800, 600, 3)
>>> chex.shape
(800, 600, 3)
>>> mask.shape
(800, 600)

これはうまくいくはずだと感じます:

image[mask == 0,...] = chex

しかし、「ValueError:配列は正しい形状にブロードキャストできません」と表示されます。

Chexピクセルをマスクがゼロの画像ピクセルにコピーするには何を使用しますか?

21
Ned Batchelder
idx=(mask==0)
image[idx]=chex[idx]

imageの形状(800,600,3)に対して、idxの形状(800,600)であることに注意してください。 ルール インデックスの状態

選択タプルがnより小さい場合、必要な数の:オブジェクトが選択タプルのendに追加され、変更された選択タプルが長さN。

したがって、インデックス配列には、独自のブロードキャスト機能があります。 idxの形状が(800,600、:)に昇格します

23
unutbu

@unutbuanswerを使用して例を説明したいと思います。このシナリオでは、回転する猫の画像があります。この回転により、特に黒以外の背景に貼り付けると、見苦しい黒のエッジが発生します。

import matplotlib.pyplot as plt
from scipy.ndimage import rotate


cat = plt.imread('cat.jpeg')
bg = plt.imread('background.jpeg')


rotcat = rotate(cat, angle=8, reshape=True) ## rotating creates some black edges
height, width, _ = rotcat.shape

bgcopy = bg.copy() ## create a copy of the background; paste on copy

x, y = 40, 50 
bgcopy[x:x+height, y:y+width] = rotcat
plt.imsave('cat-on-bg-mask.jpg', bgcopy)

bad pasting

だから、私はマスクの領域を見つけて、それらの値を元の背景値に置き換えます

mask_ind = (bgcopy == 0)
bgcopy[mask_ind] = bg[mask_ind]
plt.imsave('cat-on-bg.jpg', bgcopy)

good pasting

また、PIL.ImagePillowライブラリから)には、少ない手順で画像を別の画像に貼り付ける機能があります。

4
Jon

8x6x3、8x6x3、および8x6の配列を使用して、それぞれ画像配列、チェッカー配列、およびマスク配列を表しました。

# first create mini-versions of your arrays:
mask = NP.random.random_integers(0, 1, 48).reshape(8, 6)
img = NP.random.random_integers(3, 9, 8*6*3).reshape(8, 6, 3)
chk = NP.ones((8, 6, 3))

# all the work done in these two lines
mask = mask[:,:,NP.newaxis]
res = NP.where(mask==0, chk, img)
0
doug

1 =「保持するピクセル」、0 =「削除するピクセル」のマスクを作成するのが最も簡単であることがわかりました。

次に、画像にそのマスクを掛けて、不要なピクセルを削除しました。ポートレートのフレーム(外側)のみを保持する例:

from scipy.misc import imread
import matplotlib.pyplot as plt
import numpy as np

im = imread('portrait.jpg', mode='L') # read in image
plt.imshow(im) # show the original image

enter image description here

mask = np.ones(im.shape) # create a mask with the image's shape
bw = 0.1 # identify border width and height as fraction of image size
bx = int(im.shape[1] * bw) # get the x dimension border width
by = int(im.shape[0] * bw) # get the y dimension border height
mask[bx:-bx,by:-by] = 0 # create a mask with 1 for border and 0 for inside

masked = im * mask # multiply `im` by the mask to zero out non-border pixels
plt.imshow(masked) # show the result of the masking operation

enter image description here

0
duhaime

試してください:

image[mask[:] == 0,...] = chex[mask[:] == 0,...]
0
ezod