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

评估图片清晰度

import numpy as np
import torch
import cv2
import matplotlib.pyplot as plt
import os
from pathlib import Path

def read_raw_gt(file_path, height, width, bl):
    """读取原始RAW文件并进行预处理"""
    raw_image = np.fromfile(file_path, dtype=np.int16)
    raw_image = raw_image.reshape((height, width)).astype(np.float32)
    raw_image = np.maximum(raw_image - bl, 0) / (4095 - bl)  # 归一化到[0,1]
    raw_image = np.expand_dims(raw_image, axis=2)  # 增加通道维度

    # 分割为RGGB四通道
    raw_out = np.concatenate((
        raw_image[0:height:2, 0:width:2, :],  # R
        raw_image[0:height:2, 1:width:2, :],  # G
        raw_image[1:height:2, 0:width:2, :],  # G
        raw_image[1:height:2, 1:width:2, :]), axis=2)
    return raw_out  # 形状 (H//2, W//2, 4)


def RGGB_t_2img(raw_tensor):
    """将四通道RGGB tensor转换为RGB图像"""
    raw_image = raw_tensor.numpy() if torch.is_tensor(raw_tensor) else raw_tensor
    channels, height, width = raw_image.shape
    assert channels == 4, "Tensor must have 4 channels"

    # 构建拜耳阵列
    bayer = np.zeros((height * 2, width * 2), dtype=np.uint8)
    bayer[0::2, 0::2] = (raw_image[0] * 255).astype(np.uint8)  # R
    bayer[0::2, 1::2] = (raw_image[1] * 255).astype(np.uint8)  # G
    bayer[1::2, 0::2] = (raw_image[2] * 255).astype(np.uint8)  # G
    bayer[1::2, 1::2] = (raw_image[3] * 255).astype(np.uint8)  # B

    # 解拜耳转换为RGB
    rgb = cv2.cvtColor(bayer, cv2.COLOR_BayerRGGB2RGB)
    return rgb


def calculate_laplacian_variance(rgb_image):
    """计算拉普拉斯方差清晰度指标"""
    gray = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2GRAY)
    laplacian = cv2.Laplacian(gray, cv2.CV_64F)
    return laplacian.var()


