first commit
This commit is contained in:
129
Tool-图片堆叠/1_check_picture_pair.py
Normal file
129
Tool-图片堆叠/1_check_picture_pair.py
Normal file
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Set, Dict
|
||||
|
||||
# 定义支持的文件扩展名
|
||||
VALID_EXTENSIONS = {'.png', '.jpg', '.jpeg'}
|
||||
|
||||
def process_directory(path: Path,
|
||||
prefix: str = "",
|
||||
suffix: str = "") -> (Set[str], Dict[str, str]):
|
||||
"""
|
||||
处理单个目录,提取所有有效文件的文件名(stem),并根据前缀和后缀进行规范化。
|
||||
|
||||
返回:
|
||||
normalized_stems (Set[str]): 规范化处理后的文件名集合。
|
||||
original_to_normalized_map (Dict[str, str]): 原始文件名到规范化文件名的映射。
|
||||
(这里我们反过来,用 规范化 -> 原始,更方便后续查找)
|
||||
"""
|
||||
if not path.is_dir():
|
||||
print(f"错误: 路径 '{path}' 不是一个有效的目录。", file=sys.stderr)
|
||||
return set(), {}
|
||||
|
||||
normalized_stems: Set[str] = set()
|
||||
normalized_to_original_map: Dict[str, str] = {}
|
||||
|
||||
for file_path in path.glob('*'):
|
||||
# 确保是文件,并且扩展名在我们的有效列表中
|
||||
if file_path.is_file() and file_path.suffix.lower() in VALID_EXTENSIONS:
|
||||
original_stem = file_path.stem
|
||||
normalized_stem = original_stem
|
||||
|
||||
# 仅当提供了前缀/后缀时才进行处理
|
||||
if prefix and normalized_stem.startswith(prefix):
|
||||
normalized_stem = normalized_stem[len(prefix):]
|
||||
|
||||
if suffix and normalized_stem.endswith(suffix):
|
||||
normalized_stem = normalized_stem[:-len(suffix)]
|
||||
|
||||
# 检查处理后是否重名,如果重名则发出警告
|
||||
if normalized_stem in normalized_to_original_map:
|
||||
print(f"警告: 规范化后文件名发生冲突。")
|
||||
print(f" '{original_stem}' 和 '{normalized_to_original_map[normalized_stem]}' 都变成了 '{normalized_stem}'")
|
||||
|
||||
normalized_stems.add(normalized_stem)
|
||||
normalized_to_original_map[normalized_stem] = original_stem
|
||||
|
||||
return normalized_stems, normalized_to_original_map
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="比较两个文件夹中的文件名是否匹配。")
|
||||
parser.add_argument("-i", "--image",
|
||||
type=Path,
|
||||
required=True,
|
||||
help="Image 文件夹路径")
|
||||
parser.add_argument("-l", "--label",
|
||||
type=Path,
|
||||
required=True,
|
||||
help="Label 文件夹路径")
|
||||
parser.add_argument("-p", "--prefix",
|
||||
type=str,
|
||||
default="",
|
||||
help="在 Label 文件名中要忽略的前缀")
|
||||
parser.add_argument("-s", "--suffix",
|
||||
type=str,
|
||||
default="",
|
||||
help="在 Label 文件名中要忽略的后缀")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# 1. 处理 Image 文件夹 (不需要前缀后缀)
|
||||
print(f"--- 正在处理 Image 文件夹: {args.image} ---")
|
||||
image_stems, _ = process_directory(args.image)
|
||||
if not image_stems:
|
||||
print(f"未在 Image 文件夹中找到任何 .png 或 .jpg 文件。")
|
||||
|
||||
# 2. 处理 Label 文件夹 (需要前缀后缀)
|
||||
print(f"\n--- 正在处理 Label 文件夹: {args.label} ---")
|
||||
print(f"(忽略前缀: '{args.prefix}', 忽略后缀: '{args.suffix}')")
|
||||
label_stems_normalized, label_norm_to_orig_map = process_directory(
|
||||
args.label,
|
||||
args.prefix,
|
||||
args.suffix
|
||||
)
|
||||
if not label_stems_normalized:
|
||||
print(f"未在 Label 文件夹中找到任何 .png 或 .jpg 文件。")
|
||||
|
||||
# 3. 执行比较 (使用集合运算)
|
||||
matching_stems = image_stems.intersection(label_stems_normalized)
|
||||
|
||||
# Image 文件夹中多余的 (在 Image 中,但不在 Label 中)
|
||||
extra_in_image = image_stems.difference(label_stems_normalized)
|
||||
|
||||
# Label 文件夹中多余的 (在 Label 中,但不在 Image 中)
|
||||
extra_in_label_normalized = label_stems_normalized.difference(image_stems)
|
||||
|
||||
# 将 Label 中多余的文件名转换回原始名称
|
||||
extra_in_label_original = {label_norm_to_orig_map[stem] for stem in extra_in_label_normalized}
|
||||
|
||||
# 4. 输出结果
|
||||
print("\n" + "="*30)
|
||||
print(" 匹配结果报告")
|
||||
print("="*30)
|
||||
|
||||
print(f"\n匹配的文件总数: {len(matching_stems)}")
|
||||
|
||||
print("\n--- Image 文件夹中多余的文件 (共 {} 个) ---".format(len(extra_in_image)))
|
||||
if not extra_in_image:
|
||||
print("(无)")
|
||||
else:
|
||||
for file_stem in sorted(extra_in_image):
|
||||
print(file_stem)
|
||||
|
||||
print("\n--- Label 文件夹中多余的文件 (共 {} 个) ---".format(len(extra_in_label_original)))
|
||||
print("(显示的是原始文件名,非规范化名称)")
|
||||
if not extra_in_label_original:
|
||||
print("(无)")
|
||||
else:
|
||||
for file_stem in sorted(extra_in_label_original):
|
||||
print(file_stem)
|
||||
|
||||
print("\n" + "="*30)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
122
Tool-图片堆叠/2_TOOL_stack_pics.sh
Normal file
122
Tool-图片堆叠/2_TOOL_stack_pics.sh
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 -i <ori_image_directory> -l <ori_label_directory> -r <stack_result_directory> [ -a <alpha> -p <prefix> -s <suffix> -h]"
|
||||
echo "对image图片和label图片进行匹配(-i、-l -r均不能为空)(-p -s默认为空"" -a默认为\"0.3\") "
|
||||
echo "-i:原始image的路径,-l:原始label的路径,-p:前缀内容,-s:后缀内容(不用管文件后缀名),-h:帮助"
|
||||
echo "e.g. bash 2_TOOL_stack_pics.sh -i ./ori -l ./label -r ./result_0.3透明度 -a 0.3 -p Prefix -s _label"
|
||||
}
|
||||
|
||||
ori_image_directorys=""
|
||||
ori_label_directorys=""
|
||||
stack_result_directorys=""
|
||||
prefix=""
|
||||
suffix=""
|
||||
alpha="0.3"
|
||||
|
||||
while getopts "hl:i:r:p:s:a:" opt; do
|
||||
case $opt in
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
i)
|
||||
ori_image_directorys=$OPTARG
|
||||
;;
|
||||
l)
|
||||
ori_label_directorys=$OPTARG
|
||||
;;
|
||||
p)
|
||||
prefix=$OPTARG
|
||||
;;
|
||||
s)
|
||||
suffix=$OPTARG
|
||||
;;
|
||||
r)
|
||||
stack_result_directorys=$OPTARG
|
||||
;;
|
||||
a)
|
||||
alpha=$OPTARG
|
||||
;;
|
||||
*)
|
||||
echo -e '\033[31m!!! Error, Illegal input !!!\033[0m'
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 判断输入地址是否为空
|
||||
if [ -z "$ori_label_directorys" ] || [ -z "$ori_image_directorys" ] || [ -z "$stack_result_directorys" ]; then
|
||||
echo -e "\033[31m输入地址 -i -l -z 存在空地址\033[0m"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 地址转化
|
||||
ori_image_directory=$(readlink -f "$ori_image_directorys")
|
||||
ori_label_directory=$(readlink -f "$ori_label_directorys")
|
||||
stack_result_directory=$(readlink -f "$stack_result_directorys")
|
||||
if [ -z "$ori_label_directory" ] || [ -z "$ori_image_directory" ]|| [ -z "$stack_result_directory" ]; then
|
||||
echo "image、label、result存在无法解析地址,程序退出"
|
||||
echo -e "\033[31mori_image_directory\033[0m: $ori_image_directorys"
|
||||
echo -e "\033[31mori_label_directory\033[0m: $ori_label_directorys"
|
||||
echo -e "\033[31mori_label_directory\033[0m: $stack_result_directorys"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "$ori_label_directory" ] || [ ! -d "$ori_image_directory" ]; then
|
||||
echo "image、label两目录有一个不存在,程序退出"
|
||||
echo -e "\033[31mori_image_directory\033[0m: $ori_image_directory"
|
||||
echo -e "\033[31mori_label_directory\033[0m: $ori_label_directorys"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 获取当前脚本的路径和名称
|
||||
script_path=$(dirname "$0")
|
||||
# 将当前目录更改为脚本所在的路径
|
||||
cd "$script_path"
|
||||
|
||||
# 激活conda环境
|
||||
source /home/"$USER"/miniconda/bin/activate Deal_Data
|
||||
|
||||
echo -e "\033[32m_____ 2_TOOL_stack_pics.sh _____\033[0m"
|
||||
echo -e "\033[33mimage所在文件夹为$ori_image_directory\nlable所在文件夹为$ori_label_directory\033[0m"
|
||||
# 遍历label目录
|
||||
for file_path in "$ori_label_directory"/*; do
|
||||
# 判断是否是文件
|
||||
if [[ -f "$file_path" ]]; then
|
||||
file_name=$(basename "$file_path")
|
||||
# 判断文件名是否符合规范
|
||||
if [[ "$file_name" =~ .*\.(jpg|png|bmp|JPG|PNG|BMP) ]]; then # 判断是否有为图片
|
||||
# if [[ "$file_name" =~ "$prefix".*"$suffix".*\.(jpg|png|bmp|JPG|PNG|BMP)$ ]]; then # 判断是否有满足要求的文件名
|
||||
# 抽取文件名(有前缀、后缀的抽取前缀、后缀里面的,没有的返回整个)
|
||||
if [ -z $prefix ];then
|
||||
file_name_extract=$(echo $file_name | sed "s/"$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
|
||||
else
|
||||
file_name_extract=$(echo $file_name | sed "s/".*$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
|
||||
fi
|
||||
# 从label目录中看是否有此文件
|
||||
file_name_other=$(ls $ori_image_directory | grep $file_name_extract)
|
||||
file_name_other=$(echo "$(echo "$file_name_other" | sed '/^$/d')" | head -n1) # 提取出文件名
|
||||
# 如果另一个目录没有此文件的话
|
||||
if [ -z "$file_name_other" ]; then
|
||||
echo "$file_name label中对应内容未在$ori_image_directory搜索到"
|
||||
# 建立相关存储文件夹
|
||||
if [ ! -d "$ori_label_directory/Not_pair_pics" ]; then
|
||||
mkdir -p "$ori_label_directory/Not_pair_pics" # 建立存储文件夹
|
||||
fi
|
||||
# 移动相关文件
|
||||
cp "$ori_label_directory/$file_name" "$ori_label_directory/Not_pair_pics"
|
||||
echo "$file_name" >> "$ori_label_directory/Not_pair_pics/not_pair.txt"
|
||||
else # 如果另一个目录有此配对文件的话,则运行相关程序
|
||||
echo "image中的$file_name_other,与lable中的$file_name"
|
||||
mkdir -p "$stack_result_directory"
|
||||
python 2_stack_picture.py "$ori_image_directory/$file_name_other" "$ori_label_directory/$file_name" "$stack_result_directory" "$alpha"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
fi
|
||||
else
|
||||
echo "$file_path不是文件"
|
||||
fi
|
||||
done
|
||||
41
Tool-图片堆叠/2_stack_picture.py
Normal file
41
Tool-图片堆叠/2_stack_picture.py
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
import cv2, os, sys
|
||||
|
||||
def Stack_pic(Background_path, Overlay_path, Result_dir, alpha=0.3):
|
||||
# 读取两张没有alpha通道的图片
|
||||
img1 = cv2.imread(Background_path) # 底层图片
|
||||
img2 = cv2.imread(Overlay_path) # 顶层图片
|
||||
|
||||
Result_name = os.path.splitext(os.path.basename(Background_path))[0]
|
||||
|
||||
# 将img2调整为与img1大小相同
|
||||
img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))
|
||||
|
||||
# 将img2的透明度调整为20%
|
||||
overlay_alpha = alpha
|
||||
|
||||
# 将img2叠加到img1上
|
||||
overlay = cv2.addWeighted(img1, 1 - overlay_alpha, img2, overlay_alpha, 0)
|
||||
|
||||
# 保存结果
|
||||
if not os.path.exists(Result_dir):
|
||||
os.makedirs(Result_dir)
|
||||
cv2.imwrite(os.path.join(Result_dir, Result_name+'.png'), overlay)
|
||||
print("堆叠图片写入地址:", os.path.join(Result_dir, Result_name+'.png'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Background_path = sys.argv[1] # 背景所在路径
|
||||
Overlay_path = sys.argv[2] # 上层图片所在路径
|
||||
Result_dir = sys.argv[3] # 结果所在目录
|
||||
# 透明度,默认为0.3
|
||||
try:
|
||||
alpha = float(sys.argv[4])
|
||||
if(alpha > 1 or alpha < 0):
|
||||
print("alpha 透明度输入不正确,其值应该在0~1之间")
|
||||
alpha = 0.3
|
||||
except:
|
||||
alpha = 0.3
|
||||
# 进行对叠程序
|
||||
Stack_pic(Background_path, Overlay_path, Result_dir, alpha)
|
||||
5
Tool-图片堆叠/※使用手册
Normal file
5
Tool-图片堆叠/※使用手册
Normal file
@@ -0,0 +1,5 @@
|
||||
0. 将原始图片移动到./ori文件夹、标注图片移动到./label文件夹下
|
||||
1. 判断两个文件中文件名是否匹配
|
||||
python 1_check_picture_pair.py -i ./ori -l ./label # -p "mask_" -s "_seg"
|
||||
2. 图片堆叠
|
||||
bash 2_TOOL_stack_pics.sh -i ./ori -l ./label -r ./result_0.3透明度 -a 0.3 -s _label
|
||||
Reference in New Issue
Block a user