Python 提取图片主色调

Python 提取图片主色调

  • 效果
  • 代码编写

效果

有个要提取图片主色调的需求,记录一下。
获取图片中的主色调

代码编写

import numpy as np
import cv2
from sklearn.cluster import KMeans
from skimage.color import rgb2lab, deltaE_cie76
from collections import Counter


# 创建默认变量

# 这是用于确定背景的阈值
remove_background_threshold = 235
# 这是用于确定要提取的颜色数量的参数
extract_colors_num_colors = 8
# 这是用于确定两种颜色是否相似的阈值
is_similar_color_threshold = 30

def remove_background(image, threshold=remove_background_threshold):
    # Convert image to grayscale
    # 将图像转换为灰度图
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # Create a binary mask of the background
    # 创建一个背景的二值掩码
    _, mask = cv2.threshold(gray, threshold, 255, cv2.THRESH_BINARY_INV)
    # Apply the mask to the original image
    # 将掩码应用到原始图像上
    result = cv2.bitwise_and(image, image, mask=mask)
    return result

def get_color_name(lab):
    colors = {
        "red": [53.23, 80.11, 67.22],
        "green": [87.74, -86.18, 83.18],
        "blue": [32.30, 79.19, -107.86],
        "yellow": [97.14, -21.55, 94.48],
        "cyan": [91.11, -48.09, -14.13],
        "magenta": [60.32, 98.24, -60.83],
        "black": [0, 0, 0],
        "white": [100, 0.00, -0.01],
        "gray": [53.59, 0, 0],
        "orange": [67.79, 43.30, 74.93],
        "purple": [29.78, 58.94, -36.50],
        "brown": [38.91, 19.36, 22.29],
        "pink": [88.22, 17.75, 3.18],
        "dark red": [39.35, 62.75, 49.91],
        "light blue": [79.19, -11.03, -26.23],
        "dark green": [35.49, -46.47, 35.45],
        "light green": [88.72, -42.89, 57.40],
        "navy": [16.73, 37.09, -65.49],
        "burgundy": [28.71, 49.35, 26.27],
        "beige": [89.02, -1.39, 11.09],
        "olive": [51.87, -12.93, 56.67],
        "teal": [49.31, -28.83, -8.48],
        "maroon": [25.64, 45.52, 20.77],
        "forest green": [36.23, -37.96, 30.20],
    }
    
    min_dist = float('inf')
    closest_color = None
    for color_name, color_lab in colors.items():
        dist = np.sqrt(sum((lab - color_lab) ** 2))
        if dist < min_dist:
            min_dist = dist
            closest_color = color_name
    return closest_color

def is_similar_color(color1, color2, threshold=is_similar_color_threshold):
    lab1 = rgb2lab([[color1]])[0][0]
    lab2 = rgb2lab([[color2]])[0][0]
    diff = deltaE_cie76(lab1, lab2)
    return diff < threshold

def extract_colors(image_path, num_colors=extract_colors_num_colors):
    # Read image
    # 读取图像
    image = cv2.imread(image_path)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    # Remove background
    # 去除背景
    image_no_bg = remove_background(image)
    # Reshape image
    # 重塑图像
    pixels = image_no_bg.reshape(-1, 3)
    # Remove black pixels (background)
    # 删除黑色像素(背景)
    pixels = pixels[~np.all(pixels == [0, 0, 0], axis=1)]
    
    if len(pixels) == 0:
        return []  # Return empty list if all pixels were removed   返回空列表,如果所有像素都被删除
    
    # Perform k-means clustering
    # 执行k-means聚类
    kmeans = KMeans(n_clusters=num_colors, random_state=42, n_init=10)
    kmeans.fit(pixels)
    
    # Get the colors
    # 获取颜色
    colors = kmeans.cluster_centers_
    # Convert colors to LAB space
    # 将颜色转换为LAB空间
    colors_lab = rgb2lab(colors.reshape(1, -1, 3)).reshape(-1, 3)
    # Get color names
    # 获取颜色名称
    color_names = [get_color_name(color) for color in colors_lab]
    # Count pixels for each cluster
    # 计算每个聚类的像素数
    pixel_counts = Counter(kmeans.labels_)
    # Sort colors by frequency
    # 按频率对颜色进行排序
    sorted_colors = sorted(zip(color_names, colors, pixel_counts.values()), key=lambda x: x[2], reverse=True)
    # Remove similar colors
    # 删除相似颜色
    unique_colors = []
    for color_name, color_rgb, count in sorted_colors:
        if color_name not in [uc[0] for uc in unique_colors] and \
           not any(is_similar_color(color_rgb, existing_color) for _, existing_color, _ in unique_colors):
            unique_colors.append((color_name, color_rgb, count))
        if len(unique_colors) == 3:
            break
    
    return [color_name for color_name, _, _ in unique_colors]


