176 lines
7.1 KiB
Python
176 lines
7.1 KiB
Python
|
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 值: "))
|