颜色计数,按出现次数排序


14

这是一个简单的描述,我简直不敢相信这是以前没有打过的:

对于给定的图像(您的语言支持的任何格式),找到唯一的颜色并输出颜色列表。

  • 打印十六进制RGB的颜色代码,即一个哈希符号,#后跟R的2位数字,G的2位数字和B的2位数字(#xxxxxx其中x可以是0-9,AF和/或af)。
  • 十六进制代码后跟一个空格和十进制像素数,然后是换行符(\n\r\n)。
  • 该列表应按计数降序排序(最常见的颜色在顶部)。
  • 如果有领带(两种颜色的颜色相同),顺序并不重要。
  • 该图像将不包含透明度,因此任何alpha值都不重要。Alpha值可能不是输出的一部分。
  • 必须支持4000x3000的图片尺寸(这可能与类型定义有关)

示例图像“ 10red 20blue 30black 40white”: 样本图片1

预期产量:

#FFFFFF 40
#000000 30
#0000FF 20
#FF0000 10

样本图片“蓝色渐变”: 样本图片2

预期的输出之一(因为相同颜色的顺序可能有所不同):

#718DFF 19
#5571FF 15
#3855FF 11
#8DAAFF 11
#1C38FF 7
#AAAAFF 7
#8D8DFF 6
#AAC6FF 6
#C6C6FF 5
#C6E2FF 4
#001CFF 3
#E2E2FF 3
#FFFFFF 3

样本图片“ testImage”,由@Luis Mendo提供:

样本图片3

预期产量:

#FFFFFF 18042
#000000 1754
#FF3300 204

此问题类似,但输出是文本,而不是图像。


count descending还不清楚。我们如何分类?
Rɪᴋᴇʀ

@EᴀsᴛᴇʀʟʏIʀᴋ:降序:顶部最频繁的颜色
Thomas Weller

好的,我想说的需要更清楚一点。也许会说些什么the most frequent colors at the top
Rɪᴋᴇʀ

@EᴀsᴛᴇʀʟʏIʀᴋ:我同意,只是更新了两个问题
Thomas Weller

1
几个测试用例会很好。
Martin Ender

Answers:


4

Mathematica,91个字节

