当前位置: 首页 > news >正文

云图-地基云图

云图-地基云图

  • 地基云图介绍
  • 云图预处理
    • 云图障碍物清除
    • 云图圆心及边界处理
    • 云图色度增强
    • 云图太阳位置
  • 云图云层识别
    • 云层识别方法
  • 云团矢量外推

地基云图介绍

云图预处理

云图障碍物清除

  • 手动标记障碍物掩码
import cv2
import numpy as np
# ===== 初始化数据 =====
img = cv2.imread(img_path)
if img is None:raise FileNotFoundError(f"无法读取文件 {img_path}")
fixed_window_size = (1000, 1000)  # 窗口大小为800x600
img = cv2.resize(img, fixed_window_size)
clone = img.copy()  # 原图备份
mask = np.zeros(img.shape[:2], dtype=np.uint8)  # 单通道掩码
points = []  # 存储多边形点# 鼠标回调:点击添加点
def click_event(event, x, y, flags, param):global points, imgif event == cv2.EVENT_LBUTTONDOWN:points.append((x, y))# 在图上画一个小圆点标记点击位置cv2.circle(img, (x, y), 3, (0, 0, 255), -1)# 如果有两个及以上的点,就画折线if len(points) > 1:cv2.line(img, points[-2], points[-1], (0, 255, 0), 1)# 右键:闭合多边形elif event == cv2.EVENT_RBUTTONDOWN:if len(points) > 2:cv2.polylines(img, [np.array(points)], True, (255, 0, 0), 1)cv2.fillPoly(mask, [np.array(points)], 255)points.clear()# 创建窗口
cv2.namedWindow('image')
cv2.setMouseCallback('image', click_event)print("操作说明:\n""  左键点击:添加多边形顶点\n""  右键:闭合多边形并填充掩码\n""  R 键:重置所有标注\n""  S 键:保存掩码并退出\n""  Esc 键:退出不保存\n")while True:cv2.imshow('image', img)# cv2.imshow('mask', mask)key = cv2.waitKey(1) & 0xFFif key == ord('r'):img = clone.copy()mask[:] = 0points.clear()print("标注已重置。")elif key == ord('s'):cv2.imwrite(mask_save_path, mask)print(f"掩码已保存到 {mask_save_path}")breakelif key == 27:  # ESCbreakcv2.destroyAllWindows()

云图圆心及边界处理

  • 使用行列扫描法
def CloudCircularBboundary(img, T=40):"""云图半径圆心坐标及有效区域裁剪"""rows, cols = img.shape[:2]img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)top, bottom, left, right = 0, 0, 0, 0# 从上向下扫描for i in range(0, rows, 1):for j in range(0, cols, 1):if img_gray[i, j] >= T:if img_gray[i + 1, j] >= T:top = ibreakelse:continuebreak# 从下向上扫描for i in range(rows - 1, -1, -1):for j in range(0, cols, 1):if img_gray[i, j] >= T:if img_gray[i - 1, j] >= T:bottom = ibreakelse:continuebreak# 从左向右扫描for j in range(0, cols, 1):for i in range(top, bottom, 1):if img_gray[i, j] >= T:if img_gray[i, j + 1] >= T:left = jbreakelse:continuebreak# 从右向左扫描for j in range(cols - 1, -1, -1):for i in range(top, bottom, 1):if img_gray[i, j] >= T:if img_gray[i, j - 1] >= T:right = jbreakelse:continuebreak# 计算有效区域半径R = int(max((bottom - top) / 2, (right - left) / 2))img_valid = img[top:int(top + 2 * R), left:int(left + 2 * R)]# 创建掩膜(单通道)h, w = img_valid.shape[:2]x, y = w // 2, h // 2  # 中心mask = np.zeros((h, w), dtype=np.uint8)cv2.circle(mask, (x, y), R, 255, -1)white_bg = np.ones_like(img_valid, dtype=np.uint8) * 255# 把圆形区域的像素从原图复制到白背景上result = white_bg.copy()result[mask == 255] = img_valid[mask == 255]return result, R, (x, y)
  • 基于霍夫变换的云图边界检测
 def CloudCircularBboundary(img):"""云图圆形边界检测"""gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)edges = cv2.Canny(gray, 250, 255)circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 20,param1=50, param2=30, minRadius=0, maxRadius=0)if circles is not None:max_radius = 0masked_img,selected_circle = None,Nonecircles = np.round(circles[0, :]).astype("int")for (x, y, r) in circles:if r > max_radius:max_radius = rselected_circle = (x, y, r)print("最大圆形:", selected_circle)if selected_circle is not None:# x, y, r = selected_circlex, y, r = 300,300,250mask = np.zeros(img.shape[:2], dtype="uint8")cv2.circle(mask, (x, y), r, 255, -1)masked_img = cv2.bitwise_and(img, img, mask=mask)return masked_img,selected_circle,""else:return None,None,"未检测到圆形区域"

