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 回答