张春成
V2
2021/06/28阅读:78主题:默认主题
图解审美(三)
图解审美(三)
本文将对《图解审美(二)》中的线性变换问题进行图解说明。 并且还将提供一种基于非线性映射的改进方法,用于提升颜色分布变换的效果。
图解线性变换
线性变换是很大的课题。 本文专注于其进行空间分布标准化及映射特性,如下图所示
-
图解线性变换
从图中可以看到,此时的线性变换代表多维变量联合分布的标准化及映射。 可以用于进行联合分布之间的映射计算。
计算实例
我们已经在上文中,利用线性变换的原理进行了计算,现将结果简要介绍如下
-
源图像颜色分布
-
目标图像颜色分布
-
映射后的图像颜色分布
映射后的源图像之所以与目标图像比较相似,其原因就在于颜色空间分布的近似。
非线性改进
然而,从上例也可以看到,线性映射只能解决“线性”的问题。 对于非线性分布的情况较为无力,因此我们可以近似采用非线性方法进行分布逼近。 如下图所示
-
新目标图像
-
非线性映射后的目标图像
是不是更像了?
我们发现,非线性映射往往比线性映射效果更逼真。 但其适用是基于更加复杂的计算过程。
非线性映射的实现
在此,我们给出一种简单的非线性映射代码,希望能够为大家可能的计算工作提供帮助。
计算过程使用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 = ((1, 1), (1, 2), (2, 1))
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((3, 3)) / (3 * 3)
for j in [1, 2]:
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)
参考资料
GITHUB仓库: https://github.com/listenzcc/JupyterScripts.git
作者介绍
张春成
V2