1.背景描述
最近需要识别出一些逆光图片。例如我识别了一个人,需要用模型去看人的身上是否有安全带,但是由于背光存在,可能会导致判断不准确。我需要把这张图片的亮度提高一些,以便模型检测。
例如下面的图片,应该被识别为阴暗。计算出阴暗度之后,还可以去做一些gamma变换之类的操作,可以参考我之前的博客。
2.实现思路
首先将图像分割为不同的区域,计算图像的综合加权亮度值。权重可以用高斯方法来计算,越靠近中央权值越高(因为我们的数据,人体一般都处于图像中央)。
第二步,可以直接统计图像中的阴暗区域的个数。此处也可以利用直方图的分布来做一个分类或计算(同事做的)。
3.实现效果
目前过于阴暗的基本都能识别,效果如下:
目前这种图像效果较差,但是其他图像还是可以的。
4.代码
python
import os
import shutil
from PIL import Image
import numpy as np
def gaussian_weight(distance, center_distance, edge_weight=0.1, center_weight=3):
""" 计算高斯权重,中央权重为3,边缘权重为0.1 """
if distance == 0: # 中心点
return center_weight
else:
return edge_weight * np.exp(-distance ** 2 / (2 * (center_distance ** 2)))
def calculate_darkness(image):
"""计算图像阴暗度"""
grayscale = np.array(image.convert('L'))
return np.mean(grayscale)
def process_image(image_path):
img = Image.open(image_path).convert('RGB')
width, height = img.size
# horizontal_sections = int(width/20)
# if horizontal_sections%2==0:
# horizontal_sections+=1
# if horizontal_sections<9:
# horizontal_sections=9
horizontal_sections=11
horizontal_height = height // horizontal_sections
vertical_sections = max(5, (width // horizontal_height) // 2 * 2 + 1)
vertical_width = width // vertical_sections
darkness_values = []
weighted_darkness_values = []
# 计算每个区域的亮度和对应的权重
for i in range(horizontal_sections):
for j in range(vertical_sections):
left = j * vertical_width
upper = i * horizontal_height
right = left + vertical_width
lower = upper + horizontal_height
if j == vertical_sections - 1:
right = width
if i == horizontal_sections - 1:
lower = height
section = img.crop((left, upper, right, lower))
darkness = calculate_darkness(section)
darkness_values.append(darkness)
# 计算距离并计算权重
horizontal_center = horizontal_sections // 2
vertical_center = vertical_sections // 2
distance = np.sqrt((i - horizontal_center) ** 2 + (j - vertical_center) ** 2)
# 使用高斯权重
weight = gaussian_weight(distance, max(horizontal_sections, vertical_sections))
weighted_darkness_values.append(weight)
# 计算亮度小于90的区域占比
dark_area_count = sum(1 for value in darkness_values if value < 90)
total_areas = len(darkness_values)
dark_area_ratio = dark_area_count / total_areas
# 归一化权重
total_weight = np.sum(weighted_darkness_values)
normalized_weights = [w / total_weight for w in weighted_darkness_values]
# 计算加权综合亮度
total_weighted_darkness = np.sum(np.array(darkness_values) * np.array(normalized_weights))
return total_weighted_darkness, dark_area_ratio
def classify_images(input_folder, output_folder_y, output_folder_z):
if not os.path.exists(output_folder_y):
os.makedirs(output_folder_y)
if not os.path.exists(output_folder_z):
os.makedirs(output_folder_z)
for filename in os.listdir(input_folder):
if filename.endswith(('.jpg', '.png', '.jpeg')): # 处理常见图片格式
image_path = os.path.join(input_folder, filename)
total_weighted_darkness, dark_area_ratio = process_image(image_path)
# 根据条件移动图片
if dark_area_ratio>0.2: # 新增的规则
shutil.move(image_path, os.path.join(output_folder_y, filename))
# 根据条件移动图片
elif total_weighted_darkness >100:
shutil.move(image_path, os.path.join(output_folder_z, filename))
elif dark_area_ratio<0.1:
shutil.move(image_path, os.path.join(output_folder_z, filename))
# 根据条件移动图片
else: # 新增的规则
shutil.move(image_path, os.path.join(output_folder_y, filename))
# 使用示例
input_directory = r'E:\data\202408福建浙江安监场景效果对比\困难样本测试\阴暗' # 原始图像的文件夹路径
output_directory_y = r'E:\data\202408福建浙江安监场景效果对比\困难样本测试\阴暗\筛选阴暗' # 移动到阴暗图片文件夹
output_directory_z = r'E:\data\202408福建浙江安监场景效果对比\困难样本测试\阴暗\筛选明亮' # 移动明亮图片文件夹
classify_images(input_directory, output_directory_y, output_directory_z)