本帖最后由 guoxiaomi 于 2019-8-14 02:31 编辑
2019/8/14 更新:
参见此贴https://rpg.blue/thread-478354-1-1.html,已经打包成单exe,无需安装octave即可运行
2018/8/30 更新:
现在支持对素材图片进行划分与合并,附件已更新
2018/8/28 更新:
修正了一个错误,附件已更新
此代码已经上传到GitLab上https://gitlab.com/gxm/rm-palette
脚本范例在此,比上面做了一些细节上的修改:
rm-palette.zip
(88.75 KB, 下载次数: 105)
Octave 下载地址:https://www.gnu.org/software/octave/download.html
先说一下思路:假设现在有1p.png和1p_01.png,两张图,其中2p.png已经画好了,需要根据1p->2p的颜色变化关系,获得2p_01.png这张图。
这里是这样做的:
1. 对 2p.png 这张图进行分区,把位置、颜色相似的像素点分类到一起,使用的方法是K-均值聚类算法
2. 在上一步中,会获得 m 个聚类,其中心分别是 c1 .. cm
3. 对 2p_01.png 这张图中的每一个不透明的像素点进行处理
3.1 首先寻找 c1.. cm 中离这个像素点最近的聚类中心 ci
3.2 在第 i 个聚类中寻找离这个像素点最近的像素点(x, y)
3.3 将这个像素点的颜色替换成 1p.png 中像素点(x, y)的颜色
这里的最近,同时包括颜色差别和距离,相关的权重可以调整,然后上面这个算法是我自己编的,反正能用,也不知道是不是做了多余的部分。
使用方法:
1. 准备好原始图片和画风转换后的对比图,底色必须是透明的
2. 准备好跟原始图片相近的大量图片放在 images 文件夹里
3. 修改 main.m ,反复调试参数直到结果满意为止
main.m 里要修改的地方:
文件开头约13行处:
# parameters # cluster numbers must >= 2 global c_num = 2; # color weight: [R, G, B, Y, X] global color_weight = [1, 1, 1, 0.5, 0.05]; # train iteration times global iteration_max = 30; # splitImg(filename, x_slice, y_slice) splitImg('135-Maid03.png', 4, 4); # palette(fn_before, fn_after) palette('red.png', 'green.png'); # merge(x_slice, y_slice) mergeImg(4, 4);
# parameters
# cluster numbers must >= 2
global c_num = 2;
# color weight: [R, G, B, Y, X]
global color_weight = [1, 1, 1, 0.5, 0.05];
# train iteration times
global iteration_max = 30;
# splitImg(filename, x_slice, y_slice)
splitImg('135-Maid03.png', 4, 4);
# palette(fn_before, fn_after)
palette('red.png', 'green.png');
# merge(x_slice, y_slice)
mergeImg(4, 4);
# 开头的内容是注释
c_num 是聚类的个数,一般不要太大,看情况从2试起
color_weight 表示计算像素之间的距离的时候,Red, Green, Blue, Height, Width 各自的权重,后面的建议小一点
iteration_max 训练模型的最大迭代次数,别太小就行,太大意义也不大
splitImg,会把文件分成若干小块放入images文件夹里,第 1 个数字是横向分割的数量,第 2 个数字是纵向分割的数量
palette,第 1 个文件是转换前的参考图,第 2 个文件是转换后的参考图,输出结果会放在 result 文件夹里
mergeImg,将 result 文件夹中的图片合并成 result.png
关于权重,值越大说明这个属性越需要区分开。比如说,程序老是把图片上面的黑色和下面的黑色混到了一起,但是这两个本来对应的就不是同一种颜色,需要被区分开,增大 Height 的权重可以解决这个问题。cluster文件夹里会展示图片的分区。
打开 octave,切换到当前的目录。或者双击 main.m。
执行
显示:split image... start training... best solution find at 1 / 30, perp = 0.8477 best solution find at 2 / 30, perp = 0.9772 save clusters... show new pictures... images\01.png done. images\02.png done. images\03.png done. images\04.png done. images\05.png done. images\06.png done. images\07.png done. images\08.png done. images\09.png done. images\10.png done. images\11.png done. images\12.png done. images\13.png done. images\14.png done. images\15.png done. images\16.png done. merge image... Elapsed time is 4.2108 seconds.
split image...
start training...
best solution find at 1 / 30, perp = 0.8477
best solution find at 2 / 30, perp = 0.9772
save clusters...
show new pictures...
images\01.png done.
images\02.png done.
images\03.png done.
images\04.png done.
images\05.png done.
images\06.png done.
images\07.png done.
images\08.png done.
images\09.png done.
images\10.png done.
images\11.png done.
images\12.png done.
images\13.png done.
images\14.png done.
images\15.png done.
images\16.png done.
merge image...
Elapsed time is 4.2108 seconds.
然后就可以查看生成的 result.png 了 |