# Example usage
image_path = r'D:\Project\Python_Project\yitiaolong\expimage_1.jpg'
main_colors = extract_colors(image_path)
print("Main colors:", main_colors)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/755569.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenAI禁止中国使用API,国内大模型市场何去何从

GPT-5 一年半后发布&#xff1f;对此你有何期待&#xff1f; 前言 前言&#xff1a; 近日&#xff0c;OpenAI宣布禁止中国用户使用其API&#xff0c;这一决策引起了国内大模型市场的广泛关注。面对这一挑战&#xff0c;国内大模型市场的发展路径和前景成为业界热议的焦点。本…

收银系统源码-千呼新零售【分销商城】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

C# 实现websocket双向通信

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C# &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff…

关于新零售的一些思考

本文作为2024上半年大量输入之后的核心思考之一。工作到一定阶段之后&#xff0c;思考的重要性越来越高&#xff0c;后续会把自己的个人思考记录在这个新系列《施展爱思考》。背景是上半年面临业务转型从电商到新零售&#xff0c;本文是相关大量输入之后的思考&#xff0c;对新…

还在用 Jenkins?快来试试这款简而轻的自动化部署工具吧!

文章目录 项目介绍功能特性效果展示逻辑节点仓库信息构建列表SSH 管理 安装使用一键安装命令管理 Jpom 服务端防火墙配置 相关地址总结 &#x1f389;欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#x…

Altium Designer的元件库 PCB库 3D库神器

元件库 PCB库 3D库神器 对于硬件工程师来说贸泽是一个器件选型相当方便的电子商城,虽然购买元器件比立创商城要慢和贵,但是,上面的物料种类、选型的便捷性要远远好于立创商城;而且,它上面的大多数元件都有自己的元件封装、PCB封装、3D模型,这就对实际的开发节省了好多绘…

LangChain E-Mails with LLM

题意&#xff1a;通过LangChain使用大型语言模型&#xff08;LLM&#xff09;处理电子邮件 问题背景&#xff1a; I am quite new to LangChain and Python as im mainly doing C# but i am interested in using AI on my own data. So i wrote some python code using langch…

springboot系列八: springboot静态资源访问,Rest风格请求处理, 接收参数相关注解

文章目录 WEB开发-静态资源访问官方文档基本介绍快速入门注意事项和细节 Rest风格请求处理基本介绍应用实例注意事项和细节思考题 接收参数相关注解基本介绍应用实例PathVariableRequestHeaderRequestParamCookieValueRequestBodyRequestAttributeSessionAttribute ⬅️ 上一篇…

智慧校园-医务管理系统总体概述

智慧校园医务管理系统&#xff0c;作为校园健康管理体系的智能化升级&#xff0c;深度融合信息技术与医疗服务&#xff0c;为师生构筑起一道全方位的健康守护网。医务管理系统以提升校园医疗服务水平、优化健康管理流程为核心目标&#xff0c;通过一系列创新功能&#xff0c;确…

SerDes介绍以及原语使用介绍(2)OSERDESE2原语仿真

文章目录 前言一、SDR模式1.1、设计代码1.2、testbench代码1.3、仿真分析 二、DDR模式下2.1、设计代码2.2、testbench代码2.3、仿真分析 三、OSERDES2级联3.1、设计代码3.2、testbench代码3.3、代码分析 前言 上文通过xilinx ug471手册对OSERDESE有了简单的了解&#xff0c;接…

