使用分割 Mask 和 K-means 聚类获取天空的颜色
引言
在计算机视觉领域,获取天空的颜色是一个常见任务,广泛应用于天气分析、环境感知和图像增强等场景。本篇博客将介绍如何通过已知的天空区域 Mask 提取天空像素,并使用 K-means 聚类分析天空颜色,最终根据颜色占比查表得到主导颜色。
一、流程概述
本文的流程分为以下几个步骤:
1. 使用分割 Mask 提取天空区域像素。
2. 通过 K-means 聚类对天空像素进行颜色聚类。
3. 统计每个聚类的面积占比,筛选面积占比超过 30% 的颜色。
4. 根据筛选结果查表获取对应的颜色名称。
接下来我们将详细讲解每个步骤。
二、提取天空区域像素
分割 Mask 是一个二值化的图像,其中 1 表示天空区域,0 表示非天空区域。通过 Mask,可以从原图中提取出天空区域的像素。
from typing import Tuple
import numpy as np
from PIL import Imagedef extract_sky_pixels(image_path: str, sky_mask: np.ndarray) -> np.ndarray:"""根据天空区域的 Mask 提取像素。:param image_path: 输入图像的路径。:param sky_mask: 天空区域的二值化 Mask,1 表示天空,0 表示非天空。:return: 天空区域的像素数组,形状为 (N, 3),每行表示一个像素的 [R, G, B] 值。"""image = Image.open(image_path).convert("RGB")image_np = np.array(image) # 转为 NumPy 数组return image_np[sky_mask == 1] # 仅保留天空区域的像素
三、K-means 聚类分析天空颜色
提取天空像素后,我们使用 K-means 聚类将颜色分为若干类(默认设定为 k=3),并统计每类颜色的面积占比。
以下是 K-means 聚类的代码实现:
from sklearn.cluster import KMeans
from typing import Tupledef kmeans_clustering(sky_pixels: np.ndarray, k: int = 3) -> Tuple[np.ndarray, np.ndarray]:"""使用 K-means 对天空像素聚类。:param sky_pixels: 天空区域的像素数组,形状为 (N, 3),每行表示 [R, G, B] 值。:param k: 聚类的数量,默认值为 3。:return: - cluster_centers: 每个聚类的中心颜色,形状为 (k, 3)。- area_ratios: 每个聚类的面积占比,形状为 (k,)。"""# 归一化像素值(0-1 范围)sky_pixels_normalized = sky_pixels / 255.0# 使用 K-means 聚类kmeans = KMeans(n_clusters=k, random_state=0).fit(sky_pixels_normalized)# 获取每个像素的聚类标签labels = kmeans.labels_# 每个聚类的中心颜色cluster_centers = kmeans.cluster_centers_ * 255.0# 统计每个聚类的像素数量label_counts = np.bincount(labels)# 计算每个聚类的面积占比area_ratios = label_counts / len(sky_pixels)return cluster_centers, area_ratios
四、筛选主导颜色并查表
我们关心面积占比超过 30% 的颜色,并通过查表将 RGB 值转换为对应的颜色名称。
以下是颜色查表和筛选的代码:
from typing import List, Tupledef rgb_to_color_name(rgb: np.ndarray) -> str:"""根据 RGB 值查表获取颜色名称。:param rgb: RGB 颜色值,形状为 (3,)。:return: 颜色名称。"""# 定义常见颜色的 RGB 值和名称color_table = {"Sky Blue": (135, 206, 235),"Deep Sky Blue": (0, 191, 255),"Light Blue": (173, 216, 230),"Azure": (240, 255, 255),"Navy": (0, 0, 128)}# 计算每个颜色的欧几里得距离min_dist = float('inf')color_name = "Unknown"for name, value in color_table.items():dist = np.linalg.norm(np.array(rgb) - np.array(value))if dist < min_dist:min_dist = distcolor_name = namereturn color_namedef filter_and_get_color_names(cluster_centers: np.ndarray, area_ratios: np.ndarray, threshold: float = 0.3
) -> List[Tuple[str, float]]:"""筛选面积占比超过阈值的颜色,并查表获取颜色名称。:param cluster_centers: 每个聚类的中心颜色,形状为 (k, 3)。:param area_ratios: 每个聚类的面积占比,形状为 (k,)。:param threshold: 面积占比的筛选阈值,默认为 0.3。:return: 主导颜色及其面积占比的列表,每个元素为 (颜色名称, 面积占比)。"""colors = []for center, ratio in zip(cluster_centers, area_ratios):if ratio > threshold:color_name = rgb_to_color_name(center)colors.append((color_name, ratio))return colors
五、完整代码示例
以下是完整的流程代码,实现从分割 Mask 提取天空颜色的过程:
from typing import List, Tuple
import numpy as npdef get_sky_colors(image_path: str, sky_mask: np.ndarray, k: int = 3, threshold: float = 0.3) -> List[Tuple[str, float]]:"""获取天空区域的主导颜色。:param image_path: 输入图像的路径。:param sky_mask: 天空区域的二值化 Mask,1 表示天空,0 表示非天空。:param k: 聚类的数量,默认值为 3。:param threshold: 面积占比的筛选阈值,默认为 0.3。:return: 主导颜色及其面积占比的列表,每个元素为 (颜色名称, 面积占比)。"""# Step 1: 提取天空像素sky_pixels = extract_sky_pixels(image_path, sky_mask)# Step 2: K-means 聚类cluster_centers, area_ratios = kmeans_clustering(sky_pixels, k)# Step 3: 筛选并查表获取颜色名称dominant_colors = filter_and_get_color_names(cluster_centers, area_ratios, threshold)return dominant_colors# 测试
if __name__ == "__main__":# 假设已知分割 Masksample_mask = np.load("sky_mask.npy") # 载入二值化 Maskimage_path = "example.jpg" # 输入图像路径sky_colors = get_sky_colors(image_path, sample_mask)print("天空颜色:", sky_colors)
六、总结
通过分割 Mask 和 K-means 聚类,我们可以高效提取天空区域的颜色特征,并获取主导颜色。这种方法简单易用,适合多种场景需求。
希望这篇博客能帮助你快速上手天空颜色提取的实现!如有疑问,欢迎在评论区交流!
相关文章:

使用分割 Mask 和 K-means 聚类获取天空的颜色
引言 在计算机视觉领域,获取天空的颜色是一个常见任务,广泛应用于天气分析、环境感知和图像增强等场景。本篇博客将介绍如何通过已知的天空区域 Mask 提取天空像素,并使用 K-means 聚类分析天空颜色,最终根据颜色占比查表得到主导…...

145.《redis原生超详细使用》
文章目录 什么是redisredis 安装启动redis数据类型redis key操作key 的增key 的查key 的改key 的删key 是否存在key 查看所有key 「设置」过期时间key 「查看」过期时间key 「移除」过期时间key 「查看」数据类型key 「匹配」符合条件的keykey 「移动」到其他数据库 redis数据类…...

Pytorch基础教程:从零实现手写数字分类
文章目录 1.Pytorch简介2.理解tensor2.1 一维矩阵2.2 二维矩阵2.3 三维矩阵 3.创建tensor3.1 你可以直接从一个Python列表或NumPy数组创建一个tensor:3.2 创建特定形状的tensor3.3 创建三维tensor3.4 使用随机数填充tensor3.5 指定tensor的数据类型 4.tensor基本运算…...

【SH】Xiaomi9刷Windows10系统研发记录 、手机刷Windows系统教程、小米9重装win10系统
文章目录 参考资料云盘资料软硬件环境手机解锁刷机驱动绑定账号和设备解锁手机 Mindows工具箱安装工具箱和修复下载下载安卓和woa资源包第三方Recovery 一键安装Windows准备工作创建分区安装系统 效果展示Windows和Android一键互换Win切换安卓安卓切换Win 删除分区 参考资料 解…...

excel仅复制可见单元格,仅复制筛选后内容
背景 我们经常需要将内容分给不同的人,做完后需要合并 遇到情况如下 那是因为直接选择了整列,当然不可以了。 下面提供几种方法,应该都可以 直接选中要复制区域然后复制,不要选中最上面的列alt;选中可见单元格正常复制ÿ…...

HBASE学习(一)
1.HBASE基础架构, 1.1 参考: HBase集群架构与读写优化:理解核心机制与性能提升-CSDN博客 1.2问题: 1.FLUSH对hbase的影响 2. HLog和memstore的区别 hlog中存储的是操作记录,比如写、删除。而memstor中存储的是写入…...

