ReportGeneratorLocal/tool/lighter.py

176 lines
7.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cv2
import numpy as np
# import rawpy
# from PIL import Image
# from tqdm import tqdm
# import tkinter as tk
#from tkinter import filedialog
#from concurrent.futures import ThreadPoolExecutor
#import argparse
#import os
#import torch
#from depth_anything_v2.dpt import DepthAnythingV2
#from utils import specify_name_group_blade,get_name
#parser = argparse.ArgumentParser(description='Depth Anything V2')
# parser.add_argument('--input-size', type=int, default=518)
# parser.add_argument('--encoder', type=str, default='vitl', choices=['vits', 'vitb', 'vitl', 'vitg'])
# args = parser.parse_args()
def extraction_win_lamina_mask(raw_image, depth_anything):
# 前面读的都是RGB图像深度估计需要BGR即下面是把RGB→BGR
raw_image = cv2.cvtColor(raw_image, cv2.COLOR_BGR2RGB)
depth = depth_anything.infer_image(raw_image)
depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255.0
depth = depth.astype(np.uint8)
_, otsu_mask = cv2.threshold(depth, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return otsu_mask
def check_overexposure(image, lamina_mask,threshold):
"""
检查图像中是否有过曝区域
:param image: 输入图像
:param threshold: 亮度值的阈值,像素值超过该值则认为是过曝区域
:return: 一个二值图像,过曝区域为白色,其它区域为黑色
"""
# 转换为浮动数据类型并归一化
image_float = image.astype(np.float32)
# 获取每个像素的亮度值(可以使用 YUV 或 RGB 亮度)
gray_image = cv2.cvtColor(image_float, cv2.COLOR_BGR2GRAY)
# 标记过曝区域,亮度大于阈值的像素为过曝区域
overexposure_mask = gray_image > threshold
overexposure_mask = (lamina_mask == 255) & overexposure_mask #只取叶片的亮光区mask
overexposure_number = np.sum(overexposure_mask * 1)
overexposed_pixels = gray_image[overexposure_mask]
# 计算曝光区域的平均亮度
if overexposed_pixels.size > 0:
avg_overexposed_value = np.mean(overexposed_pixels)
else:
avg_overexposed_value = 0 # 如果没有曝光区域,返回 0
return overexposure_mask, avg_overexposed_value,overexposure_number
def check_shawn(image,lamina_mask, threshold):
"""
检查图像中是否有阴影区域
:param image: 输入图像
:param threshold: 亮度值的阈值,像素值小于该值则认为是过阴影域
:return: 一个二值图像,过曝区域为白色,其它区域为黑色
"""
# 转换为浮动数据类型并归一化
image_float = image.astype(np.float32)
# 获取每个像素的亮度值(可以使用 YUV 或 RGB 亮度)
gray_image = cv2.cvtColor(image_float, cv2.COLOR_BGR2GRAY)
# 标记阴影区域,亮度小于阈值的像素为阴影区域
shawn_mask = gray_image < threshold
shawn_mask = (lamina_mask == 255) & shawn_mask
shawn_number = np.sum(shawn_mask * 1)
shawn_pixels = gray_image[shawn_mask]
# 计算阴影区域的平均亮度
if shawn_pixels.size > 0:
avg_shawn_value = np.mean(shawn_pixels)
else:
avg_shawn_value = 0
return shawn_mask, avg_shawn_value,shawn_number
def smooth_overexposed_regions(image, overexposure_mask, kernel_size=(15, 15)):
"""
对过曝区域进行平滑处理,修复与周围区域的过渡
:param image: 输入图像
:param overexposure_mask: 过曝区域的掩码
:param kernel_size: 高斯核大小
:return: 平滑过曝区域后的图像
"""
# 使用高斯模糊平滑过曝区域和周围区域
smoothed_image = cv2.GaussianBlur(image, kernel_size, 0)
# 将平滑后的图像和原始图像合成,修复过曝区域
fixed_image = np.where(overexposure_mask[..., None] == 255, image,smoothed_image)
return fixed_image
def bilateral_filter_adjustment(image, high_light_mask, d=15, sigma_color=75, sigma_space=75):
"""
使用双边滤波器平滑高光区域与周围区域的过渡
:param image: 输入图像
:param high_light_mask: 高光区域的掩码
:param d: 邻域的直径
:param sigma_color: 颜色空间的标准差
:param sigma_space: 坐标空间的标准差
:return: 平滑后的图像
"""
# 对整个图像应用双边滤波
filtered_image = cv2.bilateralFilter(image, d, sigma_color, sigma_space)
# 合成平滑后的图像和原图,保留非高光部分
final_image = np.where(high_light_mask[..., None] == 0, image, filtered_image)
return final_image
def adjust_highlights_shadows(image, threshold_shawn,threshold, depth_anything):
lamina_mask = extraction_win_lamina_mask(image, depth_anything)
shawn_mask,avg_shawn_value,shawn_number = check_shawn(image,lamina_mask,threshold_shawn)
# 调整亮度gamma < 1 时变亮gamma > 1 时变暗
gamma = 1 - (threshold_shawn-avg_shawn_value)/255.0
# print('阴影区调整的gama: '+str(gamma))#+str('\n'))
lookup_table = np.array([((i / 255.0) ** gamma) * 255 for i in range(256)]).astype('uint8')
# 应用 gamma 校正
if shawn_number !=0:
image[shawn_mask == True] = cv2.LUT(image[shawn_mask == True], lookup_table)
gamma_corrected_image = image
else:
gamma_corrected_image = image
#gamma_corrected_image = cv2.LUT(image, lookup_table)
#寻找过爆区域
overexposure_mask,avg_overexposed_value,overexposure_number = check_overexposure(gamma_corrected_image,lamina_mask,threshold)
reduction_factor = 1-(avg_overexposed_value-threshold) / 255
#reduction_factor = (avg_overexposed_value/255)*scale
# print("降低曝光区比例:" + str(reduction_factor))
# 调整亮度gamma < 1 时变亮越小越亮gamma > 1 时变暗(越大越暗)
print((1+reduction_factor))
lookup_table = np.array([((i / 255.0) ** (1+reduction_factor)) * 255 for i in range(256)]).astype('uint8')
# 应用 gamma 校正
if overexposure_number !=0:
gamma_corrected_image[overexposure_mask == True] = cv2.LUT(gamma_corrected_image[overexposure_mask == True], lookup_table)
#gamma_corrected_image[overexposure_mask == True] = np.clip(gamma_corrected_image[overexposure_mask == True] * reduction_factor, 0, 255)
#smoothed_image = smooth_overexposed_regions(gamma_corrected_image, overexposure_mask)
#smoothed_image = bilateral_filter_adjustment(gamma_corrected_image, overexposure_mask, d=15, sigma_color=75, sigma_space=75)
return gamma_corrected_image
# path=r'/home/dtyx/下载/1_涂层损伤_叶尖3m_2m_一般_紧急_一般_尽快打磨维修.jpg'
# from time import time
# if __name__ == "__main__":
# # input_dir = input("请输入处理图片路径: ")
# # output_dir = input("请输入保存图片路径: ")
# time_start = time()
# imgpath = path
# img = cv2.imdecode(np.fromfile(imgpath, dtype=np.uint8), cv2.IMREAD_COLOR)
# cv2.imshow('img',cv2.resize(img,(800,600)))
# mask=adjust_highlights_shadows(img,180,253)
# mask=cv2.resize(mask,(800,600))
# time_end = time()
# print("Time used:", time_end - time_start)
# cv2.imshow('mask',mask)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# # gamma = float(input("请输入 gamma 值: "))