File size: 2,024 Bytes
3b01b55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from PIL import Image
from sklearn.cluster import KMeans
import numpy as np


# K-Means ้ขœ่‰ฒ้‡ๅŒ–
def kmeans_quantization(image, n_colors):
    img = image.convert("RGB")
    img_np = np.array(img)
    w, h, d = img_np.shape
    img_flat = img_np.reshape((w * h, d))
    kmeans = KMeans(n_clusters=n_colors, random_state=0).fit(img_flat)
    centroids = kmeans.cluster_centers_.astype(int)
    labels = kmeans.labels_
    quantized_img_flat = centroids[labels]
    quantized_img = quantized_img_flat.reshape((w, h, d))
    return Image.fromarray(np.uint8(quantized_img))


# Median Cut ้ขœ่‰ฒ้‡ๅŒ–
def median_cut_quantization(image, n_colors):
    quantized_img = image.convert("P", palette=Image.ADAPTIVE, colors=n_colors)
    return quantized_img.convert("RGB")


# Floyd-Steinberg Dithering
def floyd_steinberg_dithering(image, n_colors):
    quantized_img = image.convert("P", palette=Image.ADAPTIVE, colors=n_colors)
    return quantized_img.convert("RGB")


# Median Cut with Perceptual Weighting ้ขœ่‰ฒ้‡ๅŒ–
def median_cut_perceptual_weighting(image, n_colors):
    """

    ไฝฟ็”จๆ„Ÿ็ŸฅๅŠ ๆƒ็š„ Median Cut ้ขœ่‰ฒ้‡ๅŒ–ใ€‚



    ๅ‚ๆ•ฐ:

    - image: ่พ“ๅ…ฅ็š„ PIL ๅ›พๅƒๅฏน่ฑก

    - n_colors: ็›ฎๆ ‡้ขœ่‰ฒๆ•ฐ้‡



    ่ฟ”ๅ›ž:

    - ้‡ๅŒ–ๅŽ็š„ PIL ๅ›พๅƒๅฏน่ฑก

    """
    img = image.convert("RGB")

    # ๅฎšไน‰ RGB ้€š้“็š„ๆ„Ÿ็ŸฅๅŠ ๆƒ
    perceptual_weights = np.array([0.299, 0.587, 0.114])

    # ๅฐ†ๅ›พๅƒ่ฝฌไธบ numpy ๆ•ฐ็ป„
    img_np = np.array(img)

    # ่ฎก็ฎ—ๅŠ ๆƒๅŽ็š„้ขœ่‰ฒ่ท็ฆป
    weighted_img_np = img_np.astype(float)
    for i in range(3):  # ๅฏน R, G, B ้€š้“ๅˆ†ๅˆซๅŠ ๆƒ
        weighted_img_np[:, :, i] *= perceptual_weights[i]

    # ไฝฟ็”จ Pillow ็š„ Median Cut ็ฎ—ๆณ•่ฟ›่กŒๅŸบไบŽๅŠ ๆƒ็š„้ขœ่‰ฒ้‡ๅŒ–
    weighted_image = Image.fromarray(np.uint8(img_np))  # ไธๅฏนๅ›พๅƒๅƒ็ด ๅ€ผ่ฟ›่กŒๆ”นๅ˜
    quantized_img = weighted_image.convert("P", palette=Image.ADAPTIVE, colors=n_colors)

    return quantized_img.convert("RGB")