StringRiffle@SortBy[Tally["#"<>IntegerString[#,16,2]&/@Join@@#~ImageData~"Byte"],-Last@#&]&

使用与@DavidC的answer完全不同的方法。不同于那个,它可以支持任何大小和颜色数的图像。说明:

#~ImageData~"Byte"                   Take the RGB values of the image...
Join@@(...)                          Flatten to a list of colors...
"#"<>IntegerString[#,16,2]&/@(...)   Convert each color to #012def format...
Tally[(...)]                         Convert to a list of {color, multiplicity}
                                      pairs (this does most of the work)...
SortBy[(...),-Last@#&]               Order by the multiplicity descending...
StringRiffle@(...)                   And create a string with the desired format.

真好 我喜欢“字节”如何返回图像数据。
DavidC

4

Bash + coreutils,54岁

  • @manatwork节省了7个字节
grep -oE '#\w+'|sort|uniq -c|sort -nr|awk '$0=$2" "$1'

假设STDIN输入为 Imagemagick的.txt格式

伊迪恩


如果上述输入格式过于繁琐,那么我们可以添加任何格式的Imagemagick转换:

Bash + coreutils + Imagemagick,71岁

convert $1 txt:-|grep -oE '#\w+'|sort|uniq -c|sort -nr|awk '$0=$2" "$1'

在这里,输入图像文件名作为命令行参数传递。


2
awk的默认OFS是空格,您可以将'“”` ,
换成

1
甚至更短的awk部分:awk '$0=$2" "$1'
manatwork 2013年

3

JavaScript(ES6),359字节

@Neil节省了4个字节

u=>{i=new Image;i.src=u;e=document.createElement`canvas`;c=e.getContext`2d`;i.onload=_=>{w=e.width=i.width;h=e.height=i.height;c.drawImage(i,0,0);d=c.getImageData(0,0,w,h).data;for(o={},i=0;i<d.length;i+=4)++o[s='#'+`00000${(d[i]<<16|d[i+1]<<8|d[i+2]).toString(16)} `.slice(-7)]?0:o[s]=1;Object.keys(o).sort((a,b)=>o[b]-o[a]).map(c=>console.log(c+o[c]))}}

演示版

f=u=>{i=new Image;i.crossOrigin='';i.src=u;e=document.createElement`canvas`;c=e.getContext`2d`;i.onload=_=>{w=e.width=i.width;h=e.height=i.height;c.drawImage(i,0,0);d=c.getImageData(0,0,w,h).data;for(o={},i=0;i<d.length;i+=4)++o[s='#'+`00000${(d[i]<<16|d[i+1]<<8|d[i+2]).toString(16)} `.slice(-7)]?0:o[s]=1;Object.keys(o).sort((a,b)=>o[b]-o[a]).map(c=>console.log(c+o[c]))}}
f('http://i.imgur.com/acPudA9.gif')
<input value="https://i.imgur.com/acPudA9.gif" onchange="console.log('-------');f(this.value)">

我上传到imgur以支持CORS的其他测试用例:

在上载时,这两个特定的颜色数据似乎由于某些原因而略有变化,但是对于这两个测试用例,它仍然打印出相同的出现次数。


我认为|优先级较低,<<因此,如果使用它而不是优先级,+则不需要那么多()s。
尼尔

@ user2428118下次,如果您在评论中留下问题并要求我编辑自己的答案,而不是自己编辑,我将不胜感激。实际上,您通过<!-- language: lang-js -->从代码段中删除了我的演示,从而有效地禁用了JavaScript。
帕特里克·罗伯茨

@Patrick抱歉,下次我会更加小心。另外,我只是找到了一种保存一些字节的方法:u=>{document.write`<img src=${u} id=i><canvas id=e>`;c=e.getContext`2d`;i.onload=_=>{w=e.width=i.width;h=e.height=i.height;c.drawImage(i,0,0);d=c.getImageData(0,0,w,h).data;for(o={},i=0;i<d.length;i+=4)++o[s='#'+`00000${(d[i]<<16|d[i+1]<<8|d[i+2]).toString(16)} `.slice(-7)]?0:o[s]=1;Object.keys(o).sort((a,b)=>o[b]-o[a]).map(c=>console.log(c+o[c]))}}
user2428118

2

Pyth,29个字节

jmj;_d_SrSm+\#.[\06.Hid256'Q8

在线尝试!

(在线解释器无法读取图像,因此我剥离了该部分,并输入了读取图像的结果,该结果是三色列的列表。负责读取图像的部分是 '一个冒号。)

'单个冒号的功能证明


您需要一个sbefore 'Q,因为图像表示为三元组列表的列表。
贾库贝

这是一个正确的(更短的)解决方案V_SrS%L+\#*3"%02X"s'z8jd_N
Jakube

2

Mathematica 103 92字节

{"#"<>IntegerString[255Round[List@@#],16,2],#2}&@@@DominantColors[#,9999,{"Color","Count"}]&

图片


说明

DominantColors通常返回代表图片中主要簇的颜色和计数列表。当请求的颜色数量超过图像中的颜色数量时,将返回确切的像素颜色。(我假设输入图像中的颜色少于10000种。)

图片


{"#"<>IntegerString[255Round[List@@#],16,2],#2} 使用十六进制值转换基数为10的颜色值。


注意:山d图像中只有5种颜色。(我曾经ColorQuantize[<image>,5]减少标准山man图像中的颜色数量。)


只是让您失望了;)
LegionMammal978

一点点。但是您的方法需要无限数量的颜色。
DavidC

1

PowerShell v2 +,187字节

$a=New-Object System.Drawing.Bitmap $args[0]
$b=@{}
0..($a.Height-1)|%{$h=$_;0..($a.Width-1)|%{$b["#"+-join($a.GetPixel($_,$h).Name[2..7])]++}}
$b.GetEnumerator()|Sort value -des|FT -h -a

重用我回答以来的几乎所有代码 获得最主要的颜色。因此,请参考它以获取完整说明。

这里的变化是在索引$b中的第三行相匹配的明确的输出格式要求,并在最后一行,我们sort通过value-descending顺序,然后管Format-Table-HideTableHeaders和-AutoSize作为参数。实际使用非常罕见FT,在PPCG,因为在执行结束时输出是隐式的,但是在这里确保我们仅获得正确的零件输出非常有用。

例子

第一个是来自“优势色彩”挑战的“红色”测试图像,第二个是来自该挑战的“测试图像”。

PS C:\Tools\Scripts\golfing> .\color-count.ps1 C:\Tools\Scripts\golfing\img\red.png

#ff0000 139876
#dcd9cf 3056  
#f2f1ed 1512  
#ffffff 1508  
#ffe6e6 1488  
#ffe3e3 8     
#eae8e2 4     
#fffbfb 4     


PS C:\Tools\Scripts\golfing> .\color-count.ps1 C:\Tools\Scripts\golfing\img\z07VA.gif

#ffffff 18042
#000000 1754 
#ff3300 204  

1

Tcl / Tk,134字节

console s
lmap s [concat {*}[[image c photo -fi $argv] d]] {dict inc D $s}
dict fo k\ v [lsort -int -s 2 -inde 1 -de $D] {puts $k\ $v}

d是为data

Tcl / Tk,232字节

console s
set I [image c photo -fi $argv]
set i 0
time {set j 0
time {dict inc D #[join [lmap s [$I g $i $j] {format %02X $s}] ""]
incr j} [image h $I]
incr i} [image w $I]
dict fo k\ v [lsort -int -s 2 -inde 1 -de $D] {puts $k\ $v}

wish sort_pix.tcl QTE4O.png

在此处输入图片说明


wish sort_pix.tcl 5s1Ob.png

在此处输入图片说明


wish sort_pix.tcl z07VA.gif

在此处输入图片说明


1

Brain-Flak,1110字节

{{}({}[(()()()()()){}])}{}(<>)<>([]){{}({}()<({}()<({}()<>)>)>)<>([])}{}<>{({}<({}<({}<(()()<>)>)>)>)<>{(<>)<>(()()()){({}[()]<<>({}<([([(({})<>[({})]<>)])]<>)<>{({}()<([{}])<>({}<>)<>>)<>}{}<>{}<>>{})({}<({}<({}<>)<>({}<>)<>({}<>)<>>)<>({}<>)<>({}<>)<>({}<>)>)<>({}<({}<>)<>({}<>)<>>)<>({}<>)<>({}<>)>)}{}<>((){[()](<{}>)}{})((){[()](<{}({}())<>{}{}{}>)}{}){{}(<<>(()()()){({}[()]<({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}<>>)}{}>)}{}<>({}<({}<>)<>({}<>)<>({}<>)<>>)<>({}<>)<>({}<>)<>({}<>)<>}({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}(()()()()){((({}[()])<{({}[()]<({}<({}<>)<>>)>)}{}>)<{({}[()]<<>({}<>)>)}{}>)}{}<>}{}<>(()()()())([][()])({}(<>))<>([()]{()<(({})){({}[()])<>}{}>}{}<><{}{}>){({}[()]<(<(()()()())([][()])({}(<>))><>([()]{()<(({})){({}[()])<>}{}>}{}<><{}{}>)<{({}[()]<([([({}<({}<({}<({}<(({})<>)<>>)>)>)>)<><({}<>)>]{}<(())>)](<>)){({}())<>}{}({}<><{}{}>){{}<>(<({}<({}<({}<({}<({}<({}<({}<({}<>)>)>)>)<>>)>)>)>)<>({}<({}<({}<({}<<>>)>)>)>)>)}{}({}<({}<({}<({}<>)>)>)>)<>>)}{}<>{}{}{}{}>[()]){({}[()]<({}<({}<({}<({}<>)>)>)>)<>>)}{}<>>)}{}{({}[()]<>)<>}<>

在线尝试!

嗯,那是一次冒险。事实证明,Brain-Flak在图像处理方面不是很好。谁知道?

首先,我将指出这在技术上不符合要求的严格输出格式。如果您要强制执行该操作,请告诉我,我将尝试添加翻译代码。现在,它输出十进制数字:每4个数字代表红色绿色蓝色计数顺序中的一种颜色。

接下来,输入。允许的输入格式更加灵活,因此我使用了最易于Brain-Flak解析的格式(我可以找到):Netpbm P6。不幸的是,Brain-Flak无法解析P3格式的十进制数字,因为所有Netpbm图像均以字符开头,P而Brain-Flak无法处理来自包含非数字字符的文件中的十进制输入。因此使用P6代替,因为P6将颜色信息存储为字节,在ASCII输入模式下将其视为数字。由于标准需要标头信息,因此输入仍然是有效的Netpbm文件,因此仍然存在挑战。没有进行有用的编码,但是幸运的是,我不需要任何这些信息,因此将其丢弃。此程序未完全遵守Netpbm标准,因为它不允许标题内包含换行符,但不允许换行符

最后警告,TIO上的版本实际上未正确配置为“正式”操作,因为(据我所知)我无法在TIO上提供文件作为输入,也无法在直接输入中提供与不可打印ASCII对应的字节。为了进行正式操作,-a需要使用该标志将输入作为原始字节并-f从文件中获取输入。而是从Netpbm Wiki页面上的示例手动翻译了TIO链接上的示例输入。

另外,我还要感谢Brain-Flak Wiki提供的有用的代码片段。特别是,一旦我对每种颜色都进行了计数,此处的Bubble-Sort实施将对最后一步发挥作用,因为我真的不知道从哪里开始。它进行了重大修改,但我很高兴不必从头开始。

是该代码的原始版本和注释版本。Brain-Flak有点冗长,无法在本文中包含有用的格式化说明,但是TIO的非高尔夫版本包含我将包含的所有内容,其格式比我在这里可以管理的要好,因此,如果您有兴趣,请选择看。

可能还有打高尔夫球的机会,我之前对 Brain-Flak的回答经过了很多修改,但希望在那里获得的经验教训能为您提供一个更好的起点。


0

Python 2,186字节

import Image
I=Image.open(input()).convert('RGB')
w,h=I.size
r=['#'+('%0.2X'*3)%I.getpixel((i%w,i/h))for i in range(w*h)]
for a,b in sorted(set((r.count(v),v)for v in r))[::-1]:print b,a

在线尝试!

免责声明:呈现的输出是一列,以提高可读性。代码输出根据质询的要求将空格和行分隔开。

10red 20blue 30black 40white的输出:

[('#FFFFFF', 40), ('#000000', 30), ('#0000FF', 20), ('#FF0000', 10)]

蓝色渐变的输出:

[('#718DFF', 19), ('#5571FF', 15), ('#8DAAFF', 11), ('#3855FF', 11), ('#AAAAFF', 7), ('#1C38FF', 7), ('#AAC6FF', 6), ('#8D8DFF', 6), ('#C6C6FF', 5), ('#C6E2FF', 4), ('#FFFFFF', 3), ('#E2E2FF', 3), ('#001CFF', 3)]

输出测试图像

[('#FFFFFF', 18042), ('#000000', 1754), ('#FF3300', 204)]

说明:

w,h=I.size # field size stores tuple of values of width and height of image

I.getpixel((i%w,i/h)) # returns tuple of base10 RGB values

('%0.2X'*3) # format string to convert int into hex

set((r.count(v),v)for v in r) # generate set of unique pairs count-color 

sorted(set(...))[::-1] # apply sorted(), as it sorts set of tuples by firts elements and reverse sort

print b,a  # swap values in tuples and print

0

爪哇(1.4+) 483个 428字节

import java.util.*;class I {public static void main(String[] a) throws Exception {java.awt.image.BufferedImage i = javax.imageio.ImageIO.read(new java.io.File(a[0]));Map m=new HashMap();String s;for(Integer x=0,y=0,c;y<i.getHeight();y++)for(x=0;x<i.getWidth();m.put(s=x.toHexString(((c=i.getRGB(x++,y))&0xff0000)>>16)+x.toHexString((c & 0xff00)>>8)+x.toHexString(c&0xff),m.get(s)==null?1:(int)m.get(s)+1));System.out.print(m);}}

在线尝试!(不在线工作)


取消高尔夫:

import java.util.*;

class I {
    public static void main(String[] a) throws Exception {
        java.awt.image.BufferedImage i = javax.imageio.ImageIO
                .read(new java.io.File(a[0]));
        Map m = new HashMap();
        String s;
        for (Integer x = 0, y = 0, c; y < i.getHeight(); y++)
            for (x = 0; x < i.getWidth(); m
                    .put(s = x.toHexString(((c = i.getRGB(x++, y)) & 0xff0000) >> 16)
                            + x.toHexString((c & 0xff00) >> 8)
                            + x.toHexString(c & 0xff), m.get(s) == null ? 1
                            : (int) m.get(s) + 1))
                ;
        System.out.print(m);
    }
}

toString()地图的输出是这样的:

{7c7c7c=6, 1d57a5=20468, 121212=7, d3d3d3=3, bdbdbd=9, 949494=2, 333=14, 626262=3, cacaca=2, 141414=5, fff=11, c9c9c9=1, e8e8e8=1, 919191=4, 161616=5, c2c2c2=1, 646464=7, 979797=12, fafafa=2, 808080=1, 7b7b7b=1, 484848=4, b9b9b9=2, f1f1f1=2, 6b6b6b=6, 363636=15, 262626=4, d8d8d8=2, 868686=4, 757575=1, 575757=3, a7a7a7=2, cecece=2, dcdcdc=2, c3c3c3=2, 1d1d1d=5, 727272=9, 656565=2, 3a3a3a=3, 7d7d7d=10, 393939=5, 797979=3, 222=31, 8f8f8f=2, 454545=4, 181818=9, 2e2e2e=2, 222222=1, 1c1c1c=19, b8b8b8=2, e1e1e1=5, 232323=5, 8a8a8a=3, 959595=7, 6a6a6a=9, 434343=7, 5c5c5c=3, 111=20, 909090=3, 424242=4, 212121=1, 1a1a1a=6, 202020=7, efefef=1, 565656=5, 6e6e6e=7, 767676=3, 323232=2, eee=5, 444=18, 2c62ab=1, 717171=2, b1b1b1=3, 6c6c6c=3, 545454=7, 515151=17, 2f2f2f=2, 4a4a4a=3, 888888=6, 6d6d6d=3, 898989=3, a3a3a3=5, 7e7e7e=9, ddd=9, b6b6b6=3, 2b2b2b=5, 313131=5, 8d8d8d=1, a2a2a2=2, 696969=3, a5a5a5=3, 4f4f4f=5, 828282=7, 191919=5, 606060=4, 6f6f6f=4, 8b8b8b=3, ebebeb=2, 555=19, 929292=3, 131313=11, 999999=5, d2d2d2=2, 444444=9, 474747=4, dddddd=1, 585858=8, 5a5a5a=3, 000=9887, afafaf=2, dfdfdf=3, 747474=3, 666666=4, a1a1a1=4, 2a2a2a=11, 4d4d4d=6, 818181=2, 878787=5, 215aa6=1, d9d9d9=4, b5b5b5=3, b4b4b4=3, 737373=4, aeaeae=3, bbb=15, 242424=4, 2d2d2d=8, 888=19, c1c1c1=1, 494949=9, dbdbdb=5, ccc=19, 5d5d5d=3, 5f5f5f=1, 414141=6, c8c8c8=3, aaa=16, 1e1e1e=3, 707070=2, 9e9e9e=2, 373737=7, 9d9d9d=2, 1b1b1b=4, 303030=7, 535353=10, 595959=2, 8e8e8e=3, 383838=5, 939393=18, 616161=2, 686868=6, dadada=1, e3e3e3=2, 5b5b5b=3, a4a4a4=5, 8c8c8c=5, a6a6a6=11, 292929=6, 4c4c4c=3, 151515=6, fefefe=2, 787878=2, 505050=2, e2e2e2=1, 1f1f1f=9, adadad=2, ababab=1, 5e5e5e=6, 252525=4, 4e4e4e=3, 282828=7, a8a8a8=4, 9c9c9c=3, aaaaaa=1, 101010=5, b7b7b7=2, 969696=6, 7f7f7f=4, 555555=2, a9a9a9=5, 343434=8, 999=17, 777777=3, ffffff=76669, f0f0f0=4, bbbbbb=1, 1e58a5=1, b3b3b3=4, 777=20, 636363=2, d4d4d4=1, 2c2c2c=5, 848484=1, 3c3c3c=3, bfbfbf=2, 3e3e3e=9, 333333=4, 7a7a7a=3, 858585=4, 4b4b4b=3, 272727=7, 111111=6, 666=13, 9b9b9b=1, bcbcbc=4, cfcfcf=2, 9a9a9a=1, 404040=21, 525252=3, 989898=4, 171717=5, 3b3b3b=2, c4c4c4=1, 3f3f3f=7, 464646=1, cdcdcd=2, b2b2b2=33, c5c5c5=2, bababa=2}

请不要发布有关1.8高尔夫球的具体建议,除非它在较旧的Java中有效,否则我就不要了。

示例: Lambda在Java版本中的作用超出了它们的工作范围。


请不要发布1.8特定的高尔夫建议,除非它在较旧的Java中有效,我不想要。 ”出于好奇:为什么Java 10已经提供Java 4?
凯文·克鲁伊森

一些打高尔夫球应该在Java中4工作(我认为): import java.util.*;class M{public static void main(String[]a)throws Exception{java.awt.image.BufferedImage i=javax.imageio.ImageIO.read(new java.io.File(a[0]));Map m=new HashMap();String s;for(Integer x=0,y=0,c;y<i.getHeight();y++)for(x=0;x<i.getWidth();m.put(s=x.toHexString((c&0xff0000)>>16)+x.toHexString((c&0xff00)>>8)+x.toHexString(c&0xff),m.get(s)==null?1:(int)m.get(s)+1))c=i.getRGB(x++,y);System.out.print(m);}}419个字节
凯文Cruijssen

@KevinCruijssen因为可以说1.8是最大的版本,因此无法在以前的版本中运行。其他大多数发行版是对JRE的修复和添加的类。1.8与以前的JRE兼容性最低。
魔术章鱼缸

@KevinCruijssen x.toHexInteger比静态导入要聪明。
魔术章鱼缸

也不是Java 3,因为Java 3 ...确实...捷径如此之少...
Magic Octopus Urn

0

SmileBASIC,165字节

DEF C A
L=LEN(A)DIM C[L],N[L]FOR J=0TO L-1FOR I=0TO U-1ON A[J]-C[I]GOTO@L
NEXT
U=U+1@L
C[I]=A[J]INC N[I]NEXT
RSORT.,U,N,C
FOR I=0TO U-1?"#";HEX$(C[I],6),N[I]NEXT
END

图像以32位ARGB颜色值的数组形式给出(将数字转换为6位十六进制字符串时会修剪alpha值)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.