如何使用FFMPEG + Imagemagick从图像/视频中提取有组织的调色板? [英] How to extract organized palette from image/video with FFMPEG+Imagemagick?

查看:336
本文介绍了如何使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