云图色度增强

def CloudChroma(img, B_coff=0.5, R_coff=0.5):# 云图色度增强R = img[:, :, 0].astype(np.float32)G = img[:, :, 1].astype(np.float32)B = img[:, :, 2].astype(np.float32)BR_ratio = B - RBR_mean = np.mean(BR_ratio)diff = BR_ratio - BR_meanR_enhanced = R.copy()B_enhanced = B.copy()B_enhanced += diff * B_coffR_enhanced -= diff * R_coffB_enhanced = np.clip(B_enhanced, 0, 255)R_enhanced = np.clip(R_enhanced, 0, 255)img_enhanced = np.stack([R_enhanced, G, B_enhanced], axis=2).astype(np.uint8)return img_enhanced

云图太阳位置

def SolarPosition(img, dt, lat, lon, R: float, camera_angle: float = 0) -> Tuple[int, int, float, float]:img_h, img_w = img.shape[:2]z, a = SolarZenithAzimuth(lat, lon, dt)r = (z / 90) * Rtheta_rad = math.radians(a - camera_angle)x0, y0 = img_w / 2, img_h / 2x = x0 - r * math.sin(theta_rad)y = y0 - r * math.cos(theta_rad)return int(round(x)), int(round(y)), z, a

云图云层识别

云层识别方法

  • RB
def RBR(img, R1, center, threshold=1.2):B = img[:, :, 0]R = img[:, :, 2]BR_ratio = B / (R + 1e-6)cloud_mask = (BR_ratio > threshold).astype(np.uint8) * 255  # 云为1,天空为0mask = np.zeros_like(BR_ratio, dtype=np.uint8)cv2.circle(mask, center, R1, 255, -1)pixel_count = np.count_nonzero(mask)  # 圆内全部像素点个数cloud_count = np.count_nonzero(cloud_mask)cloud_coverage = 1 - cloud_count / pixel_countgo_img = 255 - cloud_maskgo_img = cv2.bitwise_and(go_img, go_img, mask=mask)return round(cloud_coverage, 2), go_imgdef BRD(img, R1, center, threshold=1.2):B = img[:, :, 0]R = img[:, :, 2]BR_ratio = B - Rcloud_mask = (BR_ratio > threshold).astype(np.uint8) * 255  # 云为1,天空为0mask = np.zeros_like(BR_ratio, dtype=np.uint8)cv2.circle(mask, center, R1, 255, -1)pixel_count = np.count_nonzero(mask)  # 圆内全部像素点个数cloud_count = np.count_nonzero(cloud_mask)cloud_coverage = 1 - cloud_count / pixel_countgo_img = cloud_maskgo_img = cv2.bitwise_and(go_img, go_img, mask=mask)return round(cloud_coverage, 2), go_imgdef NRBR(img, threshold=0.05):img_float = img.astype(np.float32)B = img_float[:, :, 0]G = img_float[:, :, 1]R = img_float[:, :, 2]denominator = (R + B)denominator[denominator == 0] = 1e-6nrbr = abs(R - B) / denominatorcloud_mask = (nrbr < threshold).astype(np.uint8)cloud_fraction = np.sum(cloud_mask) / cloud_mask.size * 100return cloud_fraction, cloud_mask * 255def CloudSegment_BRD_Diff(image, threshold=5):image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)b, g, r = cv2.split(image)diff = cv2.subtract(b, cv2.max(r, g))_, mask = cv2.threshold(diff, threshold, 255, cv2.THRESH_BINARY)mask = 255 - maskcloud_coverage = np.sum((mask > 0).astype(np.uint8)) / mask.size * 100return round(cloud_coverage,2),mask
  • RB Kmean
