如何使用FFMPEG + Imagemagick从图像/视频中提取有组织的调色板?

时间:2016-01-14 14:31:07

标签: batch-file colors ffmpeg imagemagick image-manipulation

我使用FFMPEG和Imagemagick从Windows批处理文件中提取图像或视频中的调色板,

:: 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"

这会输出类似的内容,

Palette

我需要这样才能在整个色块中有更好的过渡,就像从最暗到最轻的所有蓝调然后过渡到绿色,黄色等一样,

Better Palette

是否有方法/开关用Imagemagick / FFMPEG创建它?

1 个答案:

答案 0 :(得分:3)

我不喜欢在Windows上工作,但我想向您展示一种可以使用的技术。因此我在bash中写了它,但几乎避免了所有Unix-y的东西,并且使它变得非常简单。要在Windows上运行它,您只需要ImageMagick和awk以及sort,您可以从herehere获取Windows。

我将使用脚本在第三行附近创建的随机数据图像进行演示:

enter image description here

这是脚本。它评论很好,如果你喜欢它,它应该很容易转换成Windows。

#!/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

如果我将NGROUPS设置为10,我会得到:

enter image description here

如果我将NGROUPS设置为4,我会得到:

enter image description here

请注意,脚本不是使用管道和shell技巧,而是生成中间文件,以便您可以轻松查看处理的每个阶段以进行调试。

例如,如果你运行它:

convert image.png -unique-colors -colorspace hsl -depth 8 txt: | more

您会看到convert传递给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%)

如果您查看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            # 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
 }

<强> 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]
       }
    }

然后主脚本中的两行将变为:

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