1

画像の色を事前定義された範囲にスケーリングしようとしています。パレットの色の範囲からの最小二乗誤差に基づいて、色が出力ピクセルに割り当てられます。

Python ループでコードを書きましたが、これを行うためのより良いベクトル化された方法はありますか?

import numpy as np
import skimage.io as io

palette = [
            [180, 0 , 0],
            [255, 150, 0],
            [255, 200, 0],
            [0, 128, 0]
        ]

IMG = io.imread('lena.jpg')[:,:,:3]
DIM = IMG.shape
IOUT = np.empty(DIM)

for x in range(DIM[0]):
    for y in range(DIM[1]):
        P = ((np.array(palette)-IMG[x,y,:])**2).sum(axis=1).argmin()
        IOUT[x,y,:] = palette[P]

numpy 操作自体を使用してループを回避および解決できますか?

4

1 に答える 1

0

すべてのピクセルをループするのではなく、すべての色をループします。

import pylab as pl

palette = pl.array([[180, 0, 0], [255, 150, 0], [255, 200, 0], [0, 128, 0]])

img = pl.imread('lena.jpg')[:, :, :3].astype('float')
R, G, B = img[:, :, 0].copy(), img[:, :, 1].copy(), img[:, :, 2].copy()
dist = pl.inf * R

for i in range(len(palette)):
    new_dist = pl.square(img[:, :, 0] - palette[i, 0]) \
             + pl.square(img[:, :, 1] - palette[i, 1]) \
             + pl.square(img[:, :, 2] - palette[i, 2])
    R[new_dist < dist] = palette[i, 0]
    G[new_dist < dist] = palette[i, 1]
    B[new_dist < dist] = palette[i, 2]
    dist = pl.minimum(dist, new_dist)

pl.clf()
pl.subplot(1, 2, 1)
pl.imshow(img.astype('uint8'))
pl.subplot(1, 2, 2)
pl.imshow(pl.dstack((R, G, B)))

編集:ループレスの代替。;)

import pylab as pl

palette = pl.array([[180, 0 , 0], [255, 150, 0], [255, 200, 0], [0, 128, 0]])

img = pl.imread('lena.jpg')[:, :, :3]
pl.clf()
pl.subplot(1, 2, 1)
pl.imshow(img)

IMG = img.reshape((512, 512, 3, 1))
PAL = palette.transpose().reshape((1, 1, 3, -1))
idx = pl.argmin(pl.sum((IMG - PAL)**2, axis=2), axis=2)
img = palette[idx, :]
pl.subplot(1, 2, 2)
pl.imshow(img)
于 2014-08-09T12:43:06.413 に答える