通过分层源图像自动生成随机构图**无需创建重复项**
Posted
技术标签:
【中文标题】通过分层源图像自动生成随机构图**无需创建重复项**【英文标题】:Automatically generate random compositions by layering source images **without creating duplicates** 【发布时间】:2021-12-22 01:44:26 【问题描述】:这是this question 的后续,ign 提出问题,Marc Setchell 专业回答
虽然我希望找到一种方法来避免在随机化过程中形成重复,但它工作得很好。我将对一堆图层进行数百种变体,但存在细微的差异,因此我无法真正进入并以故障安全的方式发现重复项。
这是我正在使用的代码,如上所述 - 归功于 Marc Setchell!
#!/bin/bash
# Number of output files - edit freely :-)
NFILES=10
# Build arrays of filenames in each layer, assume directories are "Layer0", "Layer1" etc
IFS=$'\n' L0files=($(find "Layer 0" -name "*.png"))
IFS=$'\n' L1files=($(find "Layer 1" -name "*.png"))
IFS=$'\n' L2files=($(find "Layer 2" -name "*.png"))
IFS=$'\n' L3files=($(find "Layer 3" -name "*.png"))
# Produce NFILES output files
for i in `seq 1 $NFILES`; do
# Choose random index into each array of filenames
index0=$( jot -r 1 0 $(($#L0files[@] - 1)) )
index1=$( jot -r 1 0 $(($#L1files[@] - 1)) )
index2=$( jot -r 1 0 $(($#L2files[@] - 1)) )
index3=$( jot -r 1 0 $(($#L3files[@] - 1)) )
# Pick up files as specified by the random index
f0=$L0files[index0]
f1=$L1files[index1]
f2=$L2files[index2]
f3=$L3files[index3]
# Generate output filename, "output-nnn.png"
# ... where nnn starts at 0 and goes up till no ***
i=0
while :; do
out="output-$i.png"
[ ! -f "$out" ] && break
((i++))
done
echo $f0, $f1, $f2, $f3 "=> $out"
convert "$f0" "$f1" -composite "$f2" -composite "$f3" -composite "$out"
done
【问题讨论】:
请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。 我正在寻找上面的代码 - 为了创建随机图像组合而对多个 png 进行分层 - 进行了编辑,以避免在随机化过程中产生重复。 @xenoid 在如何更改输出文件名方面非常有帮助,这太棒了,但如果它试图创建重复的图像,它现在会暂停 - 并且只有在移动原始文件后才会继续。所以我现在只需要知道如何让它在输出文件名的末尾添加一个数字,以便它不会在重复时暂停。然后我可以按名称搜索并查看重复项的位置,然后将其删除。 【参考方案1】:恕我直言,与 IM 或 PS 无关。只需命名您的文件,以便它们包含您用于创建它们的图层的索引,如果您发现您正在再次创建相同的文件,请跳过。
out="output-$index0-$index1-$index2-$index3.png"
[[ ! -f "$out" ]] && continue
((i++))
这还要求您不要使用seq 1 $NFILES
来迭代您的文件,因为您只想在不跳过(*) 时增加计数器。
完成后,如有必要,您可以将文件重命名为序列。
bash 中的另一种方法是声明一个关联数组,并为您创建的每个文件放入一个元素:
# declare associative array
declare -A doneFiles
# when creating a file:
combination=$index0-$index1-$index2-$index3
donefiles[$combination]="done" # or any info
# testing:
[[ -n $doneFiles[$combination] ]] && continue # already done
(*) 顺便说一下,即使你没有明确地使用外部变量,对外部和内部循环都使用i
是很疯狂的。但是内部循环是糟糕的代码,因为您可以使用外部i
。
【讨论】:
哇,感谢您快速、深入的回答!非常感谢您的帮助。也就是说,我应该透露我对该领域非常陌生。我明白你所说的应该这样做 - 根据构成每个图像的层完成命名 - 这将是绝对理想的。我只是不知道如何将您的编辑植入我的代码以使其工作。我确实尝试过,但认为我在某些关键步骤上是无知的:) 注意 - 我需要能够为输出选择一个最终数字,因为否则有数千个甚至数百万个变化的容量。 只是为了更新 - 我意识到如果我保留我当前的脚本,并且只更改行out="output-$index0-$index1-$index2-$index3.png"
它会根据它的顺序命名它,然后我可以在每个 $index
之前添加一些东西为了给每个文件夹/图层一个特定的标题。所以我仍然面临的唯一问题是,如果它要吐出一个副本,它就会暂停,并且只有在我从该目录中移动现有文件时才会继续。有没有办法在重复的文件名中自动添加后缀以防止它停止?再次感谢!!
删除你的内循环,这是不必要的。
您是否愿意向我发送我可以使用的完整代码?我试图查找它,但我超出了我的范围......无法弄清楚。抱歉,我知道这不应该是用勺子喂食。以上是关于通过分层源图像自动生成随机构图**无需创建重复项**的主要内容,如果未能解决你的问题,请参考以下文章
R语言使用random包生成随机数或者随机字符串实战:randomNumbers函数创建随机整数的数据集(包含重复项)randomSequence函数创建不含重复项的随机序列数据集创建随机字符串