質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

8383閲覧

インデックスカラーのカラーパレットの編集

rk2

総合スコア11

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

1クリップ

投稿2019/05/02 02:00

編集2019/05/02 02:09

現在,パイソンで画像に関するプログラミングを行っています.
プログラミングはほぼ初心者です.

開発環境は,windows10,VScode,Python,です

行いたい事は,
「読み込んだインデックスカラー画像のカラーパレットの順番を任意の順番に変更し,カラーパレットの数を任意の数に変更する,変更したパレットを適用する.」です.

例:
カラーパレットの2番目と15番目の順番を入れ替える

カラーパレットの数を256から3に変更する

変更したカラーパレットを適用す

現在,読み込んだインデックスカラーのカラーパレットの確認は出来ています.
以下にコードを記載します.

順番の入れ替えやパレットの数の変更は全く分からない状況です.

python

1 img = Image.open(r"C:\Users\index.png") 2 #インデックスカラーに変換 3 img = img.convert("P") 4 5 # カラーパレットにアクセスする。 6 palette = img.getpalette() 7 # リストの値は index=0 から順番に [R, G, B, R, G, B, ...] 8 palette = np.array(palette).reshape(-1, 3) 9 #print(palette) # (256, 3) 10 11 # 256個のうち、0~50 だけ表示 12 fig, ax_list = plt.subplots(50, 1, figsize=(10, 100)) 13 for i, color in enumerate(palette[:50]): 14 color_img = np.full((1, 4, 3), color, dtype=np.uint8) 15 ax_list[i].set_axis_off() 16 ax_list[i].text(-1, 0, i, va='center', ha='right', fontsize=10) 17 ax_list[i].imshow(color_img, aspect='auto') 18 plt.show()

どなたか,分かる方いらっしゃいましたら,ご教授願います.

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2019/05/02 02:03

現状できているところまでのソースコードの提示をお願いします。
rk2

2019/05/02 02:10

記載いたしました. 宜しくお願い致します.
guest

回答1

0

ベストアンサー

8bitカラーのBMP画像のカラーパレット操作(python PIL)。の手法でできそうです。
コードにすると以下のような感じになるでしょうか。

Python

1 2from PIL import Image 3import matplotlib.pyplot as plt 4import numpy as np 5 6img = Image.open(r"lena.png") # http://optipng.sourceforge.net/pngtech/img/lena.html 7#インデックスカラーに変換 8img = img.convert("P") 9 10# カラーパレットにアクセスする。 11palette = img.getpalette() 12 13# リストの値は index=0 から順番に [R, G, B, R, G, B, ...] 14palette = np.array(palette).reshape(-1, 3) 15 16# 入れ替え 17tmp = palette[2] 18palette[2] = palette[15] 19palette[15] = tmp 20 21# パレット数の変更 22N_COLOR = len(palette)-100 # 適当な数に減らす 23palette = palette[:N_COLOR] 24 25# パレットの更新 26palette = palette.reshape(-1).tolist() 27img.putpalette(palette) 28 29# 実データの更新 30data = list(img.getdata()) 31# この処理はやりたいことに従ってご自身で実装ください。 32for i,v in enumerate(data): 33 if v >= N_COLOR: 34 data[i] = N_COLOR-1 # とりあえず末尾の番号に振る? 35 36img.putdata(data) 37img.save('ret.png')

イメージ説明

投稿2019/05/02 02:59

編集2019/05/02 08:34
can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rk2

2019/05/02 05:51

ご回答有難うございます. ご回答いただいたコードで試したところ,カラーパレットの変更はできました. 有難うございます. しかし,変更したカラーパレットをimg.putpaletteで設定したところ画像の色情報が失われてしましました. これは先ほど書いていただいた実データの更新の繰り返し分の箇所で何か処理を実装しなければいけなかった,ということでしょうか? ```python img = Image.open(r"C:\Users\index.png") #インデックスカラーに変換 img = img.convert("P") # カラーパレットにアクセスする。 palette = img.getpalette() # リストの値は index=0 から順番に [R, G, B, R, G, B, ...] palette = np.array(palette).reshape(-1, 3) #カラーパレットの入れ替え #2番目のパレット[1]に[255, 0, 0] クラス:糸 を設定 tmp = palette[1] palette[1] = palette[15] palette[15] = tmp # パレット数の変更 N_COLOR = len(palette) - 253 # 適当な数に減らす palette = palette[:N_COLOR] img.putpalette(palette) print(palette) # (256, 3) # 実データの更新 data = list(img.getdata()) img.putdata(data) img.save('ret.png') #表示 img.show() ```
can110

2019/05/02 05:57

たとえば以前バレット番号が123番だったピクセルなら0~2番に置き換える必要があると思います。 また、たとえ置き換えたとしても256色あったものを一気に3色にしたわけですから、ほぼ色情報は失われると考えられます。
rk2

2019/05/02 07:24

>>たとえば以前バレット番号が123番だったピクセルなら0~2番に置き換える必要があると思います。 この部分の処理はimg.putpalette(palette)の後に実装するのでしょうか? また,もしよろしければ,コードも教えて頂けましたら幸いです.
can110

2019/05/02 07:29

回答コードの「実データの更新」部分になります。 とりあえず末尾のパレット番号を割り当てています。
rk2

2019/05/02 08:13

実データの更新の部分も実装してみたのですがやはり,緑や赤色が消えて全体的に黒っぽい画像になってしまいました. 今回使っている元画像自体はrgbで,黒[0,0,0],赤[255,0,0],緑[0,255,0]の3色のみですので,上手くいけば,インデックス番号のみ入れ替わり,色情報は保持されると考えたのですが,考え方が何か間違っていたのでしょうか?
can110

2019/05/02 08:37

まず、回答コードを修正しました。 - パレット配列、RGBバラバラに扱っていた誤りを修正(RGBの組で操作するように) - lena.pngに適用するように。その結果画像も追加。
can110

2019/05/02 08:40

> 実データの更新の部分も実装してみたのですが~ 実際の画像データが分からないので何とも云えませんが… GIMPなどの画像編集ツールで、処理前後のパレット情報が意図通りに更新されているか確認してみてはいかがでしょうか?
rk2

2019/05/02 09:02

palette = palette.reshape(-1).tolist()を入れたらしかっりと色の方法も保持されました. パレットの更新をした後にputpalette(palette)する際に,リストの形に変形し直すことが必要だったのですね. 丁寧に教えて頂き有難うございました.
can110

2019/05/02 09:04

当初のコードにミスがあり失礼しました。解決してよかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問