Loading...
墨滴

张春成

2021/06/27  阅读:39  主题:默认主题

图解审美(三)

图解审美(三)

本文将对《图解审美(二)》中的线性变换问题进行图解说明。 并且还将提供一种基于非线性映射的改进方法,用于提升颜色分布变换的效果。


图解线性变换

线性变换是很大的课题。 本文专注于其进行空间分布标准化及映射特性,如下图所示

  • 图解线性变换 图解线性变换.png

从图中可以看到,此时的线性变换代表多维变量联合分布的标准化及映射。 可以用于进行联合分布之间的映射计算。

计算实例

我们已经在上文中,利用线性变换的原理进行了计算,现将结果简要介绍如下

  • 源图像颜色分布 3p1.png

  • 目标图像颜色分布 3p2.png

  • 映射后的图像颜色分布 3p3.png

映射后的源图像之所以与目标图像比较相似,其原因就在于颜色空间分布的近似。

非线性改进

然而,从上例也可以看到,线性映射只能解决“线性”的问题。 对于非线性分布的情况较为无力,因此我们可以近似采用非线性方法进行分布逼近。 如下图所示

  • 新目标图像 3p11.png

  • 非线性映射后的目标图像 3p22.png

是不是更像了?

我们发现,非线性映射往往比线性映射效果更逼真。 但其适用是基于更加复杂的计算过程。

非线性映射的实现

在此,我们给出一种简单的非线性映射代码,希望能够为大家可能的计算工作提供帮助。

计算过程使用python代码,可以参考我的GITHUB仓库[1]。 代码如下

  • 自定义工具函数
def plot_hsv(hsv):
    ''' Build Img by [hsv] matrix,
    and Plot the ColorSpace.
    '''

    rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
    im = Image.fromarray(rgb)
    color_space(im)
    return im

def color_space(im):
    ''' Draw Color Space of Image [im] '''
    mk_matrix(im)

    v_rgb = ravel(im.matrix['RGB'])
    df = pd.DataFrame(ravel(im.matrix['RGB']), columns=['R''G''B'])
    df[['H''S''V']] = ravel(im.matrix['HSV'])
    df['color'] = [convert(e) for e in v_rgb]

    subplot_titles = ('HS''SV''HV')
    subplot_pos = ((11), (12), (21))
    fig = make_subplots(rows=2, cols=2, subplot_titles=subplot_titles)

    for pos, title in zip(subplot_pos, subplot_titles):
        x, y = title
        row, col = pos

        _fig = px.scatter(df, x=x, y=y, title=title)
        _fig.data[0]['marker']['color'] = df['color']

        kwargs = dict(
            row=row,
            col=col
        )

        fig.add_trace(
            _fig.data[0],
            **kwargs
        )

        fig.update_xaxes(title_text=x, **kwargs)
        fig.update_yaxes(title_text=y, **kwargs)

    fig1 = px.imshow(im)
    fig.add_trace(
        fig1.data[0],
        row=2, col=2
    )

    fig.update_layout(dict(
        height=800,
        width=900,
        title=url
    ))
    fig.show()
  • 非线性映射方法
# Get Target Distribution
hsvt = imt.matrix['HSV'].copy()[::5, ::5, :]
hsvt_ravel = ravel(hsvt, num=2000)
hsvt_ravel.shape

# Get Source Distribution
hsv = im.matrix['HSV'].copy()[::2, ::2, :]
hsv_ravel = ravel(hsv, full=True)
hsv_ravel.shape

# Match using Nearest Matching
dist = []
for j in tqdm(range(len(hsvt_ravel))):
    dist.append(np.linalg.norm(hsv_ravel - hsvt_ravel[j], axis=1))

dist = np.array(dist)
dist.shape

idxs = np.argmax(dist, axis=0)
idxs.shape

# Convert the HSV using the Nearest Matching Method
new_hsv = hsv_ravel.copy()
for j in tqdm(range(len(idxs))):
    new_hsv[j] = hsvt_ravel[idxs[j]]

new_hsv_2d = new_hsv.reshape(hsv.shape)

h = np.ones((33)) / (3 * 3)
for j in [12]:
    new_hsv_2d[:, :, j] = convolve2d(new_hsv_2d[:, :, j], h, mode='same')

new_hsv_2d.shape

# Plot the Converted Img
color_space(im)
new_im = plot_hsv(new_hsv_2d)
color_space(imt)

参考资料

[1]

GITHUB仓库: https://github.com/listenzcc/JupyterScripts.git

张春成

2021/06/27  阅读:39  主题:默认主题

作者介绍

张春成