如何使用FFMPEG + Imagemagick从图像/视频中提取有组织的调色板? [英] How to extract organized palette from image/video with FFMPEG+Imagemagick?
问题描述
我使用FFMPEG和Imagemagick从带有Windows批处理文件的图片或视频中提取调色板,
::获取当前文件夹名称
for(。)中的%% * do set CurrDirName = %%〜nx *
::获取当前文件名
/ R%1 %% f in(。)do(
set CurrFileName = %%〜nf
)
ffmpeg -i%1-vf palettegen_%CurrFileName%_temp_palette.png
convert_%CurrFileName%_temp_palette.png-filter point -resize 4200 %%_%CurrFileName%_palette.png
del_%CurrFileName%_temp_palette.png
这会输出像
我需要这样才能在整个颜色块中实现更好的过渡,就像从黑暗到亮的所有蓝色,然后过渡到绿色,黄色等。 ,
这里是脚本。这是很好的评论,应该很容易转换到足够的Windows如果你喜欢它的作用。
#!/ bin / bash
#创建随机数据的初始图像100x100
convert -size 100x100 xc:gray + noise random image.png
#提取图像中的唯一颜色并转换为HSL颜色空间,从而到awk的文本
convert image.png -unique-colors -colorspace hsl -depth 8 txt:| awk -F[(),] +'
!/ ^#/ {
H = $ 3; S = $ 4; L = $ 5#拿起HSL。对于色调,32768 = 180度,65535 = 360度。对于S& L,32768 = 50%,65535 = 100%
NGROUPS = 4#根据所需的颜色组数更改此值
bin = 65535 / NGROUPS#计算bin大小$ b $ b group = int(int(H / bin)* bin)#将Hue分割成NGROUPS
printf%d%d%d%d\\\
,group,H,S,L
} '> groupHSL.txt
#按列1(组),然后按列4(亮度)排序
排序-n -k1,1 -k4,4< groupHSL.txt> groupHSL-sorted.txt
#将排序的像素重新组装成简单的图像,HSL数据的16位PNM格式
#丢弃我们使用的列1($ 1)中的组,排序数据
awk'{H [++ i] = $ 2; S [i] = $ 3; L [i] = $ 4}
END {
printfP3\\\
printf%d%d\\\
,i,1
printf65535\\ \\ n
for(j = 1; j <= i; j ++){
printf%d%d%d \\\
,H [j],S [j] j]
}
}'groupHSL-sorted.txt> HSL.pnm
#将HSL.pnm转换为sRGB.png
convert HSL.pnm -set colorspace hsl -colorspace sRGB sRGB.png
#制作方形
convert sRGB.png -crop 1x1 miff: - | montage -geometry + 0 + 0-tile 40x - result.png
如果我设置 NGROUPS
到10,我会得到:
如果我将NGROUPS设置为4,我会得到:
请注意,脚本不是使用管道和shell技巧,而是生成中间文件,因此您可以轻松查看每个处理阶段,以便对其进行调试。
例如,如果你运行这个:
convert image.png -unique-colors -colorspace hsl -depth 8 txt:|更多
您将看到 convert
传递到 awk
:
#ImageMagick像素枚举:10000,1,255 ,hsl
0,0:(257,22359,1285)#015705 hsl(1.41176,34.1176%,1.96078%)
1,0:(0,0,1542)#000006 hsl(0, 0%,2.35294%)
2,0:(41634,60652,1799)#A2EC07 hsl(228.706,92.549%,2.7451%)
3,0:(40349,61166,1799)#9DEE07 hsl(221.647,93.3333%,2.7451%)
4,0:(31868,49858,2056)#7CC208 hsl(175.059,76.0784%,3.13725%)
5,0:(5140,41377, 3341)#14A10D hsl(28.2353,63.1373%,5.09804%)
6,0:(61423,59367,3598)#EFE70E hsl(337.412,90.5882%,5.4902%)
如果你看看 groupHSL-sorted.txt
,你会看到像素已分类到组中,然后提高亮度:
0 0 53456 10537
0 0 18504 20303
0 0 41377 24158
0 0 21331 25700
0 0 62708 28270
0 0 53199 31354
0 0 23130 32896
0 0 8738 33410
0 0 44204 36494
0 0 44204 36751
0 0 46260 38293
0 0 56283 40606
0 0 53456 45489
0 0 0 46517
0 0 32896 46517
0 0 16191 50372
0 0 49601 55769
0 257 49601 11565
0 257 42148 14392
0 257 53713 14649
0 257 50115 15677
0 257 48830 16191
Windows在引用事物时尤其尴尬上面为 awk
。我建议你提取两个单独的 awk
脚本到单独的文件,像这样:
script1。 awk
!/ ^#/ {
H = $ 3; S = $ 4; L = $ 5#拿起HSL。对于色调,32768 = 180度,65535 = 360度。对于S& L,32768 = 50%,65535 = 100%
NGROUPS = 4#根据所需的颜色组数更改此值
bin = 65535 / NGROUPS#计算bin大小$ b $ b group = int(int(H / bin)* bin)#将Hue分割成NGROUPS
printf%d%d%d%d \\\
,group,H,S,L
}
和
script2。 awk
{H [++ i] = $ 2; S [i] = $ 3; L [i] = $ 4}
END {
printfP3\\\
printf%d%d\\\
,i,1
printf65535\\ \\ n
for(j = 1; j <= i; j ++){
printf%d%d%d \\\
,H [j],S [j] j]
}
}
然后主脚本中的两行成为像:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: awk -F[(),] +-f script1.awk> groupHSL.txt
和
awk -f script2.awk groupHSL-sorted.txt> HSL.pnm
I use FFMPEG and Imagemagick to extract the color palette from an image or video with a Windows batch file,
:: get current folder name
for %%* in (.) do set CurrDirName=%%~nx*
:: get current filename
for /R %1 %%f in (.) do (
set CurrFileName=%%~nf
)
ffmpeg -i "%1" -vf palettegen "_%CurrFileName%_temp_palette.png"
convert "_%CurrFileName%_temp_palette.png" -filter point -resize 4200%% "_%CurrFileName%_palette.png"
del "_%CurrFileName%_temp_palette.png"
This outputs something like,
I need this to have better transition throughout the color blocks though, like all blues from darkest to lightest then transitioning to greens, yellows etc. like,
Is there a way/switch to create this with either Imagemagick/FFMPEG?
I don't like working on Windows, but I wanted to show you a technique you could use. I have therefore written it in bash
but avoided nearly all Unix-y stuff and made it very simple. In order to run it on Windows, you would only need ImageMagick and awk
and sort
which you can get for Windows from here and here.
I'll demonstrate using an image of random data that the script creates on around the third line:
Here is the script. It is pretty well commented and should convert easily enough to Windows if you like what it does.
#!/bin/bash
# Create an initial image of random data 100x100
convert -size 100x100 xc:gray +noise random image.png
# Extract unique colours in image and convert to HSL colourspace and thence to text for "awk"
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" '
!/^#/{
H=$3; S=$4; L=$5 # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}' > groupHSL.txt
# Sort by column 1 (group) then by column 4 (Lightness)
sort -n -k1,1 -k4,4 < groupHSL.txt > groupHSL-sorted.txt
# Reassemble the sorted pixels back into a simple image, 16-bit PNM format of HSL data
# Discard the group in column 1 ($1) that we used to sort the data
awk ' { H[++i]=$2; S[i]=$3; L[i]=$4 }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}' groupHSL-sorted.txt > HSL.pnm
# Convert HSL.pnm to sRGB.png
convert HSL.pnm -set colorspace hsl -colorspace sRGB sRGB.png
# Make squareish shape
convert sRGB.png -crop 1x1 miff:- | montage -geometry +0+0 -tile 40x - result.png
If I set NGROUPS
to 10, I get:
If I set NGROUPS to 4, I get:
Note that, rather than using pipes and shell tricks, the script generates intermediate files so you can easily see each stage of the processing in order to debug it.
For example, if you run this:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | more
you will see the output that convert
is passing to awk
:
# ImageMagick pixel enumeration: 10000,1,255,hsl
0,0: (257,22359,1285) #015705 hsl(1.41176,34.1176%,1.96078%)
1,0: (0,0,1542) #000006 hsl(0,0%,2.35294%)
2,0: (41634,60652,1799) #A2EC07 hsl(228.706,92.549%,2.7451%)
3,0: (40349,61166,1799) #9DEE07 hsl(221.647,93.3333%,2.7451%)
4,0: (31868,49858,2056) #7CC208 hsl(175.059,76.0784%,3.13725%)
5,0: (5140,41377,3341) #14A10D hsl(28.2353,63.1373%,5.09804%)
6,0: (61423,59367,3598) #EFE70E hsl(337.412,90.5882%,5.4902%)
If you look at groupHSL-sorted.txt
, you will see how the pixels have been sorted into groups and then increasing lightness:
0 0 53456 10537
0 0 18504 20303
0 0 41377 24158
0 0 21331 25700
0 0 62708 28270
0 0 53199 31354
0 0 23130 32896
0 0 8738 33410
0 0 44204 36494
0 0 44204 36751
0 0 46260 38293
0 0 56283 40606
0 0 53456 45489
0 0 0 46517
0 0 32896 46517
0 0 16191 50372
0 0 49601 55769
0 257 49601 11565
0 257 42148 14392
0 257 53713 14649
0 257 50115 15677
0 257 48830 16191
Windows is particularly awkward at quoting things - especially scripts in single quotes like I use above for awk
. I would suggest you extract the two separate awk
scripts into separate files something like this:
script1.awk
!/^#/{
H=$3; S=$4; L=$5 # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}
and
script2.awk
{ H[++i]=$2; S[i]=$3; L[i]=$4 }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}
Then the two lines in the main script will become something like:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" -f script1.awk > groupHSL.txt
and
awk -f script2.awk groupHSL-sorted.txt > HSL.pnm
这篇关于如何使用FFMPEG + Imagemagick从图像/视频中提取有组织的调色板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!