def generate_blur_heatmap(rgb_image, window_size=64):
    """生成局部模糊热力图"""
    gray = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2GRAY)
    h, w = gray.shape
    heatmap = np.zeros((h // window_size, w // window_size))

    for i in range(0, h // window_size):
        for j in range(0, w // window_size):
            y = i * window_size
            x = j * window_size
            patch = gray[y:y + window_size, x:x + window_size]
            lap_var = cv2.Laplacian(patch, cv2.CV_64F).var()
            heatmap[i, j] = lap_var

    # 归一化处理
    heatmap = (heatmap - heatmap.min()) / (heatmap.max() - heatmap.min() + 1e-8)
    return cv2.resize(heatmap, (w, h), interpolation=cv2.INTER_NEAREST)

def analyze_gt_blur(file_path, height, width, bl, output_dir='./results'):
    """增强版分析函数,支持结果分文件保存"""
    # 创建输出目录
    Path(output_dir).mkdir(parents=True, exist_ok=True)

    # 生成基础文件名
    base_name = os.path.splitext(os.path.basename(file_path))[0]
    safe_name = base_name.replace(' ', '_')  # 处理特殊字符

    # 数据处理流程(保持原逻辑)
    raw_out = read_raw_gt(file_path, height, width, bl)
    raw_tensor = torch.from_numpy(raw_out).permute(2, 0, 1)
    rgb_image = RGGB_t_2img(raw_tensor)
    global_var = calculate_laplacian_variance(rgb_image)
    heatmap = generate_blur_heatmap(rgb_image)

    # 独立保存RGB图像
    rgb_path = os.path.join(output_dir, f"{safe_name}_rgb.png")
    plt.imsave(rgb_path, rgb_image)

    # 独立保存热力图(含colorbar)
    plt.figure(figsize=(8, 6))
    plt.imshow(heatmap, cmap='jet')
    plt.colorbar()
    heatmap_path = os.path.join(output_dir, f"{safe_name}_heatmap.png")
    plt.savefig(heatmap_path, bbox_inches='tight')
    plt.close()

    # 保存组合分析图
    analysis_path = os.path.join(output_dir, f"{safe_name}_analysis.png")
    fig = plt.figure(figsize=(15, 6))

    # RGB图像子图
    ax1 = fig.add_subplot(1, 3, 1)
    ax1.imshow(rgb_image)
    ax1.set_title("RGB Image")

    # 热力图层
    ax2 = fig.add_subplot(1, 3, 2)
    im = ax2.imshow(heatmap, cmap='jet')
    fig.colorbar(im, ax=ax2)
    ax2.set_title("Blur Heatmap")

    # 直方图
    ax3 = fig.add_subplot(1, 3, 3)
    ax3.hist(heatmap.flatten(), bins=50)
    ax3.set_title("Blur Distribution")

    # 主标题
    fig.suptitle(f"File: {base_name}\nGlobal Laplacian Variance: {global_var:.2f}")
    plt.savefig(analysis_path, dpi=300, bbox_inches='tight')
    plt.close()

    return {
        "rgb_path": rgb_path,
        "heatmap_path": heatmap_path,
        "analysis_path": analysis_path,
        "global_var": global_var
    }


import cv2
import numpy as np
from matplotlib import cm


def create_overlay(rgb_image, heatmap, alpha=0.5):
    """创建热力图叠加可视化"""
    # 标准化热力图数据
    norm_heat = (heatmap - np.min(heatmap)) / (np.max(heatmap) - np.min(heatmap) + 1e-8)

    # 生成伪彩色热力图
    heatmap_color = cm.jet(norm_heat)[:, :, :3]  # 转换为RGB
    heatmap_color = (heatmap_color * 255).astype(np.uint8)

    # 调整原始图像尺寸(如果需要)
    if rgb_image.shape[:2] != heatmap.shape[:2]:
        rgb_image = cv2.resize(rgb_image, (heatmap.shape[1], heatmap.shape[0]))

    # 创建叠加效果
    overlay = cv2.addWeighted(rgb_image, 1 - alpha, heatmap_color, alpha, 0)
    return overlay


def enhanced_analysis(file_path, height, width, bl, output_dir='./results'):
    """增强版分析函数,包含叠加图生成"""
    # 基础处理(保持原有流程)
    raw_out = read_raw_gt(file_path, height, width, bl)
    raw_tensor = torch.from_numpy(raw_out).permute(2, 0, 1)
    rgb_image = RGGB_t_2img(raw_tensor)
    heatmap = generate_blur_heatmap(rgb_image)

    # 创建输出路径
    base_name = Path(file_path).stem
    safe_name = base_name.replace(' ', '_')
    Path(output_dir).mkdir(exist_ok=True)

    # 保存原始RGB
    rgb_path = f"{output_dir}/{safe_name}_original.png"
    cv2.imwrite(rgb_path, cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR))

    # 保存独立热力图
    plt.figure(figsize=(8, 6))
    plt.imshow(heatmap, cmap='jet')
    plt.colorbar()
    heatmap_path = f"{output_dir}/{safe_name}_heatmap.png"
    plt.savefig(heatmap_path, bbox_inches='tight')
    plt.close()

    # 生成并保存叠加图
    overlay = create_overlay(rgb_image, heatmap)
    overlay_path = f"{output_dir}/{safe_name}_overlay.png"
    cv2.imwrite(overlay_path, cv2.cvtColor(overlay, cv2.COLOR_RGB2BGR))

    return {
        'original': rgb_path,
        'heatmap': heatmap_path,
        'overlay': overlay_path
    }


# 测试配置
height = 1440  # RAW文件原始高度
width = 2570  # RAW文件原始宽度

height = 1080  # RAW文件原始高度
width = 1920  # RAW文件原始宽度

bl = 0  # 黑电平值

# 测试文件列表
raw_files = [
    'h-29x_200.raw',
    'h-218x_200.raw',
    'h-259x_200.raw'
]

import os

gt_dir = 'gt'
# 检查目录是否存在
if os.path.exists(gt_dir) and os.path.isdir(gt_dir):
    raw_files = [os.path.join(gt_dir, f) for f in os.listdir(gt_dir) if os.path.isfile(os.path.join(gt_dir, f))]
    print(raw_files)
# 执行分析
for raw_file in raw_files:
    print(f"Analyzing {raw_file}...")
    # results = analyze_gt_blur(raw_file, height, width, bl)
    # print(f"Global sharpness variance: {results['global_var']:.2f}\n")

    results = enhanced_analysis(raw_file,
                              height=height,
                              width=width,
                              bl=bl,
                              output_dir='./enhanced_results')

全局清晰度评估

  1. 拉普拉斯方差指标(Global Laplacian Variance: 97.50)
    • 质量评级:★★★☆☆(中等偏上)(典型值域:10-200)
  1. 数值对比参考
    • 优质图像:>100
    • 可接受范围:50-100
    • 需要优化:<50

二、模糊热图特征分析

  1. 空间分布特征

区域坐标

模糊值

对应物体

成因推测

(620, 880)

0.82

桌面反光区域

镜面反射过曝

(1120, 480)

0.76

移动的椅子

拍摄时物体位移

(280, 1040)

0.68

墙面装饰画

镜头畸变导致


http://www.kler.cn/a/596650.html

相关文章:

  • 《Keras 3 : AI神经网络开发人员指南》
  • Maven高级-分模块设计与开发-继承-聚合-私服-Web后端总结
  • 2025免费资产管理系统推荐(5款免费IT资产管理系统/软件)
  • Python---数据分析(Pandas九:二维数组DataFrame数据操作二: 数据排序,数据筛选,数据拼接)
  • 单播、广播、组播和任播
  • Golang开发棋牌游戏中的坑
  • NVIDIA驱动升级
  • 【SpringCloud】OpenFeign
  • 什么是 POM 设计模式
  • 当今前沿科技:改变世界的最新技术趋势
  • VMware上调整centos终端的背景颜色
  • 机器学习开发完整流程
  • 简介S参数 .snp文件
  • 弱网测试:全链路实战、高阶策略与自动化落地
  • PTA团体程序设计天梯赛-练习集71-75题
  • Python预训练模型实现俄语音频转文字
  • 操作系统WIN11无法出现WLAN图标(解决方案)
  • spring boot 登入权限RBAC模式
  • ROS melodic 安装 python3 cv_bridge
  • Ubuntu22.04通过DKMS包安装Intel WiFi系列适配器(网卡驱动)