Python获取照片主色调

该代码实现从图像中找出主导颜色,通过KMeans聚类算法确定主要颜色。首先,对图像进行预处理,然后使用KMeans进行颜色聚类,并按像素数量排序。最后,从四个角落提取颜色,选择出现频率最高的颜色作为主导颜色。返回值可以是RGB或ARGB格式的整数或十六进制颜色代码。
摘要由CSDN通过智能技术生成

代码备份

import sys
from optparse import OptionParser 
import PIL
from PIL import Image
# import cv2
# import numpy as np
# from sklearn.cluster import KMeans
# from collections import Counter

def getMaxColor(img):
    # 计算5种主要颜色
    kmeans = KMeans(n_clusters=2)
    # 聚类目标图像
    flat_bg = np.array(img)
    # img.reshape(-1, 3)
    # for a in flat_bg:
    #     print(a)
    k_cluster = kmeans.fit(flat_bg)

    # b, g, r, a = cv2.split(img) 
    # print('A:', np.max(a))

    # 根据像素点个数对聚类结果排序
    n_pixels = len(k_cluster.labels_)
    counter = Counter(k_cluster.labels_)  # count how many pixels per cluster
    # Counter({0: 2598, 2: 633, 1: 513, 3: 243, 4: 109}) 第几种颜色有几个
    # print('A:', n_pixels, counter)

    perc = {}
    for i in counter:
        perc[i] = np.round(counter[i] / n_pixels, 2)
    perc = dict(sorted(perc.items()))
    sorted_index = sorted(perc, key=perc.get, reverse=True)
    # max_index = max(perc, key=perc.get, reverse=True)
    max_color_bgr = k_cluster.cluster_centers_[sorted_index[0]]
   
    # print(k_cluster.cluster_centers_)
    print('max value:', max_color_bgr)
    # return max_color_bgr

def getMaxColorFromPIL(img):
    colors = img.getcolors(pilImg.size[0] * pilImg.size[1])
    # print(colors)
    maxColorCount = 0
    maxColorValue = ()
    maxColorValue2 = ()
    if(len(colors) > 0):
        for color in colors:
            if (color[0] > maxColorCount):
                maxColorCount = color[0]
                maxColorValue2 = maxColorValue
                maxColorValue = color[1]

        # print(maxColorCount, maxColorValue)
        return (maxColorCount, maxColorValue)
    else:
        print('Can not fetch color in the image.')
        sys.exit(1)

def convertIntToHex(intColor, type):
    r = intColor[0]
    g = intColor[1]
    b = intColor[2]
    a = intColor[3]

    if('rgb' == type):
        return '#' + '{0:02x}'.format(r, 'x') + '{0:02x}'.format(g, 'x') + '{0:02x}'.format(b, 'x')

    return '#' + '{0:02x}'.format(a, 'x') + '{0:02x}'.format(r, 'x') + '{0:02x}'.format(g, 'x') + '{0:02x}'.format(b, 'x')

if __name__ == "__main__":
    parser = OptionParser()

    parser.add_option("-t", "--type", dest="type",  
                  help="Return value type.", metavar="argb|rgb|int")  
    parser.add_option("-d", "--debug", action="store_true", dest="debug", 
                  default=False, 
                  help="Display dominant color in palette.")  

    (options, args) = parser.parse_args()  

    is_debug = options.debug
    return_type = options.type
    img_path = args[0]
    # print(options, args)

    # K值聚类的方法无法计算透明度,且存在颜色偏移,聚类中心不准的问题
    # print('Input img Path:', img_path)
    # # 获取三色通道,不要用四色,alpha通道会导致k均值计算中心点错误
    # img = cv2.imread(img_path)
    # # 统一大小
    # resize = cv2.resize(img, (200, 200), interpolation=cv2.INTER_NEAREST)
    # rgb = cv2.cvtColor(resize, cv2.COLOR_BGR2RGB)
    # # 挖空中心
    # bg_arr = []
    # h, w, c = rgb.shape

    # s = 0
    # for i in range(h):
    #     for j in range(w):
    #         s = s + 1
    #         if (i > h / 3) and (i < 2 * h / 3) and (j > w / 3) and (j < 2 * w / 3):
    #             pass
    #         else:
    #             bg_arr.append(rgb[i, j])
    # print(len(bg_arr))    

    # im2 = rgb[0:100, 0:100]
    # rgb[::, 100:100:100] = np.NaN

    # print(rgb.shape)

    # print('Img shape', img, img.shape)
    # print(len(bg_arr), rgb.shape)
    # getMaxColor(bg_arr)

    # cv2.imshow('output', im2)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

    try:
        pilImg = Image.open(img_path).convert('RGBA').resize((200, 200))
        width, height = pilImg.size
        top = pilImg.crop((width / 3, 0, width * 2 / 3, height / 5))
        bottom = pilImg.crop((width / 3, height * 4 / 5, width * 2 / 3, height))
        left = pilImg.crop((0, height / 3, width / 5, height * 2 / 3))
        right = pilImg.crop((width * 4 / 5, height / 3, width, height * 2 / 3))

        topMaxColor = getMaxColorFromPIL(top)
        bottomMaxColor = getMaxColorFromPIL(bottom)
        leftMaxColor = getMaxColorFromPIL(left)
        rightMaxColor = getMaxColorFromPIL(right)

        maxColor = (0, ())
        if(topMaxColor[0] > maxColor[0]):
            maxColor = topMaxColor
        
        if(bottomMaxColor[0] > maxColor[0]):
            maxColor = bottomMaxColor
        
        if(leftMaxColor[0] > maxColor[0]):
            maxColor = leftMaxColor
        
        if(rightMaxColor[0] > maxColor[0]):
            maxColor = rightMaxColor
        
        # print(maxColor[1])

        if "int" == return_type:
            print(maxColor[1][0], maxColor[1][1], maxColor[1][2])
        else:
            print(convertIntToHex(maxColor[1], return_type))
        
        if is_debug:
            colorImg = Image.new('RGBA', pilImg.size, maxColor[1])
            colorImg.show()
        # p.paste(im, (0, 0, 200, 200), im)
        # p.save('jb51.net.png')

        # pilImg.show()
        # print('colors:', colors)
        # [(45, (230, 64, 114, 223)), 
    except PIL.UnidentifiedImageError:
        print('Input file type error...')
        sys.exit(0)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值