60423


RGB形式の画像があります。  
この画像は高さ900、横900ピクセルとします。  
画像には80色あります。900＊900=810000ピクセルの画像ですので、80色しかありませんので、1個以上のピクセルが同じ色です。  
このように複数のピクセルが同じ色の場合にその色の「代表ピクセル」を選びたいです。但し、選ばれた「代表ピクセル」とその周りの変色度はその他の同じ色のピクセルとその周りの変色度より低く（最も低い）なければなりません。例えば、赤のピクセル[255,0,0]を選ぶ場合には周りの８ピクセルがオール[255,0,0]の物と周りが白「255,255,255]がありましたら、周りとの変色度が比較的低い周りが赤の物を選びます。この場合の変色度は[255,0,0]
- [255,0,0] = [0,0,0]ですのでゼロです。`np.sum(np.abs(diff))`的に変色度を計算して問題ありません。  
その次の条件として、80色ありますが、選ばれた80個がなるべく画像内で散らばっているように選びたいです。一箇所、何箇所かに固まっていないようにしたいです。


CC BY-SA 4.0
2019-10-25T08:16:38.883
59969
2019-11-11T19:34:54.497
2019-11-11T05:38:56.233
29239
29239
question
python opencv numpy scipy
Pythonにて「色の代表」ピクセルを選択するアルゴリズムを知りたいです


> np.sum(np.abs(diff))的に変色度を計算して問題ありません

あるピクセルと周囲のピクセル(`surr`)の RGB
値の差分(絶対値)の総計を計算しています。実際には画像の端(edge)や角(corner)にあるピクセルの場合、周囲にあるピクセル数が 3 や 5
になるので、差分の総計値をそのピクセル数で割っています。

以下のコードでは [Pillow](https://pypi.org/project/Pillow/) ライブラリを利用しています。

[code]

    from PIL import Image
    import numpy as np
    
    im = Image.open('test.png').convert('RGB')
    w, h = im.size
    surr = [
      (-1, -1), (0, -1), (1, -1),
      (-1,  0),          (1,  0),
      (-1,  1), (0,  1), (1,  1),
    ]
    
    pixel = np.reshape(np.array(im.getdata()), (h, w, 3))
    typical = {}
    for y in range(h):
      for x in range(w):
        (r0, g0, b0) = pixel[y, x]
        p_surr = [
          pixel[y+dy, x+dx] for (dx, dy) in surr
          if 0 <= x+dx < w and 0 <= y+dy < h
        ]
        d = sum(
          [abs(r-r0) + abs(g-g0) + abs(b-b0) for (r, g, b) in p_surr]
        ) / len(p_surr)
    
        if (r0, g0, b0) not in typical or d < typical[(r0, g0, b0)][0]:
          typical[(r0, g0, b0)] = (d, x, y)
    
    im = Image.new('RGB', (w, h), (0, 0, 0, 255))
    for k, (_, x, y) in typical.items():
      print("({:3}, {:3}, {:3}): ({:3}, {:3})".format(k[0], k[1], k[2], x, y))
      im.putpixel((x, y), k) 
    im.save('typical_pixels.png')
    
[/code]

以下、左は適当に作成した80色の画像(サイズは300x300)で、右は処理結果です(`typical_pixels.png`)。

[![元画像](https://i.stack.imgur.com/WzDhD.png)](https://i.stack.imgur.com/WzDhD.png)
[![typical
pixels](https://i.stack.imgur.com/C3baG.png)](https://i.stack.imgur.com/C3baG.png)

>
> その次の条件として、80色ありますが、選ばれた80個がなるべく画像内で散らばっているように選びたいです。一箇所、何箇所かに固まっていないようにしたいです。

「散らばっている」とか「一箇所、何箇所かに固まっていない」などという表現だけでは判断ができませんので、何らかの数量的な指標が必要です。


CC BY-SA 4.0
2019-11-11T19:34:54.497
60423
2019-11-11T19:34:54.497
59969
answer