def CloudSegment_BRD_Kmeans(img,alpha=0.5):# 云图色度增强R = img[:, :, 0].astype(np.float32)G = img[:, :, 1].astype(np.float32)B = img[:, :, 2].astype(np.float32)BR_ratio = B - RBR_mean = np.mean(BR_ratio)diff = BR_ratio - BR_meanR_enhanced = R.copy()B_enhanced = B.copy()B_enhanced += diff * alphaR_enhanced -= diff * alphaB_enhanced = np.clip(B_enhanced, 0, 255)R_enhanced = np.clip(R_enhanced, 0, 255)img_enhanced = np.stack([R_enhanced, G, B_enhanced], axis=2).astype(np.uint8)# K-Means云层检测features = np.stack([R_enhanced, G, B_enhanced], axis=-1)h_img, w_img, c_img = features.shapefeatures_2d = features.reshape(-1, 3)  # 转为二维 (N, 3)kmeans = KMeans(n_clusters=2,  n_init=10, max_iter=1000)labels = kmeans.fit_predict(features_2d)labels_img = labels.reshape(h_img, w_img)# 根据聚类中心亮度判断哪个是云(亮度大)cloud_cluster = np.argmax(kmeans.cluster_centers_[:, 0])cloud_mask = (labels_img == cloud_cluster).astype(np.uint8) * 255cloud_coverage = 1return cloud_coverage,cloud_mask
  • RB GMM

def CloudSegment_GMM(img):# 2. 转 HSVhsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV).astype(np.float32)# 4. 取特征 这里选 S,V 作为聚类特征features = hsv[..., 1:3]  # shape = (H, W, 2)h, w, _ = features.shapefeatures_2d = features.reshape(-1, 2)# 5. 下采样加速sample_idx = np.random.choice(features_2d.shape[0], size=5000, replace=False)sample_features = features_2d[sample_idx]# 6. 拟合高斯混合模型gmm = GaussianMixture(n_components=2, covariance_type='full',tol=1e-3,  # 收敛阈值reg_covar=1e-6,  # 正则化参数max_iter=200,  # 最大迭代次数n_init=5,  # 运行次数取最好init_params='kmeans',  # 初始化方式random_state=42)gmm.fit(sample_features)# 7. 对全图预测labels = gmm.predict(features_2d)labels_img = labels.reshape(h, w)# 通常云像素亮度高,所以可以判断哪个聚类均值的V值更高cluster_means = []for k in range(2):cluster_means.append(np.mean(features_2d[labels == k, 1]))  # 取V均值cloud_label = np.argmax(cluster_means)mask_cloud = (labels_img == cloud_label).astype(np.uint8) * 255cloud_coverage = np.sum((mask_cloud > 0).astype(np.uint8)) / mask_cloud.size * 100return round(cloud_coverage,2),mask_cloud
  • Gray
def CloudGray(img, threshold=130):gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, binary = cv2.threshold(gray, threshold, 255, cv2.THRESH_BINARY)cloud_coverage = 1return cloud_coverage,binary

云团矢量外推

仅个人笔记使用,感谢点赞关注



目前仅专注于 NLP 大模型 机器学习和前后端的技术学习和分享

感谢大家的关注与支持!
http://www.dtcms.com/a/524169.html

相关文章:

  • R语言基于selenium模拟浏览器抓取ASCO数据-连载NO.03
  • 多分组火山图绘制-Rscript_version1.0
  • 【开题答辩全过程】以基于Hadoop的电商数据分析系统为例,包含答辩的问题和答案
  • 申威服务器安装Java11(swjdk-11u-9.ky10.sw_64.rpm)详细操作步骤(附安装包)
  • UVa 1596 Bug Hunt
  • 企业数据仓库
  • 如何用 HTML 生成 PC 端软件
  • Apache Spark算法开发指导-特征转换Normalizer
  • 泗洪网站建设变化型网页网站有哪些
  • 渭南哪家公司可以做网站小程序开发制作价格
  • 广州城市建设规划局网站我想给网站网站做代理
  • 蓝蜂 MQTT 网关打通 120 台设备数据,助汽车零部件厂降本 40%​
  • C++异常详细介绍
  • AKKO 3180键盘插到联想笔记本无法使用问题
  • 打造高清3D虚拟世界|零基础学习Unity HDRP高清渲染管线(第六天)
  • 从项目中学习CAN和CANFD报文结构(新手入门)
  • SpreadJS 赋能在线 Excel:协同编辑与精细化权限管控的技术实现
  • RabbitMQ 持久性详解
  • cms网站栏目介绍html免费模板下载
  • 太原网站建设培训班wordpress购买按钮插件
  • 北斗导航 | 接收机自主完好性监测(RAIM)在列车中的应用:原理、现状、挑战与案例
  • 前端Sass完全指南:从入门到精通
  • 网站建设地域名高校网站建设 网站群
  • 破局制造业数据孤岛,大腾智能PDM实现产研协同
  • 小程序文件在线显示(支持word,图片,视频等)
  • 记录自己写项目的第三天,springbot+redis+rabbitma高并发项目
  • Linux下查看系统启动时间、运行时间
  • Linux中子系统注册subsystem_register等函数的实现
  • MFC应用程序,工作线程学习记录
  • 在什么网站做公司人员增减wordpress主题标签