faster octree color quantization
256色画åƒå…¨ç››æœŸã¯ã¨ã£ãã«éŽãŽåŽ»ã£ãŸæ„ŸãŒã‚ã‚Šã¾ã™ãŒã€ä»Šå›žã¯ç”»åƒã‚’256色以下ã«æ¸›è‰²ã™ã‚‹ã¨ã„ã†è©±ã§ã™ã€‚減色ã•ã‚ŒãŸç”»åƒã®ç”»è³ªã‚’å‘上ã•ã›ã‚‹æ–¹æ³•ã¨ã—ã¦èª¤å·®æ‹¡æ•£æ³•ãŒã‚ã‚Šã¾ã™ãŒã€ä»Šå›žã¯ãã‚Œã¯ã‚„ã‚Šã¾ã›ã‚“。
減色ã™ã‚‹æ–¹æ³•ã¯å¤§æ˜”ã‹ã‚‰ç ”究ã•ã‚Œã¦ã„ã¦æœ‰åãªã‚‚ã®ãŒã„ãã¤ã‹ã‚ã‚Šã¾ã™ã€‚
- å‡ç‰é‡å化法 (uniform quantization)
- RGB888ãªã©ã‚’RGB332ãªã©ã«ãƒžãƒƒãƒ”ングã™ã‚‹
- 高速ã€å˜ç´”ã€ç°¡æ˜“ã€ã ãŒç”»è³ªã¯ä½Žã„
- é »åº¦æ³• (popularity algorithm)
- ç”»ç´ ã®å‡ºç¾é »åº¦ã‹ã‚‰ãƒ‘レットを作æˆã™ã‚‹
- 画質ã¯ã„ã¾ã„ã¡
- ä¸å¤®å€¤åˆ†å‰²æ³• (median cut algorithm)
- 一時ã¯æœ€å¼·ã¨å‘¼ã°ã‚Œã¦ã„ãŸæ‰‹æ³•
- 色空間を二分ã—ã¦ã„ã
- 複雑ã ãŒå‰²ã¨é«˜é€Ÿã§å‰²ã¨ãã‚Œã„
- 色空間ã¯RGBよりもYCbCrã§åˆ†å‰²ã™ã‚‹æ–¹ãŒã‚ˆã„ã¯ãš
- 八分木 (octree algorithm)
- ç¾åœ¨æœ€å¼·ã®æ‰‹æ³•
- モダンã§ç°¡æ½”ã§é«˜é€Ÿã§ãã‚Œã„
- 以下ã®æ–‡æ›¸ã¨ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ãŒåˆ†ã‹ã‚Šã‚„ã™ã„
今回ã¯octreeã‚’ã‚„ã‚Šã¾ã™ã€‚画質を追求ã™ã‚‹ã®ã¯Image Magickãªã©ãŒã‚„ã£ã¦ã„ã¾ã™ã®ã§ã€é€Ÿåº¦ã‚’追求ã—ã¦ã¿ã¾ã—ょã†ã€‚octreeã®è¨ˆç®—é‡ã¯ã€ç”»åƒã®æ¨ªå¹…ã‚’Wã€ç¸¦å¹…ã‚’Hã€æ·±ã•ã‚’Dã¨ã™ã‚‹ã¨ã€O(W*H*D)ã¨ãªã‚Šã¾ã™ã€‚試ã—ãŸé™ã‚Šã ã¨ã€octreeã ã¨æ·±ã•ãŒ4〜5程度ã§ç”»åƒã‚’人ãŒèªè˜ã™ã‚‹ã«ã¯å分ãªç”»è³ªãŒå¾—られã¾ã™ãŒã€ã„ã‹ã‚“ã›ã‚“ループ回数ãŒå¤šã™ãŽã¾ã™ã€‚ピクセル処ç†ãªã®ã«ãƒœã‚¯ã‚»ãƒ«å‡¦ç†ã—ã¦ã‚‹ã¿ãŸã„ãªè¨ˆç®—é‡ã§ã™ã€‚
é‡å化ループã®æœ€é©åŒ–ãã®ï¼‘
octreeã®ãƒ«ãƒ¼ãƒ—処ç†ã®ã‚³ãƒ¼ãƒ‰ã‚’見るã¨ã€åŒã˜ç”»ç´ ã«å¯¾ã—ã¦ã¯å…¨ãåŒã˜å‡¦ç†ãŒç¹°ã‚Šè¿”ã•ã‚Œã‚‹ã¨ã„ã†ã“ã¨ãŒåˆ†ã‹ã‚Šã¾ã™ã€‚ã“れを利用ã—ãŸæœ€é©åŒ–を考ãˆã¾ã™ã€‚ç”»åƒã®ãƒ’ストグラムを求ã‚ã‚‹ã“ã¨ãŒã§ãã‚Œã°ã€ç”»åƒã®è‰²æ•°åˆ†ã ã‘ã®ãƒ«ãƒ¼ãƒ—ã§æ¸ˆã¿ãã†ã§ã™ã。画åƒã®è‰²æ•°Cã¯ã€å¿…ãšC<=W*H以下ã«ãªã‚‹ã®ã§ã€è¨ˆç®—é‡ã¯å¿…ãšæœ€é©åŒ–å‰ã‚ˆã‚Šã‚‚å°ã•ããªã‚Šã¾ã™ã€‚
ç”»åƒã®è‰²æ•°åˆ†ã ã‘ループã™ã‚‹æ–¹æ³•ã«å‡¦ç†ã‚’書ãæ›ãˆã‚‹ã«ã¯ã€ç”»åƒã®ãƒ’ストグラムを求ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ç”»åƒã®ç”»ç´ をソートã™ã‚‹ã“ã¨ã§ç”»åƒã®ãƒ’ストグラムを求ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™ãŒ*1ã€ã‚½ãƒ¼ãƒˆã¯å‰²ã¨ã‚³ã‚¹ãƒˆãŒã‹ã‹ã‚‹ã®ã§é«˜é€ŸåŒ–ã«ã¯ä½¿ãˆã¾ã›ã‚“*2。よã£ã¦ã€çœŸé¢ç›®ã«ãƒ’ストグラムを計算ã™ã‚‹æ–¹ãŒè‰¯ã•ãã†ã§ã™ã€‚ã—ã‹ã—ã€çœŸé¢ç›®ã«ãƒ’ストグラムを計算ã™ã‚‹ã¨å¤§é‡ã«ãƒ¡ãƒ¢ãƒªãŒå¿…è¦ã«ãªã‚Šã¾ã™ã€‚RGB888ã§ã€ãƒ’ストグラムã®å„è¦ç´ を符åˆãªã—æ•´æ•°ã§ç®¡ç†ã™ã‚‹ã¨ã€2^24*4ã§64MBã‚‚ã®ãƒ¡ãƒ¢ãƒªãŒå¿…è¦ã«ãªã£ã¦ã—ã¾ã„ã¾ã™ã€‚最近ã®ç«¯æœ«ã‚„サーãƒãªã‚‰ä½™è£•ãªæ°—ã‚‚ã—ã¾ã™ãŒã€é•·ã„ã“ã¨ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã‚¢ãƒ—リを作ã£ã¦ããŸç§ã®æ„Ÿè¦šçš„ã«ã¯ãƒ¡ãƒ¢ãƒªã‚’使ã„éŽãŽã§ã™ã—ã€è‰²æ•°ãŒ1677万色もã‚ã‚‹ã¨æœ€æ‚ªã§65536x65536ã®ç”»åƒã«ç›¸å½“ã™ã‚‹å‡¦ç†ã‚’やらãªã„ã¨ã„ã‘ãªããªã‚‹ã®ã§é«˜é€ŸåŒ–ã§ãã‚‹ã®ã‹ãŒä¸å®‰ã«ãªã£ã¦ãã¾ã™ã€‚ã¨ã„ã†ã‚ã‘ã§ã€ç²¾åº¦ã‚’è½ã¨ã™ã“ã¨ã‚’考ãˆã¦ã¿ã¾ã—ょã†ã€‚
- RGB888 -> 2^24*4 -> 64MB (65536x65536程度ã®ç”»åƒã«ç›¸å½“ã™ã‚‹)
- RGB777 -> 2^21*4 -> 8MB (2896x2896程度ã®ç”»åƒã«ç›¸å½“ã™ã‚‹)
- RGB666 -> 2^18*4 -> 1MB (1024x1024程度ã®ç”»åƒã«ç›¸å½“ã™ã‚‹)
- RGB565 -> 2^16*4 -> 256KB (512x512程度ã®ç”»åƒã«ç›¸å½“ã™ã‚‹)
- RGB555 -> 2^15*4 -> 128KB (362x362程度ã®ç”»åƒã«ç›¸å½“ã™ã‚‹)
- RGB444 -> 2^12*4 -> 16KB (128x128程度ã®ç”»åƒã«ç›¸å½“ã™ã‚‹)
感覚的ã«RGB666程度ãªã‚‰ç²¾åº¦çš„ã«ã‚‚速度的ã«ã‚‚空間的ã«ã‚‚よã•ãã†ã§ã™ã。実際ã«è©¦ã—ã¦ã¿ãŸã¨ã“ã‚ã€æ‰‹å…ƒã®ãƒžã‚·ãƒ³ã§å‡¦ç†æ™‚é–“ã‚’30〜50ミリ秒程度ã‹ã‚‰10ミリ秒以下ã¾ã§å‰Šæ¸›ã§ãã¾ã—ãŸã€‚ã„ã„ã§ã™ã。ã—ã‹ã—ã€é«˜é€ŸåŒ–å‰ã¨çµæžœãŒç•°ãªã‚Šã¾ã™ã€‚高速化å‰ã®æ–¹ãŒç”»è³ªãŒã„ã„ã§ã™ã€‚ã“ã‚Œã¯é«˜é€ŸåŒ–+RGB888ã§ã‚„ã£ã¦ã‚‚高速化å‰ã®ç”»è³ªã«åŠ£ã‚Šã¾ã™ãƒ»ãƒ»ãƒ»ã€‚ã›ã£ã‹ãã®octreeãŒå°ç„¡ã—ã§æ®‹å¿µã§ã™ã。
é‡å化ループã®æœ€é©åŒ–ãã®ï¼’
ノードã‚ャッシュ
octreeã¯å‹•çš„ã«å…«åˆ†æœ¨ã®ãƒŽãƒ¼ãƒ‰ã«ä½¿ã†ãƒ¡ãƒ¢ãƒªã‚’確ä¿ãƒ»ç ´æ£„ã—ã¾ã™ã€‚確ã‹ã«ç©ºé–“çš„ãªåŠ¹çŽ‡ã¯ã„ã„ã§ã™ã€‚å˜ç™ºå‘¼ã³å‡ºã—ãªã‚‰ã€‚ãŸã ã—ã€ç¹°è¿”ã—呼ã³å‡ºã™ã¨ãƒ¡ãƒ¢ãƒªã®æ–片化ãŒèµ·ã“ã£ã¦OSã«ã‚ã¾ã‚Šå„ªã—ããªã„æ°—ãŒã—ã¾ã™ã€‚優ã—ããªã„ã®ã¯ç´³å£«çš„ã§ã¯ã‚ã‚Šã¾ã›ã‚“ã®ã§ã€å„ªã—ãã§ããªã„ã‹ã‚’考ãˆã¦ã¿ã¾ã—ょã†ã€‚å°ã•ã„メモリã®ç¢ºä¿ãƒ»ç ´æ£„ãŒé€£ç¶šã™ã‚‹ã¨æ–片化ãŒç™ºç”Ÿã—ã‚„ã™ã„ã§ã™ãŒã€ç¢ºä¿ãƒ»ç ´æ£„ãŒãªã‘ã‚Œã°æ–片化ã¯ç™ºç”Ÿã—ã¾ã›ã‚“。ノードをプールã—ã¦ãŠã‘ã°ã„ã„ã‚ã‘ã§ã™ã。ã§ã¯ã„ãã¤ãƒ—ールã—ã¦ãŠã‘ã°ã„ã„ã§ã—ょã†ã‹ï¼Ÿã“ã‚Œã¯å…«åˆ†æœ¨ã®æ·±ã•ã«ã‚ˆã‚Šã¾ã™ã€‚ãã‚Œãžã‚Œã®æ·±ã•ã®ãƒŽãƒ¼ãƒ‰ãŒã„ãã¤å˜åœ¨ã—ã†ã‚‹ã‹ã‚’考ãˆã¦ã¿ã¾ã—ょã†ã€‚
- 深㕠0 -> ノード数 1
- 深㕠1 -> ノード数 8
- 深㕠2 -> ノード数 64
- 深㕠3 -> ノード数 512
- 深㕠4 -> ノード数 4096 (4K)
- 深㕠5 -> ノード数 32768 (32K)
- 深㕠6 -> ノード数 262144 (256K)
- 深㕠7 -> ノード数 2097152 (2MB)
- 深㕠8 -> ノード数 16777216 (16MB)
上ã§æ·±ã•4〜5ã§å分ãªç”»è³ªãŒå¾—られるã¨æ›¸ã„ãŸã®ã§ã€æ·±ã•4ã¾ã§ã‚ャッシュã™ã‚‹ã“ã¨ã‚’考ãˆã¦ã¿ã¾ã—ょã†ã€‚æ·±ã•4ã¾ã§ã®ãƒŽãƒ¼ãƒ‰ã‚’連続ã—ãŸã‚¢ãƒ‰ãƒ¬ã‚¹ç©ºé–“ã«é…ç½®ã™ã‚‹ãŸã‚ã«ã€é †åºä»˜ã‘を考ãˆã¦ã¿ã¾ã—ょã†ã€‚例ãˆã°ã“ã‚“ãªæ„Ÿã˜ã§ã™ã€‚
- 深㕠0 -> 0
- 深㕠1 -> 1〜8 (1+n)
- 深㕠2 -> 9〜72 (1+(1+n)*8 = 1+8+8*n)
- 深㕠3 -> 73〜584 (1+8+(1+n)*64 = 1+8+64+64*n)
- 深㕠4 -> 585〜4680 (1+8+64+(1+n)*512 = 1+8+64+512+512*n)
ã“ã‚Œã§æ·±ã•ã«å¿œã˜ãŸé †åºä»˜ã‘ãŒã§ãã¾ã—ãŸã€‚ç°¡å˜ã§ã™ã。
パレットインデクス付ã®æœ€é©åŒ–
上記ã®å‡¦ç†ã§é«˜é€Ÿã«ãƒ‘レットãŒç”Ÿæˆã§ãるよã†ã«ãªã‚Šã¾ã—ãŸãŒã€å®Ÿéš›ã«æ¸›è‰²ã•ã‚ŒãŸç”»åƒã‚’å¾—ã‚‹ã«ã¯ç”Ÿæˆã—ãŸãƒ‘レットã¨ç”»åƒã‚’対応付ã‘ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ã“ã®ç”»ç´ ã¯ãƒ‘レットã§ã„ã†ã¨ã©ã®è‰²ã ã€ã¨ã„ã†å‡¦ç†ã§ã™ã。octreeã¯å…¨ã¦ã®ç”»ç´ を処ç†ã™ã‚‹ã¾ã§ãƒ‘レットãŒæ±ºå®šã•ã‚Œãªã„ã®ã§ã€åŠ¹çŽ‡çš„ãªé€†å¼•ããŒé›£ã—ã„ã®ã§ã™ã€‚何ã®å‰ææ¡ä»¶ã‚‚ãªã„å ´åˆã€è¿‘似色計算ã¯ç”»ç´ 毎ã«ãƒ‘レットã®å…¨ã‚¨ãƒ³ãƒˆãƒªã¨ã®è‰²ç©ºé–“ã®è·é›¢ã‚’調ã¹ã¦æœ€ã‚‚è·é›¢ãŒå°ã•ã„ã‚‚ã®ã‚’é¸æŠžã—ã¦ã„ãã¨ã„ã†å‡¦ç†ã«ãªã‚Šã¾ã™ã€‚計算é‡ã¯ãƒ‘レットã®ã‚¨ãƒ³ãƒˆãƒªæ•°ã‚’Pã¨ã™ã‚‹ã¨O(W*H*P)ã¨ãªã‚Šã¾ã™ã€‚ã¾ãŸãƒœã‚¯ã‚»ãƒ«å‡¦ç†ã¿ãŸã„ã«ãªã£ã¦ã¾ã™ã€‚ボクセル処ç†ã¯ç¦æ¢ã§ã™ã€‚感覚的ã«ã¯ã€ç”»ç´ ã‹ã‚‰ãƒãƒƒã‚·ãƒ¥çš„ã«ãƒ‘レットã®ã‚¤ãƒ³ãƒ‡ã‚¯ã‚¹ã‚’求ã‚ã‚‹ã“ã¨ãŒã§ãã‚Œã°é«˜é€Ÿã«å‡¦ç†ã§ããã†ãªæ°—ãŒã—ã¾ã™ã€‚
*1:http://d.hatena.ne.jp/izariuo440/20120320/1332212854
*2:ç§ãŒè©¦ã—ãŸé™ã‚Šã§ã¯ã€ã‚½ãƒ¼ãƒˆã ã‘ã§æœ€é©åŒ–å‰ã®octreeã®å‡¦ç†ã‚ˆã‚Šã‚‚時間ãŒã‹ã‹ã£ã¦ã—ã¾ã„ã¾ã—ãŸãŒã€ç”»ç´ æ•°ã«ã‚ˆã£ã¦ã¯ã‚½ãƒ¼ãƒˆã®æ–¹ãŒé€Ÿã„ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“