Saya mencoba membuat modul yang dapat mengekstrak warna dominan dari suatu gambar. Misalnya, saya mencoba mengekstrak empat warna dari gambar bendera ini:

enter image description here

Metode getpalette dan getcolors mengembalikan None, jika saya mencoba menggunakannya dalam mode RGB. (Saya sudah mencoba menyetel maxcolors, saya masih mendapatkan None.)

paletted = img.convert('RGB', palette=Image.ADAPTIVE, colors=4)
print(paletted.getpalette())
print(paletted.getcolors(maxcolors=256))
# None
# None

Jika saya mengonversi ke mode P, saya dapat menggunakan modul ini, tetapi saya kehilangan warna kuning.

paletted = img.convert('P', palette=Image.ADAPTIVE, colors=4)
paletted.show()

enter image description here

Apa yang saya lakukan salah di sini?

0
CJ H 10 Mei 2021, 20:44

1 menjawab

Jawaban Terbaik

Pertama-tama, berikut ini tidak berfungsi, atau lebih tepatnya, diabaikan begitu saja:

paletted = img.convert('RGB', palette=Image.ADAPTIVE, colors=4)

Dari dokumentasi di Image.convert< /a>:

palet – Palet yang akan digunakan saat mengonversi dari mode "RGB" ke "P". Palet yang tersedia adalah WEB atau ADAPTIVE.

Anda mengonversi dari RGB ke RGB, sehingga parameter palette dan colors diabaikan.

Masalah berikutnya, yang juga mencegah konversi yang tepat ke mode P: Anda memiliki gambar JPG dengan artefak JPG. Gambar Anda mengandung lebih banyak warna daripada yang Anda harapkan. Dari dokumentasi di Image.getcolors< /a>:

maxcolors – Jumlah warna maksimum. Jika angka ini terlampaui, metode ini mengembalikan Tidak Ada. Batas default adalah 256 warna.

Tingkatkan maxcolors (kemungkinan jumlah maksimum warna berbeda untuk beberapa gambar RGB 24 bit penuh adalah 224), dan periksa empat warna yang paling menonjol:

from PIL import Image

img = Image.open('47ckF.jpg')
n_dom_colors = 4
dom_colors = sorted(img.getcolors(2 ** 24), reverse=True)[:n_dom_colors]
print(dom_colors)
# [(135779, (0, 0, 0)), (132476, (0, 0, 254)), (109155, (254, 0, 0)), (2892, (251, 2, 0))]

Anda mendapatkan hitam pekat, biru hampir solid, merah hampir solid, dan varian merah. Mana kuning? Artefak JPG! Anda memiliki banyak warna hitam-ish, biru-ish, dan merah-ish, yang semuanya lebih menonjol daripada warna kuning-ish pertama. Misalnya, bahkan pengaturan n_dom_colors = 20 tidak akan menunjukkan warna kuning-ish pertama.

Bagaimana mencapainya, apa yang mungkin ada dalam pikiran Anda? Lihat Image.quantize< /a>, yang akan memberi Anda gambar mode P menggunakan kuantisasi warna:

from PIL import Image

img = Image.open('47ckF.jpg')
img = img.quantize(colors=4, kmeans=4).convert('RGB')
n_dom_colors = 4
dom_colors = sorted(img.getcolors(2 ** 24), reverse=True)[:n_dom_colors]
print(dom_colors)
# [(139872, (1, 0, 1)), (138350, (0, 0, 253)), (134957, (252, 1, 1)), (3321, (253, 240, 12))]

Anda mendapatkan warna hitam hampir pekat, biru hampir pekat, merah hampir pekat, dan varian kuning!

Untuk referensi, gambar yang dikuantisasi dan dikonversi ulang:

Quantized

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
PyCharm:       2021.1.1
Pillow:        8.2.0
----------------------------------------
1
HansHirse 10 Mei 2021, 19:37