Rabbit MQ安装详细记录

RabbitMQ是Erlang语言开发的&#xff0c;因此安装Erlang环境在进行安装RbbitMQ的操作&#xff0c;选择两者版本时一定要参考版本的兼容性。 查看RabbitMQ和Erlang版本对应关系&#xff1a;https://www.rabbitmq.com/which-erlang.html 一、下载地址 下载Erlang地址 : https:…

【RT摩拳擦掌】RT云端测试之百度天工物接入构建(设备型)

【RT摩拳擦掌】RT云端测试之百度天工物接入构建&#xff08;设备型&#xff09; 一&#xff0c; 文档介绍二&#xff0c; 物接入IOT Hub物影子构建2.1 创建设备型项目2.2 创建物模型2.3 创建物影子 三&#xff0c; MQTT fx客户端连接云端3.1 MQTT fx配置3.2 MQTT fx订阅3.3 MQT…

SpringBoot学习05-[SpringBoot的嵌入式Servlet容器]

SpringBoot的嵌入式Servlet容器 嵌入式Servlet容器servlet容器-嵌入式servlet容器配置修改通过全局配置文件修改修改添加实现了WebServerFactoryCustomizer接口的bean来进行修改 servlet容器-注册servlet三大组件 嵌入式Servlet容器 SpringBoot包含对嵌入式Tomcat、Jetty、Und…

Nvidia Jetson/RK3588+AI双目立体相机,适合各种割草机器人、扫地机器人、AGV等应用

双目立体视觉是基于视差原理&#xff0c;依据成像设备从不同位置获取的被测物体的图像&#xff0c;匹配对应点的位置偏移&#xff0c;得到视差数据&#xff0c;进而计算物体的空间三维信息。为您带来高图像质量的双目立体相机&#xff0c;具有高分辨率、低功耗、远距离等优点&a…

DIYGW UniApp低代码可视化平台:高效、灵活、安全的应用开发新途径

一、引言 在数字化快速发展的今天&#xff0c;企业对于快速构建多端应用的需求日益增长。然而&#xff0c;传统的应用开发方式往往面临周期长、成本高、技术门槛高等问题。为了解决这些问题&#xff0c;DIYGW UniApp低代码可视化平台应运而生&#xff0c;它以高效率、多端使用…

动态人物抠图换背景 MediaPipe

pip下载 MediaPipe pip install mediapipe -i 手部特征点模型包包含一个手掌检测模型和一个手部特征点检测模型。手掌检测模型在输入图片中定位手部&#xff0c;手部特征点检测模型可识别手掌检测模型定义的被剪裁手掌图片上的特定手部特征点。 由于运行手掌检测模型非常耗时&…

面试突击:HashMap 源码详解

本文已收录于&#xff1a;https://github.com/danmuking/all-in-one&#xff08;持续更新&#xff09; 数据结构 JDK1.8 之前 JDK1.8 之前 HashMap 采用 数组和链表 结合的数据结构。如下图&#xff1a; HashMap 将 key 的 hashCode 经过扰动函数处理过后得到 hash 值&#…

用C/C++写一个客户端和服务器之间进行TCP通信的DEMO

目录 一、Visual Sudio 2022 二、配置 三、说明 四、客户端 五、服务端 六、演示 一、Visual Sudio 2022 Visual Studio 2022是微软公司推出的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在为开发人员提供全面的工具集&#xff0c;支持从Windows到MacOS…

【算法专题--链表】两数相加 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐双指针 -- 模拟进位 (使用哨兵位头节点) &#x1f95d; 什么是哨兵位头节点&#xff1f; &#x1f347;思路解析 &#x1f34d;案例图解 四、总结与提炼 五、共勉 一、前言 两数相加 这道题&#xff0c;可以说是--…

Linux Swap

Swap: 页面换出&#xff1a;就是在 Swap 机制下&#xff0c;当内存资源紧张时&#xff0c;内核就会把不经常使用的这些匿名页中的数据写入到 Swap 分区或者 Swap 文件中。从而释放这些数据所占用的内存空间。 页面换入&#xff1a;就是当进程再次访问那些被换出的数据时&…