element select 绑定一个对象{}
背景: select组件的使用,适用广泛的基础单选 v-model 的值为当前被选中的 el-option 的 value 属性值。但是我们这里想绑定一个对象,一个el-option对应的对象。 <el-select v-model"state.form.modelA" …...

Sprint Boot教程之五十八:动态启动/停止 Kafka 监听器
Spring Boot – 动态启动/停止 Kafka 监听器 当 Spring Boot 应用程序启动时,Kafka Listener 的默认行为是开始监听某个主题。但是,有些情况下我们不想在应用程序启动后立即启动它。 要动态启动或停止 Kafka Listener,我们需要三种主要方法…...

C:JSON-C简介
介绍 JSON-C是一个用于处理JSON格式数据的C语言库,提供了一系列操作JSON数据的函数。 一、json参数类型 typedef enum json_type { json_type_null, json_type_boolean, json_type_double, json_type_int, json_type_object, json_type_ar…...

业务幂等性技术架构体系之消息幂等深入剖析
在系统中当使用消息队列时,无论做哪种技术选型,有很多问题是无论如何也不能忽视的,如:消息必达、消息幂等等。本文以典型的RabbitMQ为例,讲解如何保证消息幂等的可实施解决方案,其他MQ选型均可参考。 一、…...

【Go】Go Gin框架初识(一)
1. 什么是Gin框架 Gin框架:是一个由 Golang 语言开发的 web 框架,能够极大提高开发 web 应用的效率! 1.1 什么是web框架 web框架体系图(前后端不分离)如下图所示: 从上图中我们可以发现一个Web框架最重要…...

2024年合肥市科普日小学组市赛第一题题解
9304:数字加密(encrypt)(1) 【问题描述】 在信息科技课堂上,小肥正在思考“数字加密”实验项目。项目需要加密n个正整数,对每一个正整数x加密的规则是,将x的每一位数字都替换为x的最大数字。例如࿰…...

【MySQL实战】mysql_exporter+Prometheus+Grafana
要在Prometheus和Grafana中监控MySQL数据库,如下图: 可以使用mysql_exporter。 以下是一些步骤来设置和配置这个监控环境: 1. 安装和配置Prometheus: - 下载和安装Prometheus。 - 在prometheus.yml中配置MySQL通过添加以下内…...

Wireshark 使用教程:网络分析从入门到精通
一、引言 在网络技术的广阔领域中,网络协议分析是一项至关重要的技能。Wireshark 作为一款开源且功能强大的网络协议分析工具,被广泛应用于网络故障排查、网络安全检测以及网络协议研究等诸多方面。本文将深入且详细地介绍 Wireshark 的使用方法&#x…...

如何在前端给视频进行去除绿幕并替换背景?-----Vue3!!
最近在做这个这项目奇店桶装水小程序V1.3.9安装包骑手端V2.0.1小程序前端 最近,我在进行前端开发时,遇到了一个难题“如何给前端的视频进行去除绿幕并替换背景”。这是一个“数字人项目”所需,我一直在冥思苦想。终于有了一个解决方法…...

使用中间件自动化部署java应用
为了实现你在 IntelliJ IDEA 中打包项目并通过工具推送到两个 Docker 服务器(172.168.0.1 和 172.168.0.12),并在推送后自动或手动重启容器,我们可以按照以下步骤进行操作: 在 IntelliJ IDEA 中配置 Maven 或 Gradle 打…...

pytorch张量分块投影示例代码
张量的投影操作 背景 张量投影 是深度学习中常见的操作,将输入张量通过线性变换映射到另一个空间。例如: Y=W⋅X+b 其中: X: 输入张量(形状可能为 (B,M,K),即批量维度、序列维度、特征维度)。W: 权重矩阵((K,N),将 K 维投影到 N 维)。b: 偏置向量(可选,(N,))。Y:…...

Visual Studio 同一解决方案 同时运行 多个项目
方案一 方案二...

VMware中Ubuntu如何连接网络?安排!
一、设置NAT模式 1、关闭Ubuntu虚拟机: 确保Ubuntu已经完全关机,而不是挂起或休眠状态。 2、编辑虚拟网络设置: 在VMware主界面点击“编辑”菜单,选择“虚拟网络编辑器”。 如果需要,选择VMnet8 (NAT模式)并点击“更改…...

使用 Charles 调试 Flutter 应用中的 Dio 网络请求
为了成功使用 Charles 抓取并调试 Flutter 应用程序通过 Dio 发起的网络请求,需遵循特定配置步骤来确保应用程序能够识别 Charles 的 SSL 证书,并正确设置代理服务器。 配置 Charles 以支持 HTTPS 请求捕获 Charles 默认会拦截 HTTP 流量;…...

CMD批处理命令入门(6)——常用的特殊字符
CMD批处理命令入门(6)——特殊字符 本章内容主要学习要点:重定向符 >、>>命令管道符 |组合命令 &、&&、||转义字符 ^变量引导符 %界定符 "" 本章内容主要学习要点: >、>>重定向符| 命令…...

【跟着官网学技术系列之MySQL】第7天之创建和使用数据库1
前言 在当今信息爆炸的时代,拥有信息检索的能力很重要。 作为一名软件工程师,遇到问题,你会怎么办?带着问题去搜索引擎寻找答案?亦或是去技术官网,技术社区去寻找? 根据个人经验,一…...

next-auth v5 结合 Prisma 实现登录与会话管理
1. 安装依赖 npm install next-auth prisma prisma/client2. 配置 Prisma 模型 在 prisma/schema.prisma 文件中定义 User 和 Account 模型(next-auth v5 推荐使用自定义模型)。 model User {id String id default(uuid())email …...

WPS excel使用宏编辑器合并 Sheet工作表
使用excel自带的工具合并Sheet表,我们会发现需要开通WPS会员才能使用合并功能; 那么WPS excel如何使用宏编辑器进行合并 Sheet表呢? 1、首先我们要看excel后缀是 .xlsx 还是 .xls ;如果是.xlsx 那么 我们需要修改为 .xls 注…...

(即插即用模块-Attention部分) 四十四、(ICIP 2022) HWA 半小波注意力
文章目录 1、Half Wavelet Attention2、代码实现 paper:HALFWAVELET ATTENTION ON M-NET FOR LOW-LIGHT IMAGE ENHANCEMENT Code:https://github.com/FanChiMao/HWMNet 1、Half Wavelet Attention 传统的图像增强方法主要关注图像在空间域的特征信息&am…...

Linux第二课:LinuxC高级 学习记录day04
6、shell中的语句 6.3、结构性语句 6.3.1、if if…then…fi 1、结构 1)基本结构 if 表达式 then 命令表 fi if [ 表达式 ] // 【】两侧有空格 then 命令表 fi 2)分层结构 if 表达式 then 命令表1 else 命令表2 fi 3)嵌套结构 if …...

occ的开发框架
occ的开发框架 1.Introduction This manual explains how to use the Open CASCADE Application Framework (OCAF). It provides basic documentation on using OCAF. 2.Purpose of OCAF OCAF (the Open CASCADE Application Framework) is an easy-to-use platform for ra…...

Redis 如何解决大 key 问题
前言 嗨👋,大家好,我是雪荷。做为一个后端开发,Redis 是我们经常接触到的一个非关系行数据库。其对我们系统开发和优化有着举足轻重的作用,但是随着业务和用户迅速增长,也会滋生许多的问题,而大…...

驱动开发系列33 - Linux Graphics mesa Intel驱动介绍
一:概述 mesa 中的 Intel 驱动体系是为支持 Intel GPU 提供图形 API 的硬件实现部分,主要包括 OpenGL、Vulkan等图形接口,Intel驱动实现整体上分为四层: 第一层:API 层, 实现 OpenGL 和 Vulkan 接口, src/mesa/main、src/vulkan。 第二层:驱动层,实现 OpenGL 和 Vulkan…...

【华为OD-E卷 - 整数编码 100分(python、java、c++、js、c)】
【华为OD-E卷 - 整数编码 100分(python、java、c、js、c)】 题目 实现一种整数编码方法,使得待编码的数字越小,编码后所占用的字节数越小。 编码规则如下: 编码时7位一组,每个字节的低7位用于存储待编码数字的补码 字…...