first commit

This commit is contained in:
admin
2026-05-20 15:05:35 +08:00
commit ac09b26253
2048 changed files with 189478 additions and 0 deletions

View File

@@ -0,0 +1,308 @@
#!/bin/bash
usage() {
echo "Usage: $0 -i <ori_image_directory> -l <ori_label_directory> [-h]"
echo "对image图片和label图片进行处理"
echo "-i:原始图片的路径,-l:原始标签的路径,-h:帮助"
}
ori_image_directorys=""
ori_label_directorys=""
while getopts "hl:i:" opt; do
case $opt in
h)
usage
exit 0
;;
i)
ori_image_directorys=$OPTARG
;;
l)
ori_label_directorys=$OPTARG
;;
*)
echo -e '\033[31m!!! Error, Illegal input !!!\033[0m'
usage
exit 1
;;
esac
done
# 判断输入地址是否都为空
if [ -z "$ori_label_directorys" ] && [ -z "$ori_image_directorys" ]; then
echo -e "\033[31m输入地址 -i -l 都为空\033[0m"
usage
exit 1
fi
# 地址转化
ori_image_directory=$(readlink -f "$ori_image_directorys")
ori_label_directory=$(readlink -f "$ori_label_directorys")
if [ -z "$ori_label_directory" ] && [ -z "$ori_image_directory" ]; then
echo "无法解析地址,程序退出"
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
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"
echo -e "\033[32m______ 1_rename_data.sh _____\033[0m"
while true; do
PS3='Please enter your choice: '
options=("Move all pics in dir to dir" "Delete all space in filename" "Add jpg to no suffix filename" "Replace content in filename" "Extract filename between prefix and suffix" "Add content before filename" "Add content behand filename" "Quit")
echo "一般处理流程1(移动文件)、2(删除所有空格)、3(文件后缀添加.jpg)、4(删除内容)\"-恢复的\"/\"-副本\"、5(取出前缀、后缀中的内容)(方案1:Still/\"\"方案2:\"\"/.Still)、6(添加前缀)、7(添加后缀)、8(关闭)"
select opt in "${options[@]}"
do
case $opt in
### 选项1将所有在目录下的图片移动到目录中 ###
"Move all pics in dir to dir")
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
# 遍历 标签图片 目录中的所有后缀为 .png 或 .PNG 的文件,将其移动到主目录
find "$ori_label_directory" -not -path "*/error/*" \( -iname "*.png" -o -iname "*.PNG" \) -type f -print0 |
while IFS= read -r -d $'\0' file; do
echo cp -n "$file" "$ori_label_directory"
cp -n "$file" "$ori_label_directory"
done
fi
echo ""
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
# 遍历 原图片 目录中的所有后缀为 .png 或 .PNG 的文件,将其移动到主目录
find "$ori_image_directory" -not -path "*/error/*" \( -iname "*.png" -o -iname "*.PNG" \) -type f -print0 |
while IFS= read -r -d $'\0' file; do
echo cp -n "$file" "$ori_image_directory"
cp -n "$file" "$ori_image_directory"
done
fi
echo -e ""
break
;;
### 选项2替换文件名中的空格 ###
"Delete all space in filename")
# 输入待删除的内容
Del_str=" "
Replace_str=""
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
ls "$ori_image_directory" | grep -e "$Del_str" | awk -v ori_image_directory="$ori_image_directory" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(/ /, ""); print "mv \""ori_image_directory"/"s1"\" \""ori_image_directory"/"$1""Replace_str""$2"\""}'
ls "$ori_image_directory" | grep -e "$Del_str" | awk -v ori_image_directory="$ori_image_directory" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(/ /, ""); print "mv \""ori_image_directory"/"s1"\" \""ori_image_directory"/"$1""Replace_str""$2"\""}' | bash
echo -e ""
else
echo "**** image图片目录不存在: $ori_image_directory ****"
echo -e ""
fi
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
ls "$ori_label_directory" | grep -e "$Del_str" | awk -v ori_label_directory="$ori_label_directory" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(/ /, ""); print "mv \""ori_label_directory"/"s1"\" \""ori_label_directory"/"$1""Replace_str""$2"\""}'
ls "$ori_label_directory" | grep -e "$Del_str" | awk -v ori_label_directory="$ori_label_directory" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(/ /, ""); print "mv \""ori_label_directory"/"s1"\" \""ori_label_directory"/"$1""Replace_str""$2"\""}' | bash
echo -e ""
else
echo "**** label图片目录不存在: $ori_label_directory ****"
echo -e ""
fi
break
;;
### 选项3在无后缀文件后添加.jpg后缀 ###
"Add jpg to no suffix filename")
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
find "$ori_image_directory" -type f ! -name "*.*" | awk -F/ '{print $NF}' | awk -v ori_image_directory="$ori_image_directory" '{print "mv \""ori_image_directory"/"$0"\" \""ori_image_directory"/"$0".jpg\""}'
find "$ori_image_directory" -type f ! -name "*.*" | awk -F/ '{print $NF}' | awk -v ori_image_directory="$ori_image_directory" '{print "mv \""ori_image_directory"/"$0"\" \""ori_image_directory"/"$0".jpg\""}' | bash
echo -e ""
else
echo "**** image图片目录不存在: $ori_image_directory ****"
echo -e ""
fi
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
find "$ori_label_directory" -type f ! -name "*.*" | awk -F/ '{print $NF}' | awk -v ori_label_directory="$ori_label_directory" '{print "mv \""ori_label_directory"/"$0"\" \""ori_label_directory"/"$0".jpg\""}'
find "$ori_label_directory" -type f ! -name "*.*" | awk -F/ '{print $NF}' | awk -v ori_label_directory="$ori_label_directory" '{print "mv \""ori_label_directory"/"$0"\" \""ori_label_directory"/"$0".jpg\""}' | bash
echo -e ""
else
echo "**** label图片目录不存在: $ori_label_directory ****"
echo -e ""
fi
break
;;
### 选项4替换文件名中内容 ###
"Replace content in filename")
# 输入待删除的内容
echo -n "Please input the content to be deleted = "
read -r Del_str
echo -n "Please input the content to be replace(default is None) = "
read -r Replace_str
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
ls "$ori_image_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | grep -e "$Del_str" | awk -v ori_image_directory="$ori_image_directory" -v Del_str="$Del_str" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(Del_str, Replace_str); print "mv \""ori_image_directory"/"s1"\" \""ori_image_directory"/"$0"\""}'
ls "$ori_image_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | grep -e "$Del_str" | awk -v ori_image_directory="$ori_image_directory" -v Del_str="$Del_str" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(Del_str, Replace_str); print "mv \""ori_image_directory"/"s1"\" \""ori_image_directory"/"$0"\""}' | bash
echo -e ""
else
echo "**** image图片目录不存在: $ori_image_directory ****"
echo -e ""
fi
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
ls "$ori_label_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | grep -e "$Del_str" | awk -v ori_label_directory="$ori_label_directory" -v Del_str="$Del_str" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(Del_str, Replace_str); print "mv \""ori_label_directory"/"s1"\" \""ori_label_directory"/"$0"\""}'
ls "$ori_label_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | grep -e "$Del_str" | awk -v ori_label_directory="$ori_label_directory" -v Del_str="$Del_str" -v Replace_str="$Replace_str" -F "$Del_str" '{s1=$0; gsub(Del_str, Replace_str); print "mv \""ori_label_directory"/"s1"\" \""ori_label_directory"/"$0"\""}' | bash
echo -e ""
else
echo "**** label图片目录不存在: $ori_label_directory ****"
echo -e ""
fi
break
;;
### 选项5删除文件名前缀、后缀之间的内容 ###
"Extract filename between prefix and suffix")
# 输入待删除的内容
echo -n "Please input the prefix to be deleted = "
read -r prefix
echo -n "Please input the suffix to be deleted = "
read -r suffix
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
# ls -1 以回车显示
ls -1 "$ori_image_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | grep -e "$prefix" | grep -e "$suffix" | while read file_name; do
# 提取出新的文件名
if [ -z $prefix ];then
file_name_new=$(echo $file_name | sed "s/\(.*\)$suffix.*\(\.jpg\|\.png\|\.bmp\|\.JPG\|\.PNG\|\.BMP\)$/\1\2/")
else
echo "sed "s/^.*$prefix\(.*\)$suffix.*\(\.jpg\|\.png\|\.bmp\|\.JPG\|\.PNG\|\.BMP\)$/\1\2/""
file_name_new=$(echo $file_name | sed "s/^.*$prefix\(.*\)$suffix.*\(\.jpg\|\.png\|\.bmp\|\.JPG\|\.PNG\|\.BMP\)$/\1\2/")
fi
echo "$file_name -> $file_name_new"
echo "mv "$ori_image_directory/$file_name" "$ori_image_directory/$file_name_new""
mv "$ori_image_directory/$file_name" "$ori_image_directory/$file_name_new"
done
# ls "$ori_image_directory" | grep -e "$Del_str" | awk -v ori_image_directory="$ori_image_directory" -v Del_str="$Del_str" '{ s1=$0; match($0, Del_str); sub(substr($0, 1, RSTART + RLENGTH - 1), ""); print "mv \""ori_image_directory"/"s1"\" \""ori_image_directory"/"$0"\""}'
# ls "$ori_image_directory" | grep -e "$Del_str" | awk -v ori_image_directory="$ori_image_directory" -v Del_str="$Del_str" '{ s1=$0; match($0, Del_str); sub(substr($0, 1, RSTART + RLENGTH - 1), ""); print "mv \""ori_image_directory"/"s1"\" \""ori_image_directory"/"$0"\""}' | bash
echo -e ""
else
echo "**** image图片目录不存在: $ori_image_directory ****"
echo -e ""
fi
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
ls -1 "$ori_label_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | grep -e "$prefix" | grep -e "$suffix" | while read file_name; do
# 提取出新的文件名
if [ -z $prefix ];then
file_name_new=$(echo $file_name | sed "s/\(.*\)$suffix.*\(\.jpg\|\.png\|\.bmp\|\.JPG\|\.PNG\|\.BMP\)$/\1\2/")
else
echo "sed "s/^.*$prefix\(.*\)$suffix.*\(\.jpg\|\.png\|\.bmp\|\.JPG\|\.PNG\|\.BMP\)$/\1\2/""
file_name_new=$(echo $file_name | sed "s/^.*$prefix\(.*\)$suffix.*\(\.jpg\|\.png\|\.bmp\|\.JPG\|\.PNG\|\.BMP\)$/\1\2/")
fi
echo "$file_name -> $file_name_new"
echo "mv "$ori_label_directory/$file_name" "$ori_label_directory/$file_name_new""
mv "$ori_label_directory/$file_name" "$ori_label_directory/$file_name_new"
done
# ls "$ori_label_directory" | grep -e "$Del_str" | awk -v ori_label_directory="$ori_label_directory" -v Del_str="$Del_str" '{ s1=$0; match($0, Del_str); sub(substr($0, 1, RSTART + RLENGTH - 1), ""); print "mv \""ori_label_directory"/"s1"\" \""ori_label_directory"/"$0"\""}'
# ls "$ori_label_directory" | grep -e "$Del_str" | awk -v ori_label_directory="$ori_label_directory" -v Del_str="$Del_str" '{ s1=$0; match($0, Del_str); sub(substr($0, 1, RSTART + RLENGTH - 1), ""); print "mv \""ori_label_directory"/"s1"\" \""ori_label_directory"/"$0"\""}' | bash
echo -e ""
else
echo "**** label图片目录不存在: $ori_label_directory ****"
echo -e ""
fi
break
;;
### 选项6在文件名前添加内容 ###
"Add content before filename")
echo -n "Please input the content to be added = "
read Group_str
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
ls "$ori_image_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_image_directory="$ori_image_directory" -v Group_str="$Group_str" '{print "mv \""ori_image_directory"/"$0"\" \""ori_image_directory"/"Group_str""$0"\""}'
ls "$ori_image_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_image_directory="$ori_image_directory" -v Group_str="$Group_str" '{print "mv \""ori_image_directory"/"$0"\" \""ori_image_directory"/"Group_str""$0"\""}' | bash
echo -e ""
else
echo "**** image图片目录不存在: $ori_image_directory ****"
echo -e ""
fi
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
ls "$ori_label_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_label_directory="$ori_label_directory" -v Group_str="$Group_str" '{print "mv \""ori_label_directory"/"$0"\" \""ori_label_directory"/"Group_str""$0"\""}'
ls "$ori_label_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_label_directory="$ori_label_directory" -v Group_str="$Group_str" '{print "mv \""ori_label_directory"/"$0"\" \""ori_label_directory"/"Group_str""$0"\""}' | bash
echo -e ""
else
echo "**** label图片目录不存在: $ori_label_directory ****"
echo -e ""
fi
break
;;
### 选项7在文件名后添加内容 ###
"Add content behand filename")
echo -n "Please input the content to be added = "
read Group_str
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
ls "$ori_image_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_image_directory="$ori_image_directory" -v Group_str="$Group_str" -F . '{print "mv \""ori_image_directory"/"$0"\" \""ori_image_directory"/"substr($0, 1, length($0)-length($NF)-1)""Group_str"."$NF"\""}'
ls "$ori_image_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_image_directory="$ori_image_directory" -v Group_str="$Group_str" -F . '{print "mv \""ori_image_directory"/"$0"\" \""ori_image_directory"/"substr($0, 1, length($0)-length($NF)-1)""Group_str"."$NF"\""}' | bash
echo -e ""
else
echo "**** image图片目录不存在: $ori_image_directory ****"
echo -e ""
fi
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
ls "$ori_label_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_label_directory="$ori_label_directory" -v Group_str="$Group_str" -F . '{print "mv \""ori_label_directory"/"$0"\" \""ori_label_directory"/"substr($0, 1, length($0)-length($NF)-1)""Group_str"."$NF"\""}'
ls "$ori_label_directory" | grep -E "\.(png|jpg|PNG|JPG|BMP|bmp)$" | awk -v ori_label_directory="$ori_label_directory" -v Group_str="$Group_str" -F . '{print "mv \""ori_label_directory"/"$0"\" \""ori_label_directory"/"substr($0, 1, length($0)-length($NF)-1)""Group_str"."$NF"\""}' | bash
echo -e ""
else
echo "**** label图片目录不存在: $ori_label_directory ****"
echo -e ""
fi
break
;;
### 选项8 退出 ###
"Quit")
echo "Exiting..."
exit 0
;;
*)
echo "Invalid option: $REPLY"
echo -e ""
break
;;
esac
done
done

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*
import os, cv2, sys
def transform(input_path, output_path):
for root, dirs, files in os.walk(input_path):
for name in files:
print("2_1_正在检索", os.path.join(root, name))
# 如果图片是jpg图片
if name.endswith('.jpg') or name.endswith('.JPG') :
# convert一下图片
print("convert \""+os.path.join(root, name)+"\" \""+os.path.join(input_path, name)+"\"")
os.system("convert \""+os.path.join(root, name)+"\" \""+os.path.join(input_path, name)+"\"")
file = os.path.join(root, name)
if os.path.basename(root) == 'error':
break
try:
# 读取图片并且改变存储方式
im = cv2.imread(file)
if output_path:
# 压缩度调为0
cv2.imwrite(os.path.join(output_path, name.replace('jpg', 'png').replace('JPG', 'png')), im, [cv2.IMWRITE_PNG_COMPRESSION, 100, cv2.IMWRITE_PNG_COMPRESSION, 0])
else:
print('transform' + file.replace('jpg', 'png').replace('JPG', 'png'))
os.system("rm \""+file+"\"")
# 压缩度调为0
cv2.imwrite(file.replace('jpg', 'png').replace('JPG', 'png'), im, [cv2.IMWRITE_PNG_COMPRESSION, 100, cv2.IMWRITE_PNG_COMPRESSION, 0])
except:
os.system("echo "+file+" >> error.txt")
# 检查文件夹是否存在
if not os.path.exists(os.path.join(root, 'error')):
# 如果不存在,创建文件夹
os.mkdir(os.path.join(root, 'error'))
os.system("mv "+file+" "+os.path.join(root, 'error'))
# 如果图片是jpg图片
if name.endswith('.bmp') or name.endswith('.BMP') :
# convert一下图片
print("convert "+os.path.join(root, name)+" "+os.path.join(input_path, name))
os.system("convert "+os.path.join(root, name)+" "+os.path.join(input_path, name))
file = os.path.join(root, name)
if os.path.basename(root) == 'error':
break
try:
# 读取图片并且改变存储方式
im = cv2.imread(file)
if output_path:
# 压缩度调为0
cv2.imwrite(os.path.join(output_path, name.replace('bmp', 'png').replace('BMP', 'png')), im, [cv2.IMWRITE_PNG_COMPRESSION, 100, cv2.IMWRITE_PNG_COMPRESSION, 0])
else:
print('transform' + os.path.join(root, name.replace('bmp', 'png').replace('BMP', 'png')))
os.system("rm \""+file+"\"")
# 压缩度调为0
cv2.imwrite(os.path.join(root, name.replace('bmp', 'png').replace('BMP', 'png')), im, [cv2.IMWRITE_PNG_COMPRESSION, 100, cv2.IMWRITE_PNG_COMPRESSION, 0])
except:
os.system("echo \""+file+"\" >> error.txt")
# 检查文件夹是否存在
if not os.path.exists(os.path.join(root, 'error')):
# 如果不存在,创建文件夹
os.mkdir(os.path.join(root, 'error'))
os.system("mv \""+file+"\" \""+os.path.join(root, 'error')+"\"")
if __name__ == '__main__':
input_path = sys.argv[1] # './2.C组/Group_label_C0'
output_path = None
if not os.path.exists(input_path):
print("文件夹不存在!")
else:
print("Start to transform 2_1_Trans_to_png!")
transform(input_path, output_path)
print("Transform end 2_1_Trans_to_png!")
print()

View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*
import cv2, sys
import os
break_up = None
break_up_point = False
# 重新改变图像大小
def Resize(input_path, output_path, interpolation=False, default_height=1920, default_width=1080):
global break_up, break_up_point
# 遍历输入路径
for root, dirs, files in os.walk(input_path):
# 遍历所有文件
for name in files:
file = os.path.join(root, name)
if(name == break_up or break_up == None): # 如果没到达断点或者没有断点
break_up_point = True
if break_up_point == False:
continue
if not name.endswith(('.png', '.jpg', '.PNG', '.JPG')):
continue
if os.path.basename(root) == 'error':
break
print("2_2_正在处理", file)
try:
# print("convert "+os.path.join(root, name)+" "+os.path.join(input_path, name))
print("Processing: ","convert \""+file+"\" \""+file+"\"")
status = os.system("convert \""+file+"\" \""+file+"\"") # 改变文件格式
# 如果返回状态不为0则移动对应图片到Error文件夹中
if status != 0:
os.system("echo \""+file+"\" >> error.txt")
# 检查文件夹是否存在
if not os.path.exists(os.path.join(root, 'error')):
# 如果不存在,创建文件夹
os.mkdir(os.path.join(root, 'error'))
os.system("mv \""+file+"\" \""+os.path.join(root, 'error')+'\"')
print("此文件是问题文件 ","mv \""+file+"\" \""+os.path.join(root, 'error')+'\"')
continue
# 读取图片
im = cv2.imread(file)
height, width, channels = im.shape
# 判断高度和宽度是否符合要求
if height == default_height and width == default_width:
print("符合要求")
continue
else:
# 是否满足最近临要求
if interpolation == False:
im = cv2.resize(im, (default_width, default_height))
else:
im = cv2.resize(im, (default_width, default_height),interpolation = cv2.INTER_NEAREST)
# 输出影像
if output_path:
cv2.imwrite(os.path.join(output_path, name), im, [cv2.IMWRITE_PNG_COMPRESSION, 100, cv2.IMWRITE_PNG_COMPRESSION, 0])
else:
print('Resize' + file)
os.system("rm \""+file+"\"") # TODO
# 压缩度调为0
cv2.imwrite(file, im, [cv2.IMWRITE_PNG_COMPRESSION, 100, cv2.IMWRITE_PNG_COMPRESSION, 0])
except:
os.system("echo \""+file+"\" >> error.txt")
# 检查文件夹是否存在
if not os.path.exists(os.path.join(root, 'error')):
# 如果不存在,创建文件夹
os.mkdir(os.path.join(root, 'error'))
os.system("mv \""+file+"\" \""+os.path.join(root, 'error')+"\"")
if __name__ == '__main__':
input_path = sys.argv[1] # './2.C组/Group_label_C0'
output_path = None
try:
default_width = int(sys.argv[3])
except:
default_width = 1920 # 默认宽度
try:
default_height = int(sys.argv[4])
except:
default_height = 1080 # 默认高度
if default_width == 0 or default_height == 0:
print("发生错误default_width、default_height不应该为0")
sys.exit()
interpolation = sys.argv[2] # 最近临插值
if interpolation == "False":
interpolation = False
elif interpolation == "True":
interpolation = True
else:
print("interpolation must be True or False!")
quit
if not os.path.exists(input_path):
print(input_path)
print("文件夹不存在!")
else:
print("Start to transform_2_2_Resize.py!")
print(input_path, output_path, default_height,default_width)
Resize(input_path, output_path, interpolation=interpolation, default_height=default_height, default_width=default_width)
print("Transform end_2_2_Resize.py!")

View File

@@ -0,0 +1,118 @@
#!/bin/bash
usage() {
echo "Usage: $0 -i <ori_image_directory> -l <ori_label_directory> -w <width_of_pic> -h <height_of_pic> [-help]"
echo "对image图片和label图片进行处理将其转为PNG格式并调整图片的宽和高和格式"
echo "-i:原始图片的路径,-l:原始标签的路径,-w:图片宽度,-h:图片高度,-help帮助"
}
ori_image_directorys=""
ori_label_directorys=""
pic_width=1920
pic_height=1080
while getopts "l:i:h:w:" opt; do
case $opt in
h)
if [[ $OPTARG =~ ^-?[0-9]+$ ]];then
pic_height=$OPTARG
echo pic_height is $pic_height
elif [ $OPTARG == 'elp' ];then
usage
exit 0
else
echo "-h(pic_height)必须为整数"
usage
exit 1
fi
;;
i)
ori_image_directorys=$OPTARG
;;
l)
ori_label_directorys=$OPTARG
;;
w)
if [[ $OPTARG =~ ^-?[0-9]+$ ]];then
pic_width=$OPTARG
echo pic_width is $pic_width
else
echo "-w(pic_height)必须为整数"
usage
exit 1
fi
;;
*)
echo -e '\033[31m!!! Error, Illegal input !!!\033[0m'
usage
exit 1
;;
esac
done
# 判断输入地址是否都为空
if [ -z "$ori_label_directorys" ] && [ -z "$ori_image_directorys" ]; then
echo -e "\033[31m输入地址 -i -l 都为空\033[0m"
usage
exit 1
fi
# 地址转化
ori_image_directory=$(readlink -f "$ori_image_directorys")
ori_label_directory=$(readlink -f "$ori_label_directorys")
if [ -z "$ori_label_directory" ] && [ -z "$ori_image_directory" ]; then
echo "无法解析地址,程序退出"
echo -e "\033[31mori_image_directory\033[0m: $ori_image_directorys"
echo -e "\033[31mori_label_directory\033[0m: $ori_label_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_directorys"
echo -e "\033[31mori_label_directory\033[0m: $ori_label_directorys"
exit 1
fi
echo -e "\033[32m_____ 2_reformate_data.sh _____\033[0m"
# 获取当前脚本的路径和名称
script_path=$(dirname "$0")
# 将当前目录更改为脚本所在的路径
cd "$script_path"
# 激活conda环境
source /home/"$USER"/miniconda/bin/activate Deal_pics
# 判断image图片路径是否存在
if [ -d "$ori_image_directory" ]; then
echo "**** Processing ori_image_directory: $ori_image_directory ****"
echo "1.Trans pics to png"
python 2_1_Trans_to_png.py "$ori_image_directory"
echo -e ""
echo "2.Resize image pics with nearest"
echo -e "\033[35m运行\033[0mpython 2_2_Resize.py "$ori_image_directory" False $pic_width $pic_height "
python 2_2_Resize.py "$ori_image_directory" False $pic_width $pic_height # False 是不使用最近邻插值
echo -e ""
else
echo "**** image图片目录不存在: $ori_image_directory ****"
echo -e ""
fi
# 判断label图片路径是否存在
if [ -d "$ori_label_directory" ]; then
echo "**** Processing ori_label_directory: $ori_label_directory ****"
echo -e "\033[33m__ 1.Trans pics to png __\033[0m"
echo -e "\033[35m运行\033[0mpython 2_1_Trans_to_png.py "$ori_label_directory""
python 2_1_Trans_to_png.py "$ori_label_directory"
echo -e ""
echo -e "\033[33m__ 2.Resize label pics without nearest __\033[0m"
echo -e "\033[35m运行\033[0mpython 2_2_Resize.py "$ori_label_directory" True $pic_width $pic_height"
python 2_2_Resize.py "$ori_label_directory" True $pic_width $pic_height # True 是使用最近邻插值
echo -e ""
else
echo -e "\033[33m**** label图片目录不存在: $ori_image_directory ****\033[0m"
echo -e ""
fi
source /home/"$USER"/miniconda/bin/deactivate

View File

@@ -0,0 +1,186 @@
#!/bin/bash
usage() {
echo "Usage: $0 -i <ori_image_directory> -l <ori_label_directory> [ -p <prefix> -s <suffix> -h]"
echo "对image图片和label图片进行匹配-i、-l均不能为空-p -s默认为空"") "
echo "-i:原始image的路径-l:原始label的路径-p:前缀内容,-s:后缀内容(不用管文件后缀名)-h:帮助"
echo "e.g. 3_pair_ori_label.sh -i ./C组未标注 -l ./C组标注图片 -p Group_C_ -s _label"
}
ori_image_directorys=""
ori_label_directorys=""
prefix=""
suffix=""
while getopts "hl:i:p:s:" 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
;;
*)
echo "$opt"
echo -e '\033[31m!!! Error, Illegal input !!!\033[0m'
usage
exit 1
;;
esac
done
# 判断输入地址是否为空
if [ -z "$ori_label_directorys" ] || [ -z "$ori_image_directorys" ]; then
echo -e "\033[31m输入地址 -i -l 存在空地址\033[0m"
usage
exit 1
fi
# 地址转化
ori_image_directory=$(readlink -f "$ori_image_directorys")
ori_label_directory=$(readlink -f "$ori_label_directorys")
if [ -z "$ori_label_directory" ] || [ -z "$ori_image_directory" ]; then
echo "无法解析地址,程序退出"
echo -e "\033[31mori_image_directory\033[0m: $ori_image_directorys"
echo -e "\033[31mori_label_directory\033[0m: $ori_label_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_directorys"
echo -e "\033[31mori_label_directory\033[0m: $ori_label_directorys"
exit 1
fi
# 获取当前脚本的路径和名称
script_path=$(dirname "$0")
# 将当前目录更改为脚本所在的路径
cd "$script_path"
echo -e "\033[32m_____ 3_pair_ori_label.sh _____\033[0m"
# find -name 中"*"表示通配,与'.*'不同
# 遍历img目录
for file_path in "$ori_image_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
echo "$file_name -> $file_name_extract"
# 从label目录中看是否有此文件sed匹配时$suffix后要有.*
if [ -z $prefix ];then
file_name_other=$(ls $ori_label_directory | grep $file_name_extract | sed "s/"$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
else
file_name_other=$(ls $ori_label_directory | grep $file_name_extract | sed "s/".*$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
fi
# 如果另一个目录没有此文件的话
if [ -z "$file_name_other" ]; then
echo "$file_name image中内容未在$ori_label_directory搜索到"
# 建立相关存储文件夹
if [ ! -d "$ori_image_directory/Not_pair_pics" ]; then
mkdir -p "$ori_image_directory/Not_pair_pics" # 建立存储文件夹
fi
# 移动相关文件
echo "$file_name" >> "$ori_image_directory/Not_pair_pics/not_pair.txt"
mv "$ori_image_directory/$file_name" "$ori_image_directory/Not_pair_pics"
fi
fi
fi
done
# 遍历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
echo "$file_name -> $file_name_extract"
# 从image目录中看是否有此文件
if [ -z $prefix ];then
file_name_other=$(ls $ori_image_directory | grep $file_name_extract | sed "s/"$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
else
file_name_other=$(ls $ori_image_directory | grep $file_name_extract | sed "s/".*$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
fi
# 如果另一个目录没有此文件的话
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
# 移动相关文件
mv "$ori_label_directory/$file_name" "$ori_label_directory/Not_pair_pics"
echo "$file_name" >> "$ori_label_directory/Not_pair_pics/not_pair.txt"
fi
fi
fi
done
# 第二次遍历img目录
for file_path in "$ori_image_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
echo "$file_name -> $file_name_extract"
# 从label目录中看是否有此文件sed匹配时$suffix后要有.*
if [ -z $prefix ];then
file_name_other=$(ls $ori_label_directory | grep $file_name_extract | sed "s/"$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
else
file_name_other=$(ls $ori_label_directory | grep $file_name_extract | sed "s/".*$prefix"\(.*\)"$suffix".*/\1/" | sed "s/\(.*\)\.\(jpg\|png\|bmp\|JPG\|PNG\|BMP\)$/\1/")
fi
# 如果另一个目录没有此文件的话
if [ -z "$file_name_other" ]; then
echo "$file_name image中内容未在$ori_label_directory搜索到"
# 建立相关存储文件夹
if [ ! -d "$ori_image_directory/Not_pair_pics" ]; then
mkdir -p "$ori_image_directory/Not_pair_pics" # 建立存储文件夹
fi
# 移动相关文件
echo "$file_name" >> "$ori_image_directory/Not_pair_pics/not_pair.txt"
mv "$ori_image_directory/$file_name" "$ori_image_directory/Not_pair_pics"
fi
fi
fi
done

View File

@@ -0,0 +1,445 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*
import os,time,sys,threading, colorsys, argparse
import asyncio, cv2, multiprocessing, random
from PIL import Image
import numpy as np
from Tool_deal_labels import edge_detection, detect_connected_regions, Tool_color_connected_array, fill_white_regions, color_connected_regions
def getFileList(dir,Filelist=[], ext=None, Max_layer=1, layer=0, Donot_Search=['1_边缘检测并膨胀', '2_连通区域检测', '3_分水岭算法填充']):
"""
获取文件夹及其子文件夹中文件列表
输入 dir文件夹根目录
输入 ext: 扩展名
返回: 文件路径列表
"""
newDir = dir
if os.path.isfile(dir):
if ext is None:
Filelist.append(dir)
else:
if ext in dir[-3:]:
Filelist.append(dir)
elif os.path.isdir(dir):
file_name = os.path.basename(dir)
# 判断是否在禁搜名单中
if file_name in Donot_Search:
return Filelist
for s in os.listdir(dir):
newDir=os.path.join(dir,s)
if layer <= Max_layer:
getFileList(newDir, Filelist, ext, Max_layer, layer+1)
return Filelist
class Deal_image():
def __init__(self, Annotate_CLASSES = ('肝脏','胆囊'), Annotate_PALETTE = [[255,91,0],[255,234,0]], src_label_fold = "./Label", save_pro_label_fold = "./LABEL_PNG_new", save_GT_label_fold = "./Label_Generate", GT_channel = 1, pro_append_name="_label", GT_append_name="_gtFine_labelTrainIds", ori_img_folder="./ORI_PNG", res_label_folder="./Result_label", save_merge_pic_folder="./Result_merge", back_gnd_color=0, first_class_color=1, pic_type="png", Max_width = 10000, Label_Max_Search_layer=1000, save_process_pics=False, bg_PALETTE = [0,0,0]):
# 背景最好放在最后
# self.src_CLASSES = ('肝脏','胆囊','分离钳','止血海绵','肝总管','胆总管','吸引器','剪刀','止血纱布','生物夹','无损伤钳','喷洒','胆囊管','胆囊动脉','电凝','标本袋','引流管','纱布','金属钛夹','术中超声','吻合器','乳胶管','推结器','肝带','钳夹','超声刀','脂肪','双极电凝','棉球','血管阻断夹','肿瘤','针','线','韧带','胆囊静脉','背景')
# self.src_PALETTE = np.array([[255,91,0],[255,234,0],[85, 111, 181],[181, 227, 14],[72, 0, 255],[0, 155, 33],[255,0,255],[29, 32, 136],[160, 15, 95],[0,160,233],[52,184,178],[90,120,41],[255,0,0],[177,0,0],[167,24,233],[112,113,150],[0,255,0],[255,255,255],[0,255,255],[138,251,213],[136,162,196],[197,83,181],[202,202,200],[113,102,140],[66,115,82],[240,16,116],[155,132,0],[155,62,0],[146,175,236],[255,172,159],[245,161,0],[134,124,118], [0,157,142], [181,85,105], [42,8,66],[0,0,0]])
# self.src_CLASSES_NUM = np.shape(self.src_CLASSES)[0]
self.bg_PALETTE = bg_PALETTE # 背景颜色 TODO
self.Annotate_CLASSES = Annotate_CLASSES # 待分类的类
self.Annotate_PALETTE = np.array(Annotate_PALETTE) # 每一类的像素直
self.Annotate_CLASSES_NUM = np.shape(Annotate_CLASSES)[0] # 类数量
self.save_process_pics = save_process_pics # 保存中间过程图片
self.src_label_fold = src_label_fold # 原始标签图片 保存位置
self.save_pro_label_fold = save_pro_label_fold # 优化后标签图片 保存位置
self.save_GT_label_fold = save_GT_label_fold # GT标签图片 保存位置
self.ori_img_folder = ori_img_folder # 最原始手术图片 保存位置
self.res_label_folder = res_label_folder # 训练出来的label 保存位置
self.save_merge_pic_folder = save_merge_pic_folder # 融合图像保存位置
self.pro_append_name = pro_append_name # 优化后标签图片后缀
self.GT_append_name = GT_append_name # GT标签图片后缀
self.GT_channel = GT_channel # GT标签图片通道数
self.Max_width = Max_width # 最大图片宽度(匹配时候用)
self.pic_type = pic_type # 图片类型
self.back_gnd_color = back_gnd_color # 背景颜色
self.first_class_color = first_class_color # 第一类上的颜色
self.Label_Max_Search_layer=Label_Max_Search_layer # 文件夹最大搜索深度
try:
self.labellist_src = getFileList(src_label_fold, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到ori_label图片 '+str(len(self.labellist_src))+' 张图像')
except:
self.labellist_src = None
print("没有ori_label相关文件")
try:
# print(save_pro_label_fold)
self.labellist_pro = getFileList(save_pro_label_fold, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到pro_label图片 '+str(len(self.labellist_pro))+' 张图像')
except:
self.labellist_pro = None
print("没有pro_label相关文件")
try:
self.imglist_src = getFileList(ori_img_folder, [], pic_type, self.Label_Max_Search_layer)
self.reslist_src = getFileList(res_label_folder, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到ori原始图片 '+str(len(self.imglist_src))+' 张图像')
print('本次执行检索到训练train_result图片 '+str(len(self.reslist_src))+' 张图像')
except:
self.imglist_src = None
self.reslist_src = None
print("没有train_result和原始图片相关文件")
# 获取单张图片各个通路信息
def get_single_pic_rgb(self, imgpath):
print(imgpath)
image = Image.open(imgpath).convert('RGB') # 转为RGB图片
# 将 RGB 色值分离
image.load()
r, g, b = image.split()
r = np.array(r)
g = np.array(g)
b = np.array(b)
return image, r, g, b
# 将单个pro图片变成GT图片
def Conver_pro_label_pic_2_GT_pic(self, imgpath, imgname):
time_start=time.time() # 记录开始时间
# 获取单张图片各个通路信息
image, r,g,b = self.get_single_pic_rgb(imgpath)
result_gt = np.ones(np.shape(image))*self.back_gnd_color # 初始化填充内容为back_gnd_color
gt_number = self.first_class_color # 第一类上色颜色确定
# PALETTE中排除掉 '背景' [0,0,0]
PALETTE_No_Bg = self.Annotate_PALETTE[~np.all(self.Annotate_PALETTE == self.bg_PALETTE, axis=1)]
# 遍历所有待识别颜色
for [Annotate_PALETTE_r, Annotate_PALETTE_g, Annotate_PALETTE_b] in PALETTE_No_Bg:
# 查找三原色匹配位置
locate_r = np.where( r == Annotate_PALETTE_r )
locate_g = np.where( g == Annotate_PALETTE_g )
locate_b = np.where( b == Annotate_PALETTE_b )
# 查找都匹配位置(交集)
# 将矩阵换一种表示形式
locate_r = np.array(locate_r[0]) * Max_width + np.array(locate_r[1])
locate_g = np.array(locate_g[0]) * Max_width + np.array(locate_g[1])
locate_b = np.array(locate_b[0]) * Max_width + np.array(locate_b[1])
# 用自带函数寻找匹配项
matched = np.intersect1d(np.intersect1d(locate_r, locate_g), locate_b)
matched = np.concatenate(([matched // self.Max_width], [np.mod(matched, self.Max_width)]), 0)
result_gt[matched[0],matched[1], :] = gt_number
gt_number = gt_number + 1
# 输出GT图片
if(int(self.GT_channel) == 1):
result_gt = result_gt[:,:,0]
elif(int(self.GT_channel) == 3):
result_gt = cv2.cvtColor(np.float32(result_gt), cv2.COLOR_RGB2BGR) # rgb颜色互换
else:
print("GT_channel 必须为1或3")
quit
try: # 新建文件夹
os.mkdir(self.save_GT_label_fold)
except:
print("已有"+self.save_GT_label_fold)
if imgname.lower().endswith(('.jpg', '.png')):
save_dir = os.path.join(self.save_GT_label_fold, os.path.basename(imgname).rpartition('.')[0]+self.GT_append_name+'.'+self.pic_type)
else:
save_dir = os.path.join(self.save_GT_label_fold, os.path.basename(imgname)+self.GT_append_name+'.'+self.pic_type)
cv2.imwrite(save_dir, result_gt)
print("GT图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 将处理好的图片转化为GT图片
def Conver_pro_label_pic_2_GT_pic_all(self):
print("\033[33m**** 进行转换将Pro_label_pic转换为GT_label_pic ****\033[0m")
print("\033[33mPro_label_pic存储位置为\033[0m", self.save_pro_label_fold)
print("\033[33mGT_label_pic生成位置为\033[0m", self.save_GT_label_fold)
try:
# print(save_pro_label_fold)
self.labellist_pro = getFileList(save_pro_label_fold, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到pro_label图片 '+str(len(self.labellist_pro))+' 张图像')
except:
self.labellist_pro = None
print("没有pro_label相关文件")
try:
os.mkdir(self.save_GT_label_fold) # 新建存储文件夹
except:
print("已有"+self.save_GT_label_fold)
# 指定最大进程数为 3
max_processes = 20
# 创建Pool对象
pool = multiprocessing.Pool(processes=max_processes)
# 创建并启动进程
args_list1 = []
args_list2 = []
# 遍历整个文件夹
for imgpath in self.labellist_pro:
imgname = os.path.basename(imgpath).rpartition('.')[0].replace(self.pro_append_name,"")
args_list1.append(imgpath)
args_list2.append(imgname)
args_list = zip(args_list1, args_list2)
# 使用进程池并行执行任务
pool.starmap(self.Conver_pro_label_pic_2_GT_pic, args_list)
# 关闭进程池
pool.close()
pool.join()
def Conver_ori_label_pic_2_pro_pic(self, imgpath, imgname):
time_start=time.time() # 记录开始时间
# 获取单张图片各个通路信息
image = cv2.imread(imgpath)
# 1. 边缘检测并膨胀
dilated_image = edge_detection(image)
# 如果需要存储中间态图片
if(self.save_process_pics == True):
if imgname.lower().endswith(('.jpg', '.png')):
save_dir = os.path.join(self.save_pro_label_fold, '1_边缘检测并膨胀', os.path.basename(imgname).rpartition('.')[0]+self.pro_append_name+'_Edge'+'.'+self.pic_type)
else:
save_dir = os.path.join(self.save_pro_label_fold, '1_边缘检测并膨胀', os.path.basename(imgname)+self.pro_append_name+'_Edge'+'.'+self.pic_type)
cv2.imwrite(save_dir, dilated_image)
print("中间态-边缘检测并膨胀 图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 2. 检测连通区域
filtered_labeled_array, _ = detect_connected_regions(dilated_image)
colored_image_filtered = Tool_color_connected_array(filtered_labeled_array)
# 如果需要存储中间态图片
if(self.save_process_pics == True):
if imgname.lower().endswith(('.jpg', '.png')):
save_dir = os.path.join(self.save_pro_label_fold, '2_连通区域检测', os.path.basename(imgname).rpartition('.')[0]+self.pro_append_name+'_Region'+'.'+self.pic_type)
else:
save_dir = os.path.join(self.save_pro_label_fold, '2_连通区域检测', os.path.basename(imgname)+self.pro_append_name+'_Region'+'.'+self.pic_type)
cv2.imwrite(save_dir, colored_image_filtered)
print("中间态-连通区域检测 图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 3. 分水岭填充白色区域
filled_labeled_array = fill_white_regions(filtered_labeled_array)
colored_image_filled = Tool_color_connected_array(filled_labeled_array)
# 如果需要存储中间态图片
if(self.save_process_pics == True):
if imgname.lower().endswith(('.jpg', '.png')):
save_dir = os.path.join(self.save_pro_label_fold, '3_分水岭算法填充', os.path.basename(imgname).rpartition('.')[0]+self.pro_append_name+'_FillEdge'+'.'+self.pic_type)
else:
save_dir = os.path.join(self.save_pro_label_fold, '3_分水岭算法填充', os.path.basename(imgname)+self.pro_append_name+'_FillEdge'+'.'+self.pic_type)
cv2.imwrite(save_dir, colored_image_filled)
print("中间态-分水岭算法填充 图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 4. 对连通区域最终上色
ori_labeled_image = image
result_pro = color_connected_regions(filled_labeled_array, filtered_labeled_array, ori_labeled_image, self.Annotate_PALETTE)
if imgname.lower().endswith(('.jpg', '.png')):
save_dir = os.path.join(self.save_pro_label_fold, os.path.basename(imgname).rpartition('.')[0]+self.pro_append_name+'.'+self.pic_type)
else:
save_dir = os.path.join(self.save_pro_label_fold, os.path.basename(imgname)+self.pro_append_name+'.'+self.pic_type)
print("Pro图片已保存", save_dir)
cv2.imwrite(save_dir, result_pro)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 将原始src图片转化为处理好的pro图片
def Conver_ori_label_pic_2_pro_pic_all(self):
print("\033[33m**** 进行转换将Ori_label_pic转换为Pro_label_pic ****\033[0m")
print("\033[33mOri_label_pic存储位置为\033[0m", self.src_label_fold)
print("\033[33mPro_label_pic生成位置为\033[0m", self.save_pro_label_fold)
# 输出颜色预处理图片
try:
os.mkdir(self.save_pro_label_fold) # 新建存储文件夹
except:
print("已有"+self.save_pro_label_fold)
if(self.save_process_pics == True):
try:
os.mkdir(os.path.join(self.save_pro_label_fold, '1_边缘检测并膨胀')) # 新建存储1_边缘检测并膨胀文件夹
except:
print("已有"+os.path.join(self.save_pro_label_fold, '1_边缘检测并膨胀'))
try:
os.mkdir(os.path.join(self.save_pro_label_fold, '2_连通区域检测')) # 新建存储2_连通区域检测文件夹
except:
print("已有"+os.path.join(self.save_pro_label_fold, '2_连通区域检测'))
try:
os.mkdir(os.path.join(self.save_pro_label_fold, '3_分水岭算法填充')) # 新建存储1_边缘检测并膨胀文件夹
except:
print("已有"+os.path.join(self.save_pro_label_fold, '3_分水岭算法填充'))
# 指定最大进程数为 20多参数函数并行
max_processes = 20
# 创建Pool对象
pool = multiprocessing.Pool(processes=max_processes)
# 创建并启动进程
args_list1 = []
args_list2 = []
# 遍历整个文件夹
for imgpath in self.labellist_src:
if imgpath.lower().endswith(('.jpg', '.png')):
imgname= os.path.basename(imgpath).rpartition('.')[0].replace(self.pro_append_name,"")
else:
imgname= os.path.basename(imgpath).replace(self.pro_append_name,"")
try:
print("Processing: ", imgname, "...")
# self.Conver_ori_label_pic_2_pro_pic(imgpath, imgname)s
# args_list.append({'imgpath': imgpath, 'imgname': imgname})
args_list1.append(imgpath)
args_list2.append(imgname)
except:
os.system("echo "+imgname+" >> error_1.txt")
args_list = zip(args_list1, args_list2)
# 使用进程池并行执行任务
pool.starmap(self.Conver_ori_label_pic_2_pro_pic, args_list) # 使用starmap进行多参数并行
# 关闭进程池
pool.close()
pool.join()
# 图片堆叠
def Merge_ori_pic_and_label_pic(self, res_img_path, res_imgname):
time_start=time.time() # 记录开始时间
# 获取单张图片各个通路信息
ori_img_path = os.path.join(self.ori_img_folder, res_imgname+'.'+self.pic_type)
if not os.path.exists(ori_img_path):
print("****照片不存在:****", ori_img_path)
return -1
ori_image, ori_r, ori_g, ori_b = self.get_single_pic_rgb(ori_img_path)
res_image, res_r, res_g, res_b = self.get_single_pic_rgb(res_img_path)
merge_img = np.array(ori_image) # merge图片初始化默认图片背景为0.0.0
# 遍历所有待识别颜色
for [Annotate_PALETTE_r, Annotate_PALETTE_g, Annotate_PALETTE_b] in self.Annotate_PALETTE:
# 查找三原色匹配位置
locate_r = np.where( res_r == Annotate_PALETTE_r )
locate_g = np.where( res_g == Annotate_PALETTE_g )
locate_b = np.where( res_b == Annotate_PALETTE_b )
# 查找都匹配位置(交集)
# 将矩阵换一种表示形式
locate_r = np.array(locate_r[0]) * self.Max_width + np.array(locate_r[1])
locate_g = np.array(locate_g[0]) * self.Max_width + np.array(locate_g[1])
locate_b = np.array(locate_b[0]) * self.Max_width + np.array(locate_b[1])
# 用自带函数寻找匹配项
matched = np.intersect1d(np.intersect1d(locate_r, locate_g), locate_b)
matched = np.concatenate(([matched // self.Max_width], [np.mod(matched, self.Max_width)]), 0)
merge_img[matched[0],matched[1], 0] = Annotate_PALETTE_r
merge_img[matched[0],matched[1], 1] = Annotate_PALETTE_g
merge_img[matched[0],matched[1], 2] = Annotate_PALETTE_b
# 转成cv2形式
merge_img = cv2.cvtColor(np.float32(merge_img), cv2.COLOR_RGB2BGR)
try: # 新建文件夹
os.mkdir(self.save_merge_pic_folder)
except:
print("已有"+self.save_merge_pic_folder)
if res_imgname.lower().endswith(('.jpg', '.png')):
save_dir = os.path.join(self.save_merge_pic_folder, os.path.basename(res_imgname).rpartition('.')[0]+'.'+self.pic_type)
else:
save_dir = os.path.join(self.save_merge_pic_folder, os.path.basename(res_imgname)+'.'+self.pic_type)
cv2.imwrite(save_dir, merge_img)
print("Merge图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 将label图片与原图片重合
def Merge_ori_pic_and_label_pic_all(self):
# 遍历整个文件夹
for res_img_path in self.reslist_src:
if res_img_path.lower().endswith(('.jpg', '.png')):
res_imgname = os.path.basename(res_img_path).rpartition('.')[0].replace(self.pro_append_name,"")
else:
res_imgname = os.path.basename(res_img_path).replace(self.pro_append_name,"")
print("Processing: ", res_imgname, "...")
self.Merge_ori_pic_and_label_pic(res_img_path, res_imgname)
if __name__ == "__main__":
Annotate_CLASSES = ('肝脏','胆囊','分离钳','止血海绵','肝总管','胆总管','吸引器','剪刀','止血纱布','生物夹','无损伤钳','喷洒','胆囊管','胆囊动脉','电凝','标本袋','引流管','纱布','金属钛夹','术中超声','吻合器','乳胶管','推结器','肝带','钳夹','超声刀','脂肪','双极电凝','棉球','血管阻断夹','肿瘤','','线','韧带','胆囊静脉','背景') # 待分类的类
Annotate_PALETTE = [[255,91,0],[255,234,0],[85, 111, 181],[181, 227, 14],[72, 0, 255],[0, 155, 33],[255,0,255],[29, 32, 136],[160, 15, 95],[0,160,233],[52,184,178],[90,120,41],[255,0,0],[177,0,0],[167,24,233],[112,113,150],[0,255,0],[255,255,255],[0,255,255],[138,251,213],[136,162,196],[197,83,181],[202,202,200],[113,102,140],[66,115,82],[240,16,116],[155,132,0],[155,62,0],[146,175,236],[255,172,159],[245,161,0],[134,124,118], [0,157,142], [181,85,105], [42,8,66],[0,0,0]] # 每一类的像素直
bg_PALETTE = [0,0,0] # 背景的RGB
# 创建参数解析器
parser = argparse.ArgumentParser(description='Process some files.')
# 添加参数选项
parser.add_argument('-src_fold', dest='src_label_fold', default='', help='source label folder')
parser.add_argument('-save_pro_fold', dest='save_pro_label_fold', default='./save_pro_label_fold', help='processed label folder')
parser.add_argument('-save_GT_fold', dest='save_GT_label_fold', default='./save_GT_label_fold', help='ground truth folder')
parser.add_argument('-fold_search_depth', dest='Label_Max_Search_layer', default='1000', type=int, help='Folder Search Depth')
parser.add_argument('-pro_suffix_name', dest='pro_append_name', default='_label', help='Pro file suffix')
parser.add_argument('-GT_suffix_name', dest='GT_append_name', default='_gtFine_labelTrainIds', help='GT file suffix')
parser.add_argument('-GT_channel', dest='GT_channel', default='1', type=int, help='GT file channel(1 or 3)')
parser.add_argument('-back_gnd_color', dest='back_gnd_color', default='0', type=int, help='Color of "Back ground"(0 or 255)')
parser.add_argument('-first_class_color', dest='first_class_color', default='1', type=int, help='Color of "First Class"')
parser.add_argument('-pic_type', dest='pic_type', default='png', help='type of picture(Do not add ".")')
parser.add_argument('-Max_width', dest='Max_width', default='10000', type=int, help='Max width of picture')
parser.add_argument('-Rebuild_from', dest='Rebuild_from', default='label', help='Source to Rebuild Labels(label/pro)')
parser.add_argument('-Rebuild_to', dest='Rebuild_to', default='GT', help='Destination of Rebuild Labels(pro/GT)')
parser.add_argument('-save_process_pics', dest='save_process_pics', default='False', help='Save the processed pics(e.g.Gray_pics,Color_pics) in generating pro_pics')
# 解析命令行参数
args = parser.parse_args()
src_label_fold = args.src_label_fold
save_pro_label_fold = args.save_pro_label_fold
save_GT_label_fold = args.save_GT_label_fold
Label_Max_Search_layer = args.Label_Max_Search_layer
pro_append_name = args.pro_append_name
GT_append_name = args.GT_append_name
GT_channel = args.GT_channel
back_gnd_color = args.back_gnd_color
first_class_color = args.first_class_color
pic_type = args.pic_type
Max_width = args.Max_width
Rebuild_from = args.Rebuild_from
Rebuild_to = args.Rebuild_to
save_process_pics = args.save_process_pics
try: # 遍历文件深度最小为1
Label_Max_Search_layer=int(Label_Max_Search_layer)
except:
Label_Max_Search_layer=1000
try: # GT标签图片通道数
GT_channel=int(GT_channel)
except:
GT_channel=1
try: # 背景颜色背景选择0或255)
back_gnd_color=int(back_gnd_color)
except:
back_gnd_color=0
try: # 第一类上的颜色(如果背景为0,选择1)
first_class_color=int(first_class_color)
except:
first_class_color=1
try: # 最大图片宽度(匹配时候用)
Max_width=int(Max_width)
except:
Max_width=10000
if(save_process_pics.lower() == 'false'):
save_process_pics = False
elif(save_process_pics.lower() == 'true'):
save_process_pics = True
else:
save_process_pics = False
D = Deal_image(Annotate_CLASSES=Annotate_CLASSES, Annotate_PALETTE=Annotate_PALETTE, src_label_fold=src_label_fold, save_pro_label_fold=save_pro_label_fold, save_GT_label_fold=save_GT_label_fold, GT_channel=GT_channel, pro_append_name=pro_append_name, GT_append_name=GT_append_name, back_gnd_color=back_gnd_color, first_class_color=first_class_color, pic_type=pic_type, Max_width=Max_width, Label_Max_Search_layer=Label_Max_Search_layer, save_process_pics=save_process_pics, bg_PALETTE = bg_PALETTE)
# print(D.src_CLASSES_NUM)
if Rebuild_from == 'label':
# 1.先将所有原始图片转为pro图片
D.Conver_ori_label_pic_2_pro_pic_all()
pass
if Rebuild_to == 'GT':
# 2.再将pro图片转为GT图片
D.Conver_pro_label_pic_2_GT_pic_all()
pass

View File

@@ -0,0 +1,463 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*
import os,time,sys,threading, colorsys, argparse
import asyncio, cv2, multiprocessing
from PIL import Image
import numpy as np
def getFileList(dir,Filelist=[], ext=None, Max_layer=1, layer=0, Donot_Search=['1_颜色预处理', '2_灰度化', '3_边缘化']):
"""
获取文件夹及其子文件夹中文件列表
输入 dir文件夹根目录
输入 ext: 扩展名
返回: 文件路径列表
"""
newDir = dir
if os.path.isfile(dir):
if ext is None:
Filelist.append(dir)
else:
if ext in dir[-3:]:
Filelist.append(dir)
elif os.path.isdir(dir):
file_name = os.path.basename(dir)
# 判断是否在禁搜名单中
if file_name in Donot_Search:
return Filelist
for s in os.listdir(dir):
newDir=os.path.join(dir,s)
if layer <= Max_layer:
getFileList(newDir, Filelist, ext, Max_layer, layer+1)
return Filelist
class Deal_image():
def __init__(self, Annotate_CLASSES = ('肝脏','胆囊'), Annotate_PALETTE = [[255,91,0],[255,234,0]], src_label_fold = "./Label", save_pro_label_fold = "./LABEL_PNG_new", save_GT_label_fold = "./Label_Generate", GT_channel = 1, pro_append_name="_label", GT_append_name="_gtFine_labelTrainIds", ori_img_folder="./ORI_PNG", res_label_folder="./Result_label", save_merge_pic_folder="./Result_merge", back_gnd_color=0, first_class_color=1, pic_type="png", Max_width = 10000, Label_Max_Search_layer=1000, save_process_pics=False):
self.src_CLASSES = ('肝脏','胆囊','分离钳','止血海绵','肝总管','胆总管','吸引器','剪刀','止血纱布','生物夹','无损伤钳','喷洒','胆囊管','胆囊动脉','电凝','标本袋','引流管','纱布','金属钛夹','背景')
self.src_PALETTE = np.array([[255,91,0],[255,234,0],[85, 107, 179],[181, 227, 14],[72, 0, 255],[0, 155, 33],[255,0,255],[29, 32, 136],[160, 15, 95],[0,160,233],[52,184,178],[90,120,41],[255,0,0],[177,0,0],[167,24,233],[112,113,150],[0,255,0],[255,255,255],[0,255,255],[0,0,0]])
self.src_CLASSES_NUM = np.shape(self.src_CLASSES)[0]
self.Annotate_CLASSES = Annotate_CLASSES # 待分类的类
self.Annotate_PALETTE = np.array(Annotate_PALETTE) # 每一类的像素直
self.Annotate_CLASSES_NUM = np.shape(Annotate_CLASSES)[0] # 类数量
self.save_process_pics = save_process_pics # 保存中间过程图片
self.src_label_fold = src_label_fold # 原始标签图片 保存位置
self.save_pro_label_fold = save_pro_label_fold # 优化后标签图片 保存位置
self.save_GT_label_fold = save_GT_label_fold # GT标签图片 保存位置
self.ori_img_folder = ori_img_folder # 最原始手术图片 保存位置
self.res_label_folder = res_label_folder # 训练出来的label 保存位置
self.save_merge_pic_folder = save_merge_pic_folder # 融合图像保存位置
self.pro_append_name = pro_append_name # 优化后标签图片后缀
self.GT_append_name = GT_append_name # GT标签图片后缀
self.GT_channel = GT_channel # GT标签图片通道数
self.Max_width = Max_width # 最大图片宽度(匹配时候用)
self.pic_type = pic_type # 图片类型
self.back_gnd_color = back_gnd_color # 背景颜色
self.first_class_color = first_class_color # 第一类上的颜色
self.Label_Max_Search_layer=Label_Max_Search_layer # 文件夹最大搜索深度
try:
self.labellist_src = getFileList(src_label_fold, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到ori_label图片 '+str(len(self.labellist_src))+' 张图像')
except:
self.labellist_src = None
print("没有ori_label相关文件")
try:
# print(save_pro_label_fold)
self.labellist_pro = getFileList(save_pro_label_fold, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到pro_label图片 '+str(len(self.labellist_pro))+' 张图像')
except:
self.labellist_pro = None
print("没有pro_label相关文件")
try:
self.imglist_src = getFileList(ori_img_folder, [], pic_type, self.Label_Max_Search_layer)
self.reslist_src = getFileList(res_label_folder, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到ori原始图片 '+str(len(self.imglist_src))+' 张图像')
print('本次执行检索到训练train_result图片 '+str(len(self.reslist_src))+' 张图像')
except:
self.imglist_src = None
self.reslist_src = None
print("没有train_result和原始图片相关文件")
# 获取单张图片各个通路信息
def get_single_pic_rgb(self, imgpath):
print(imgpath)
image = Image.open(imgpath).convert('RGB') # 转为RGB图片
# 将 RGB 色值分离
image.load()
r, g, b = image.split()
r = np.array(r)
g = np.array(g)
b = np.array(b)
return image, r, g, b
# 将单个pro图片变成GT图片
def Conver_pro_label_pic_2_GT_pic(self, imgpath, imgname):
time_start=time.time() # 记录开始时间
# 获取单张图片各个通路信息
image, r,g,b = self.get_single_pic_rgb(imgpath)
result_gt = np.ones(np.shape(image))*self.back_gnd_color # 初始化填充内容为back_gnd_color
gt_number = self.first_class_color # 第一类上色颜色确定
# 遍历所有待识别颜色
for [Annotate_PALETTE_r, Annotate_PALETTE_g, Annotate_PALETTE_b] in self.Annotate_PALETTE:
# 查找三原色匹配位置
locate_r = np.where( r == Annotate_PALETTE_r )
locate_g = np.where( g == Annotate_PALETTE_g )
locate_b = np.where( b == Annotate_PALETTE_b )
# 查找都匹配位置(交集)
# 将矩阵换一种表示形式
locate_r = np.array(locate_r[0]) * Max_width + np.array(locate_r[1])
locate_g = np.array(locate_g[0]) * Max_width + np.array(locate_g[1])
locate_b = np.array(locate_b[0]) * Max_width + np.array(locate_b[1])
# 用自带函数寻找匹配项
matched = np.intersect1d(np.intersect1d(locate_r, locate_g), locate_b)
matched = np.concatenate(([matched // self.Max_width], [np.mod(matched, self.Max_width)]), 0)
result_gt[matched[0],matched[1], :] = gt_number
gt_number = gt_number + 1
# 输出GT图片
if(int(self.GT_channel) == 1):
result_gt = result_gt[:,:,0]
elif(int(self.GT_channel) == 3):
result_gt = cv2.cvtColor(np.float32(result_gt), cv2.COLOR_RGB2BGR) # rgb颜色互换
else:
print("GT_channel 必须为1或3")
quit
try: # 新建文件夹
os.mkdir(self.save_GT_label_fold)
except:
print("已有"+self.save_GT_label_fold)
save_dir = os.path.join(self.save_GT_label_fold, os.path.splitext(imgname)[0]+self.GT_append_name+'.'+self.pic_type)
cv2.imwrite(save_dir, result_gt)
print("GT图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 将处理好的图片转化为GT图片
def Conver_pro_label_pic_2_GT_pic_all(self):
print("\033[33m**** 进行转换将Pro_label_pic转换为GT_label_pic ****\033[0m")
print("\033[33mPro_label_pic存储位置为\033[0m", self.save_pro_label_fold)
print("\033[33mGT_label_pic生成位置为\033[0m", self.save_GT_label_fold)
try:
# print(save_pro_label_fold)
self.labellist_pro = getFileList(save_pro_label_fold, [], pic_type, self.Label_Max_Search_layer)
print('本次执行检索到pro_label图片 '+str(len(self.labellist_pro))+' 张图像')
except:
self.labellist_pro = None
print("没有pro_label相关文件")
try:
os.mkdir(self.save_GT_label_fold) # 新建存储文件夹
except:
print("已有"+self.save_GT_label_fold)
# 指定最大进程数为 3
max_processes = 20
# 创建Pool对象
pool = multiprocessing.Pool(processes=max_processes)
# 创建并启动进程
args_list1 = []
args_list2 = []
# 遍历整个文件夹
for imgpath in self.labellist_pro:
imgname= os.path.splitext(os.path.basename(imgpath))[0].replace(self.pro_append_name,"")
args_list1.append(imgpath)
args_list2.append(imgname)
args_list = zip(args_list1, args_list2)
# 使用进程池并行执行任务
pool.starmap(self.Conver_pro_label_pic_2_GT_pic, args_list)
# 关闭进程池
pool.close()
pool.join()
def Conver_ori_label_pic_2_pro_pic(self, imgpath, imgname):
time_start=time.time() # 记录开始时间
# 获取单张图片各个通路信息
image, r, g, b = self.get_single_pic_rgb(imgpath)
result_pro = np.zeros(np.shape(image)) # pro图片初始化默认图片背景为0.0.0
# 生成距离初始矩阵 width*height*num_of_classes
Dis_mat = np.zeros((np.shape(image)[0], np.shape(image)[1], self.src_CLASSES_NUM))
# 遍历所有类
i = 0 # 顺序指示物
# 遍历寻找最短距离是第几个内容
for palette in self.src_PALETTE:
Dis_mat[:,:,i] = np.abs((r - palette[0])) + np.abs((g - palette[1])) + np.abs((b - palette[2]))
i = i + 1
Min_Dis_mat = np.argmin(Dis_mat, axis = 2)
# 给图片上色
for number_class in range(self.src_CLASSES_NUM):
# 查找图片种类
loc_of_class_pic = np.where(Min_Dis_mat == number_class)
# 否则给图片上对应颜色
result_pro[loc_of_class_pic[0], loc_of_class_pic[1], :] = self.src_PALETTE[number_class]
result_pro = cv2.cvtColor(np.float32(result_pro), cv2.COLOR_RGB2BGR) # rgb颜色互换
# 如果需要存储中间态图片
if(self.save_process_pics == True):
save_dir = os.path.join(self.save_pro_label_fold, '1_颜色预处理', os.path.splitext(imgname)[0]+self.pro_append_name+'_preproc'+'.'+self.pic_type)
cv2.imwrite(save_dir, result_pro)
print("中间态-颜色图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 边界区域大小
half_region_len=(5-1)//2
pic_height = result_pro.shape[0]
pic_width = result_pro.shape[1]
# 2_灰度化
gray = cv2.cvtColor(result_pro, cv2.COLOR_BGR2GRAY)
gray = (gray*255).astype(np.uint8) # cv2对图片格式要求较为严格
# 如果需要存储中间态图片
if(self.save_process_pics == True):
save_dir = os.path.join(self.save_pro_label_fold, '2_灰度化', os.path.splitext(imgname)[0]+self.pro_append_name+'_gray'+'.'+self.pic_type)
cv2.imwrite(save_dir, gray)
print("中间态-灰度图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 边缘检测
edges = cv2.Canny(gray, 50, 150)
# 定义膨胀核
kernel = np.ones((3, 3), np.uint8)
# 对Canny输出图像进行膨胀
edges = cv2.dilate(edges, kernel, iterations=1)
# 如果需要存储中间态图片
if(self.save_process_pics == True):
save_dir = os.path.join(self.save_pro_label_fold, '3_边缘化', os.path.splitext(imgname)[0]+self.pro_append_name+'_edge'+'.'+self.pic_type)
cv2.imwrite(save_dir, edges)
print("中间态-边缘图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 查找边缘
nonzero_idx = np.array(np.nonzero(edges)).T
# nonzero_idx, counts = np.unique(nonzero_idx, axis=0, return_counts=True)
print("边缘个数:",np.shape(nonzero_idx)[0])
for k in range(len(nonzero_idx)):
i = nonzero_idx[k][0]
j = nonzero_idx[k][1]
# 遍历周围3*3的区域
# 找到与当前像素值附近5*5*3(channel)的像素并将矩阵变为25(5*5)*3(channel)
if i <= half_region_len:
i = half_region_len
elif i >= pic_height-half_region_len:
i = pic_height-half_region_len
if j <= half_region_len:
j = half_region_len
elif j >= pic_width-half_region_len:
j = pic_width-half_region_len
region_x = i
region_y = j
region = np.array(result_pro[region_x-half_region_len:region_x+half_region_len, region_y-half_region_len:region_y+half_region_len,:]).reshape(-1, 3)
# 计算唯一列及其出现次数
# print(region_x-half_region_len, region_x+half_region_len, region_y-half_region_len, region_y+half_region_len)
unique_columns, counts = np.unique(region, axis=0, return_counts=True)
# 找出出现次数最多的列的索引
max_count_index = np.argmax(counts)
# 将其赋值为出现次数最多的列
result_pro[i, j, :] = unique_columns[max_count_index]
# result_pro[i, j, :] = [0,0,0]
save_dir = os.path.join(self.save_pro_label_fold, os.path.splitext(imgname)[0]+self.pro_append_name+'.'+self.pic_type)
print("Pro图片已保存", save_dir)
cv2.imwrite(save_dir, result_pro)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 将原始src图片转化为处理好的pro图片
def Conver_ori_label_pic_2_pro_pic_all(self):
print("\033[33m**** 进行转换将Ori_label_pic转换为Pro_label_pic ****\033[0m")
print("\033[33mOri_label_pic存储位置为\033[0m", self.src_label_fold)
print("\033[33mPro_label_pic生成位置为\033[0m", self.save_pro_label_fold)
# 输出颜色预处理图片
try:
os.mkdir(self.save_pro_label_fold) # 新建存储文件夹
except:
print("已有"+self.save_pro_label_fold)
if(self.save_process_pics == True):
try:
os.mkdir(os.path.join(self.save_pro_label_fold, '1_颜色预处理')) # 新建存储1_颜色预处理文件夹
except:
print("已有"+os.path.join(self.save_pro_label_fold, '1_颜色预处理'))
try:
os.mkdir(os.path.join(self.save_pro_label_fold, '2_灰度化')) # 新建存储2_灰度化文件夹
except:
print("已有"+os.path.join(self.save_pro_label_fold, '2_灰度化'))
try:
os.mkdir(os.path.join(self.save_pro_label_fold, '3_边缘化')) # 新建存储1_颜色预处理文件夹
except:
print("已有"+os.path.join(self.save_pro_label_fold, '3_边缘化'))
# 指定最大进程数为 20多参数函数并行
max_processes = 20
# 创建Pool对象
pool = multiprocessing.Pool(processes=max_processes)
# 创建并启动进程
args_list1 = []
args_list2 = []
# 遍历整个文件夹
for imgpath in self.labellist_src:
try:
imgname= os.path.splitext(os.path.basename(imgpath))[0].replace(self.pro_append_name,"")
print("Processing: ", imgname, "...")
# self.Conver_ori_label_pic_2_pro_pic(imgpath, imgname)s
# args_list.append({'imgpath': imgpath, 'imgname': imgname})
args_list1.append(imgpath)
args_list2.append(imgname)
except:
os.system("echo "+imgname+" >> error_1.txt")
args_list = zip(args_list1, args_list2)
# 使用进程池并行执行任务
pool.starmap(self.Conver_ori_label_pic_2_pro_pic, args_list) # 使用starmap进行多参数并行
# 关闭进程池
pool.close()
pool.join()
# 图片堆叠
def Merge_ori_pic_and_label_pic(self, res_img_path, res_imgname):
time_start=time.time() # 记录开始时间
# 获取单张图片各个通路信息
ori_img_path = os.path.join(self.ori_img_folder, res_imgname+'.'+self.pic_type)
if not os.path.exists(ori_img_path):
print("****照片不存在:****", ori_img_path)
return -1
ori_image, ori_r, ori_g, ori_b = self.get_single_pic_rgb(ori_img_path)
res_image, res_r, res_g, res_b = self.get_single_pic_rgb(res_img_path)
merge_img = np.array(ori_image) # merge图片初始化默认图片背景为0.0.0
# 遍历所有待识别颜色
for [Annotate_PALETTE_r, Annotate_PALETTE_g, Annotate_PALETTE_b] in self.Annotate_PALETTE:
# 查找三原色匹配位置
locate_r = np.where( res_r == Annotate_PALETTE_r )
locate_g = np.where( res_g == Annotate_PALETTE_g )
locate_b = np.where( res_b == Annotate_PALETTE_b )
# 查找都匹配位置(交集)
# 将矩阵换一种表示形式
locate_r = np.array(locate_r[0]) * self.Max_width + np.array(locate_r[1])
locate_g = np.array(locate_g[0]) * self.Max_width + np.array(locate_g[1])
locate_b = np.array(locate_b[0]) * self.Max_width + np.array(locate_b[1])
# 用自带函数寻找匹配项
matched = np.intersect1d(np.intersect1d(locate_r, locate_g), locate_b)
matched = np.concatenate(([matched // self.Max_width], [np.mod(matched, self.Max_width)]), 0)
merge_img[matched[0],matched[1], 0] = Annotate_PALETTE_r
merge_img[matched[0],matched[1], 1] = Annotate_PALETTE_g
merge_img[matched[0],matched[1], 2] = Annotate_PALETTE_b
# 转成cv2形式
merge_img = cv2.cvtColor(np.float32(merge_img), cv2.COLOR_RGB2BGR)
try: # 新建文件夹
os.mkdir(self.save_merge_pic_folder)
except:
print("已有"+self.save_merge_pic_folder)
save_dir = os.path.join(self.save_merge_pic_folder, os.path.splitext(res_imgname)[0]+'.'+self.pic_type)
cv2.imwrite(save_dir, merge_img)
print("Merge图片已保存", save_dir)
time_end=time.time() # 输出结束时间
print('time cost',time_end-time_start,'s')
# 将label图片与原图片重合
def Merge_ori_pic_and_label_pic_all(self):
# 遍历整个文件夹
for res_img_path in self.reslist_src:
res_imgname = os.path.splitext(os.path.basename(res_img_path))[0].replace(self.pro_append_name,"")
print("Processing: ", res_imgname, "...")
self.Merge_ori_pic_and_label_pic(res_img_path, res_imgname)
if __name__ == "__main__":
Annotate_CLASSES = ('肝脏','胆囊','分离钳','止血海绵','肝总管','胆总管','吸引器','剪刀','止血纱布','生物夹','无损伤钳','喷洒','胆囊管','胆囊动脉','电凝','标本袋','引流管','纱布','金属钛夹') # 待分类的类
Annotate_PALETTE = [[255,91,0],[255,234,0],[85, 107, 179],[181, 227, 14],[72, 0, 255],[0, 155, 33],[255,0,255],[29, 32, 136],[160, 15, 95],[0,160,233],[52,184,178],[90,120,41],[255,0,0],[177,0,0],[167,24,233],[112,113,150],[0,255,0],[255,255,255],[0,255,255]]# [[255,91,0],[255,234,0]] # 每一类的像素直
# 创建参数解析器
parser = argparse.ArgumentParser(description='Process some files.')
# 添加参数选项
parser.add_argument('-src_fold', dest='src_label_fold', default='', help='source label folder')
parser.add_argument('-save_pro_fold', dest='save_pro_label_fold', default='./save_pro_label_fold', help='processed label folder')
parser.add_argument('-save_GT_fold', dest='save_GT_label_fold', default='./save_GT_label_fold', help='ground truth folder')
parser.add_argument('-fold_search_depth', dest='Label_Max_Search_layer', default='1000', type=int, help='Folder Search Depth')
parser.add_argument('-pro_suffix_name', dest='pro_append_name', default='_label', help='Pro file suffix')
parser.add_argument('-GT_suffix_name', dest='GT_append_name', default='_gtFine_labelTrainIds', help='GT file suffix')
parser.add_argument('-GT_channel', dest='GT_channel', default='1', type=int, help='GT file channel(1 or 3)')
parser.add_argument('-back_gnd_color', dest='back_gnd_color', default='0', type=int, help='Color of "Back ground"(0 or 255)')
parser.add_argument('-first_class_color', dest='first_class_color', default='1', type=int, help='Color of "First Class"')
parser.add_argument('-pic_type', dest='pic_type', default='png', help='type of picture(Do not add ".")')
parser.add_argument('-Max_width', dest='Max_width', default='10000', type=int, help='Max width of picture')
parser.add_argument('-Rebuild_from', dest='Rebuild_from', default='label', help='Source to Rebuild Labels(label/pro)')
parser.add_argument('-Rebuild_to', dest='Rebuild_to', default='GT', help='Destination of Rebuild Labels(pro/GT)')
parser.add_argument('-save_process_pics', dest='save_process_pics', default='False', help='Save the processed pics(e.g.Gray_pics,Color_pics) in generating pro_pics')
# 解析命令行参数
args = parser.parse_args()
src_label_fold = args.src_label_fold
save_pro_label_fold = args.save_pro_label_fold
save_GT_label_fold = args.save_GT_label_fold
Label_Max_Search_layer = args.Label_Max_Search_layer
pro_append_name = args.pro_append_name
GT_append_name = args.GT_append_name
GT_channel = args.GT_channel
back_gnd_color = args.back_gnd_color
first_class_color = args.first_class_color
pic_type = args.pic_type
Max_width = args.Max_width
Rebuild_from = args.Rebuild_from
Rebuild_to = args.Rebuild_to
save_process_pics = args.save_process_pics
try: # 遍历文件深度最小为1
Label_Max_Search_layer=int(Label_Max_Search_layer)
except:
Label_Max_Search_layer=1000
try: # GT标签图片通道数
GT_channel=int(GT_channel)
except:
GT_channel=1
try: # 背景颜色背景选择0或255)
back_gnd_color=int(back_gnd_color)
except:
back_gnd_color=0
try: # 第一类上的颜色(如果背景为0,选择1)
first_class_color=int(first_class_color)
except:
first_class_color=1
try: # 最大图片宽度(匹配时候用)
Max_width=int(Max_width)
except:
Max_width=10000
if(save_process_pics.lower() == 'false'):
save_process_pics = False
elif(save_process_pics.lower() == 'true'):
save_process_pics = True
else:
save_process_pics = False
D = Deal_image(Annotate_CLASSES=Annotate_CLASSES, Annotate_PALETTE=Annotate_PALETTE, src_label_fold=src_label_fold, save_pro_label_fold=save_pro_label_fold, save_GT_label_fold=save_GT_label_fold, GT_channel=GT_channel, pro_append_name=pro_append_name, GT_append_name=GT_append_name, back_gnd_color=back_gnd_color, first_class_color=first_class_color, pic_type=pic_type, Max_width=Max_width, Label_Max_Search_layer=Label_Max_Search_layer, save_process_pics=save_process_pics)
# print(D.src_CLASSES_NUM)
if Rebuild_from == 'label':
# 1.先将所有原始图片转为pro图片
D.Conver_ori_label_pic_2_pro_pic_all()
pass
if Rebuild_to == 'GT':
# 2.再将pro图片转为GT图片
D.Conver_pro_label_pic_2_GT_pic_all()
pass

View File

@@ -0,0 +1,163 @@
#!/bin/bash
usage() {
echo "Usage: $0 l <ori_label_directory> [ -h ]"
echo "对label图片进行处理及转化-l不能为空 "
echo "-l:原始label的路径-h:帮助"
echo "e.g. 4_rebuild_labels.sh -l ./C组标注图片"
echo "接下来一路回车就ok"
}
ori_label_directorys=""
while getopts "hl:" opt; do
case $opt in
h)
usage
exit 0
;;
l)
ori_label_directorys=$OPTARG
;;
*)
echo -e '\033[31m!!! Error, Illegal input !!!\033[0m'
usage
exit 1
;;
esac
done
# 判断输入地址是否为空
if [ -z "$ori_label_directorys" ]; then
echo -e "\033[31m输入地址 -i -l 存在空地址\033[0m"
usage
exit 1
fi
# 地址转化
ori_label_directory=$(readlink -f "$ori_label_directorys")
if [ -z "$ori_label_directory" ]; then
echo -e "\033[31m无法解析地址程序退出\033[0m"
echo -e "\033[31mori_label_directory\033[0m: $ori_label_directorys"
exit 1
fi
if [ ! -d "$ori_label_directory" ]; then
echo -e "\033[31mlabel目录不存在程序退出\033[0m"
echo -e "\033[31mori_label_directory\033[0m: $ori_label_directorys"
exit 1
fi
echo -e "\033[32m_____ 4_rebuild_labels.sh _____\033[0m"
echo -n "请选择label图片搜索深度(默认为1):"
read -r fold_search_depth
if [ -z $fold_search_depth ]; then
fold_search_depth='1'
fi
save_pro_folds=""${ori_label_directory%/}"_pro_label_fold" # 去掉末尾的足/
save_pro_fold=$(readlink -f "$save_pro_folds")
echo -n "请选择初步处理label后label_pro图片存储位置(默认为$save_pro_fold):"
read -r save_pro_folds
if [ -z $save_pro_folds ]; then
save_pro_folds=""${ori_label_directory%/}"_pro_label_fold"
fi
save_pro_fold=$(readlink -f "$save_pro_folds")
echo -n "请选择label_pro图片后缀(默认为\"_label\"):"
read -r pro_suffix_name
if [ -z $pro_suffix_name ]; then
pro_suffix_name='_label'
fi
save_GT_folds=""${ori_label_directory%/}"_GT_label_fold"
save_GT_fold=$(readlink -f "$save_GT_folds")
echo -n "请选择处理label_pro后label_GT图片存储位置(默认为$save_GT_fold):"
read -r save_pro_folds
if [ -z $save_pro_folds ]; then
save_GT_folds=""${ori_label_directory%/}"_GT_label_fold"
fi
save_GT_fold=$(readlink -f "$save_GT_folds")
echo -n "请选择label_GT图片后缀(默认为\"_gtFine_labelTrainIds\"):"
read -r GT_suffix_name
if [ -z $GT_suffix_name ]; then
GT_suffix_name='_gtFine_labelTrainIds'
fi
echo -n "请选择label_GT图片通道数(1或3默认为1):"
read -r GT_channel
if [ -z $GT_channel ]; then
GT_channel='1'
fi
if [[ $GT_channel != '1' && $GT_channel != '3' ]]; then
echo -e "\033[35mGT_channel只能为1或3输入有误将其默认变为1\033[0m"
GT_channel='1'
fi
echo -n "请选择GT图片背景颜色(0或255默认为0黑色)):"
read -r back_gnd_color
if [ -z $back_gnd_color]; then
back_gnd_color='0'
fi
echo -n "请选择GT图片中第一类的颜色(黑色背景(0)下默认为1白色背景(255)下默认为0):"
read -r first_class_color
if [ -z $first_class_color]; then
if [ $back_gnd_color == '255' ]; then
first_class_color='0'
else
first_class_color='1'
fi
fi
echo -n "请选择图片类型(png或jpg默认为png没有\".\")):"
read -r pic_type
if [ -z $pic_type ]; then
pic_type='png'
fi
echo -n "请选择重建起始目录(label或pro默认为label):"
read -r Rebuild_from
if [ -z $Rebuild_from ]; then
Rebuild_from='label'
fi
if [[ $Rebuild_from != 'label' && $Rebuild_from != 'pro' ]]; then
echo -e "\033[35mRebuild_from只能为label或pro输入有误将其默认变为label\033[0m"
Rebuild_from='label'
fi
echo -n "请选择重建最终目标(pro或GT默认为GT):"
read -r Rebuild_to
if [ -z $Rebuild_to ]; then
Rebuild_to='GT'
fi
if [[ $Rebuild_to != 'GT' && $Rebuild_to != 'pro' ]]; then
echo -e "\033[35mRebuild_to只能为GT或pro输入有误将其默认变为GT\033[0m"
Rebuild_to='GT'
fi
echo -n "请选择是否保存pro图片生成中间状态e.g.灰度图等)(false或true默认为false):"
read -r save_process_pics
if [ -z $save_process_pics ]; then
save_process_pics='false'
fi
if [[ $save_process_pics != 'true' && $save_process_pics != 'false' ]]; then
echo -e "\033[35msave_process_pics只能为true或false输入有误将其默认变为false\033[0m"
save_process_pics='false'
fi
# 获取当前脚本的路径和名称
script_path=$(dirname "$0")
# 将当前目录更改为脚本所在的路径
cd "$script_path"
# 激活conda环境
source /home/"$USER"/miniconda/bin/activate Deal_pics
echo -e "\033[35m运行\033[0mpython 4_deal_labels.py -src_fold $ori_label_directory -save_pro_fold $save_pro_fold -save_GT_fold $save_GT_fold -fold_search_depth $fold_search_depth -pro_suffix_name $pro_suffix_name -GT_suffix_name $GT_suffix_name -GT_channel $GT_channel -back_gnd_color $back_gnd_color -first_class_color $first_class_color -pic_type $pic_type -Rebuild_from $Rebuild_from -Rebuild_to $Rebuild_to -save_process_pics $save_process_pics "
echo ""
python 4_deal_labels.py -src_fold $ori_label_directory -save_pro_fold $save_pro_fold -save_GT_fold $save_GT_fold -fold_search_depth $fold_search_depth -pro_suffix_name $pro_suffix_name -GT_suffix_name $GT_suffix_name -GT_channel $GT_channel -back_gnd_color $back_gnd_color -first_class_color $first_class_color -pic_type $pic_type -Rebuild_from $Rebuild_from -Rebuild_to $Rebuild_to -save_process_pics $save_process_pics
echo "4_rebuild_label_pics.sh重构完毕"

View 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. 5_TOOL_stack_pics.sh -i ./C组未标注 -l ./C组标注图片 -r ./C组result_0.3透明度 -a 0.3 -p Group_C_ -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_pics
echo -e "\033[32m_____ 5_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 5_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

View 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)

View File

@@ -0,0 +1,167 @@
#!/bin/bash
usage() {
echo "Usage: $0 -i <ori_image_directory> -l <ori_label_directory> -r <stitch_result_directory> [ -p <prefix> -s <suffix> -h]"
echo "对image图片和label图片进行拼接-i -r不能为空-l为填写项-p -s默认为空"") "
echo "-i:原始image的路径-l:拼接label的路径-p:前缀内容,-s:后缀内容(不用管文件后缀名)-h:帮助"
echo "e.g. 6_TOOL_stitch_pics.sh -i ./C组未标注 -l ./C组标注图片 -r ./C组result_stitch -p Group_C_ -s _label"
}
ori_image_directorys=""
ori_label_directorys=""
stitch_result_directorys=""
prefix=""
suffix=""
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)
stitch_result_directorys=$OPTARG
;;
*)
echo -e '\033[31m!!! Error, Illegal input !!!\033[0m'
usage
exit 1
;;
esac
done
# 如果堆叠地址为空,生成默认堆叠地址
if [ -z "$stitch_result_directorys" ]; then
stitch_result_directorys=""$ori_label_directorys"_拼接"
echo -n "请输入堆叠结果存储目录(默认为$stitch_result_directorys)"
read -r temp
if [ ! -z $temp ]; then
stitch_result_directorys=$temp
fi
fi
# 判断输入地址是否为空
if [ -z "$ori_label_directorys" ] || [ -z "$ori_image_directorys" ] || [ -z "$stitch_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")
stitch_result_directory=$(readlink -f "$stitch_result_directorys")
if [ -z "$ori_label_directory" ] || [ -z "$ori_image_directory" ]|| [ -z "$stitch_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: $stitch_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
echo -e "\033[32m_____ 6_TOOL_stitch_pics.sh _____\033[0m"
# 图片相对位置
PS3='Please enter your choice:'
options=("Imge ↑ Label ↓" "Label ↑ Imge ↓" "Imge ← Label →" "Label ← Imge →" )
echo "请选择图片与Label的相对位置默认为1.\"Imge↑Label↓\""
select opt in "${options[@]}"
do
case $opt in
# 这里面返回的结果都是img在前label在后的
"Imge ↑ Label ↓")
relative_pos="Img_up_label_down"
break
;;
"Label ↑ Imge ↓")
relative_pos="Img_down_label_up"
break
;;
"Imge ← Label →")
relative_pos="Img_left_label_right"
break
;;
"Label ← Imge →")
relative_pos="Img_right_label_left"
break
;;
*)
echo "Set to default 1.\"Imge↑Label↓\""
relative_pos="Img_up_label_down"
break
;;
esac
done
# 获取当前脚本的路径和名称
script_path=$(dirname "$0")
# 将当前目录更改为脚本所在的路径
cd "$script_path"
# 激活conda环境
source /home/"$USER"/miniconda/bin/activate Deal_pics
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"
if [ ! -d "$stitch_result_directory" ]; then
echo "创建stitch_result_directory存储文件夹"
echo -e "\033[35运行:\033[0m mkdir -p $stitch_result_directory"
mkdir -p $stitch_result_directory
fi
echo -e "\033[35运行:\033[0mpython 6_stitch_picture.py "$ori_image_directory/$file_name_other" "$ori_label_directory/$file_name" "$stitch_result_directory" "$relative_pos""
python 6_stitch_picture.py "$ori_image_directory/$file_name_other" "$ori_label_directory/$file_name" "$stitch_result_directory" "$relative_pos"
echo ""
fi
fi
else
echo "$file_path不是文件"
fi
done

View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import cv2, os, sys, re
def Stitch_pic(Ori_image_path, Ori_label_path, Result_dir, img_pos, label_pos):
# 读取两张没有stitch_pos通道的图片
img1 = cv2.imread(Ori_image_path) # 底层图片
img2 = cv2.imread(Ori_label_path) # 顶层图片
Result_name = os.path.splitext(os.path.basename(Ori_image_path))[0]
# 将img2调整为与img1大小相同
if img1.shape != img2.shape:
img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))
# 拼接图片
if img_pos == 'up' and label_pos == 'down':
result = cv2.vconcat([img1, img2])
elif img_pos == 'down' and label_pos == 'up':
result = cv2.vconcat([img2, img1])
elif img_pos == 'left' and label_pos == 'right':
result = cv2.hconcat([img1, img2])
elif img_pos == 'right' and label_pos == 'left':
result = cv2.hconcat([img2, img1])
else:
RED = '\033[91m'
END = '\033[0m'
print(RED + "The input of relative_pos is wrong, img_pos is " + img_pos + " label_pos is " + label_pos + END)
os.exit()
# 保存结果
if not os.path.exists(Result_dir):
os.makedirs(Result_dir)
cv2.imwrite(os.path.join(Result_dir, Result_name+'.png'), result)
print("堆叠图片写入地址:", os.path.join(Result_dir, Result_name+'.png'))
if __name__ == '__main__':
Ori_image_path = sys.argv[1] # 背景所在路径
Ori_label_path = sys.argv[2] # 上层图片所在路径
Result_dir = sys.argv[3] # 结果所在目录
relative_pos = str.lower(sys.argv[4])
match_up = re.search(r'up', relative_pos)
match_down = re.search(r'down', relative_pos)
match_left = re.search(r'up', relative_pos)
match_right = re.search(r'down', relative_pos)
if match_up and match_down:
pos_up = match_up.start()
pos_down = match_down.start()
if pos_down < pos_up :
img_pos = "down"
label_pos = "up"
else:
img_pos = "up"
label_pos = "down"
elif match_left and match_right:
pos_left = match_up.start()
pos_right = match_down.start()
if pos_left < pos_right :
img_pos = "left"
label_pos = "right"
else:
img_pos = "left"
label_pos = "right"
else:
print("Either 'up'/'down' 'left'/'right' is missing or in the text.")
print("Set to default img_pos = up label_pos = down")
img_pos = "up"
label_pos = "down"
# 进行对叠程序
Stitch_pic(Ori_image_path, Ori_label_path, Result_dir, img_pos, label_pos)

View File

@@ -0,0 +1,246 @@
#!/bin/bash
usage() {
echo "Usage: $0 -i <ori_image_directory> -l <ori_label_directory> [-h]"
echo "对image图片和label图片进行统一处理"
echo "-i:原始图片的路径,-l:原始标签的路径,-h:帮助"
}
ori_image_directorys=""
ori_label_directorys=""
stack_result_directorys=""
stitch_result_directorys=""
while getopts "hl:i:" opt; do
case $opt in
h)
usage
exit 0
;;
i)
ori_image_directorys=$OPTARG
;;
l)
ori_label_directorys=$OPTARG
;;
*)
echo '!!! Error, Illegal input !!!'
usage
exit 1
;;
esac
done
# 判断label、image是否都为空
echo $ori_label_directorys $ori_image_directorys
if [ -z "$ori_label_directorys" ] && [ -z "$ori_image_directorys" ]; then
echo -e "\033[31mori_label_directory、ori_image_directory不能都为空\033[0m"
usage
exit 1
fi
# 进行绝对路径转化
ori_image_directory=$(readlink -f "$ori_image_directorys")
ori_label_directory=$(readlink -f "$ori_label_directorys")
if [ ! -d "$ori_label_directory" ] && [ ! -d "$ori_image_directory" ]; then
echo "image、label都不存在程序退出"
echo -e "\033[31mori_image_directory\033[0m: $ori_image_directorys"
echo "$ori_image_directory"
echo -e "\033[31mori_label_directory\033[0m: $ori_label_directorys"
echo "$ori_label_directory"
exit 1
fi
# 激活conda环境
# source /home/"$USER"/miniconda/bin/activate Pat_infos
# 记录脚本所在路径
script_path=$(dirname "$0")
echo -e "\033[32m******* 开始Run运行Seg_data_run.sh批量图片处理程序 *******\033[0m"
# 进行操作选择
while true; do
PS3='Please enter your choice: '
options=("移动图片与重命名" "图片统一大小与类型" "image、label配对检测" "对label进行重建" "TOOL_image、label堆叠" "TOOL_image、label拼接" "Quit")
echo -e "\033[35m____ Seg_data_run选择 ____\033[0m"
echo -e "\033[35mImage所在地址\033[0m$ori_image_directory"
echo -e "\033[35mLabel所在地址\033[0m$ori_label_directory"
select opt in "${options[@]}"
do
case $opt in
### 选项1 ###
"移动图片与重命名")
echo -e "\033[31mRun运行:\033[0mbash $script_path/1_rename_pics.sh -i $ori_image_directory -l $ori_label_directory"
bash $script_path/1_rename_pics.sh -i "$ori_image_directory" -l "$ori_label_directory"
echo ""
break
;;
### 选项2 ###
"图片统一大小与类型")
echo -n "请输入宽度默认1920:"
read -r width
echo -n "请输入高度默认1080:"
read -r height
if [ -z "$width" ]; then
width=1920
fi
if [ -z "$height" ]; then
height=1080
fi
# 如果输入图片路径为空
if [ -z $ori_image_directory ];then
echo -e "\033[31mRun运行:\033[0mbash $script_path/2_reformate_pics.sh -l $ori_label_directory -w $width -h $height "
bash $script_path/2_reformate_pics.sh -l $ori_label_directory -w $width -h $height
elif [ -z $ori_label_directory ];then
echo -e "\033[31mRun运行:\033[0mbash $script_path/2_reformate_pics.sh -l $ori_label_directory -w $width -h $height "
bash $script_path/2_reformate_pics.sh -i $ori_image_directory -w $width -h $height
else
echo -e "\033[31mRun运行:\033[0mbash $script_path/2_reformate_pics.sh -i $ori_image_directory -l $ori_label_directory -w $width -h $height"
bash $script_path/2_reformate_pics.sh -i $ori_image_directory -l $ori_label_directory -w $width -h $height
fi
echo ""
break
;;
### 选项3 ###
"image、label配对检测")
while [ ! -d "$ori_image_directory" ]; do
echo -e "\033[31mImage地址为:$ori_image_directorys,其不存在\033[0m"
echo -n "请输入image所在地址:"
read -r ori_image_directorys
ori_image_directory=$(readlink -f "$ori_image_directorys")
done
while [ ! -d "$ori_label_directory" ]; do
echo -e "\033[31mLabel地址为:$ori_label_directorys,其不存在\033[0m"
echo -n "请输入label所在地址:"
read -r ori_label_directorys
ori_label_directory=$(readlink -f "$ori_label_directorys")
done
echo -n "请输入图片前缀文本(默认为\"\":"
read -r prefix # 禁止转译
echo -n "请输入图片后缀文本(非.png类后缀名默认为\"\":"
read -r suffix
if [ -z $preffix ];then
preffix=""
fi
if [ -z $suffix ];then
suffix=""
fi
echo -e "\033[31mRun运行:\033[0mbash $script_path/3_pair_ori_label.sh -i $ori_image_directory -l $ori_label_directory -p $prefix -s $suffix"
bash $script_path/3_pair_ori_label.sh -i $ori_image_directory -l $ori_label_directory -p "$prefix" -s "$suffix"
echo ""
break
;;
### 选项4 ###
"对label进行重建")
# 判断Label目录是否存在
while [ -z "$ori_label_directory" ]; do
echo -e "\033[31mLabel地址为:$ori_label_directorys,其存在异常\033[0m"
echo -n "请输入堆叠结果存储目录地址:"
read -r ori_label_directorys
ori_label_directory=$(readlink -f "$ori_label_directorys")
done
echo -e "\033[31mRun运行:\033[0mbash $script_path/4_rebuild_labels.sh -l $ori_label_directory"
bash $script_path/4_rebuild_labels.sh -l $ori_label_directory
echo ""
break
;;
### 选项5 ###
"TOOL_image、label堆叠")
while [ ! -d "$ori_image_directory" ]; do
echo -e "\033[31mImage地址为:$ori_image_directorys,其不存在\033[0m"
echo -n "请输入image所在地址:"
read -r ori_image_directorys
ori_image_directory=$(readlink -f "$ori_image_directorys")
done
while [ ! -d "$ori_label_directory" ]; do
echo -e "\033[31mLabel地址为:$ori_label_directorys,其不存在\033[0m"
echo -n "请输入label所在地址:"
read -r ori_label_directorys
ori_label_directory=$(readlink -f "$ori_label_directorys")
done
echo -n "请输入堆叠图片透明程度0~1,0为最透明默认为0.3"
read -r alpha
echo -n "请输入图片前缀文本(默认为\"\":"
read -r prefix
echo -n "请输入图片后缀文本(非.png类后缀名默认为\"\":"
read -r suffix
if [ -z "$alpha" ]; then
alpha="0.3"
fi
stack_result_directory=""$ori_label_directory"_堆叠_"$alpha"_透明度"
echo -n "请输入堆叠结果存储目录(默认为$stack_result_directory)"
read -r stack_result_directorys
# 判断堆叠目录非为空则进行转换
if [ ! -z "$stack_result_directorys" ]; then
stack_result_directory=$(readlink -f "$stack_result_directorys")
fi
# 判断Label目录是否存在
while [ -z "$ori_label_directory" ]; do
echo -e "\033[31mLabel地址为:$ori_label_directorys,其存在异常\033[0m"
echo -n "请输入堆叠结果存储目录地址:"
read -r ori_label_directorys
ori_label_directory=$(readlink -f "$ori_label_directorys")
done
echo -e "\033[31mRun运行:\033[0mbash $script_path/5_TOOL_stack_pics.sh -i $ori_image_directory -l $ori_label_directory -p $prefix -s $suffix -a $alpha -r $stack_result_directory"
bash $script_path/5_TOOL_stack_pics.sh -i "$ori_image_directory" -l "$ori_label_directory" -p "$prefix" -s "$suffix" -a "$alpha" -r "$stack_result_directory"
echo ""
break
;;
### 选项6 图片拼接 ###
"TOOL_image、label拼接")
while [ ! -d "$ori_image_directory" ]; do
echo -e "\033[31mImage地址为:$ori_image_directorys,其不存在\033[0m"
echo -n "请输入image所在地址:"
read -r ori_image_directorys
ori_image_directory=$(readlink -f "$ori_image_directorys")
done
echo "1.label目前为\"$ori_label_directory\""
echo -n "是否调整label所在文件夹(默认为不调整,有输入视为调整):"
read -r temp
while [ ! -z "$temp" ]; do
read -r ori_label_directorys
ori_label_directorys=$(readlink -f "$ori_label_directorys")
done
while [ ! -d "$ori_label_directory" ]; do
echo -e "\033[31mLabel地址为:$ori_label_directorys,其不存在\033[0m"
echo -n "请输入label所在地址:"
read -r ori_label_directorys
ori_label_directory=$(readlink -f "$ori_label_directorys")
done
stitch_result_directory=""$ori_label_directory"_拼接"
echo -n "2.请输入堆叠结果存储目录(默认为$stitch_result_directory)"
read -r stitch_result_directorys
# 判断堆叠目录非为空则进行转换
if [ ! -z "$stitch_result_directorys" ]; then
stitch_result_directory=$(readlink -f "$stitch_result_directorys")
fi
echo -n "3.请输入图片前缀文本(默认为\"\":"
read -r prefix
echo -n "4.请输入图片后缀文本(非.png类后缀名默认为\"\":"
read -r suffix
echo -e "\033[31mRun运行:\033[0mbash $script_path/6_TOOL_stitch_pics.sh -i $ori_image_directory -l $ori_label_directory -p "$prefix" -s "$suffix" -r "$stitch_result_directory""
bash $script_path/6_TOOL_stitch_pics.sh -i "$ori_image_directory" -l "$ori_label_directory" -p "$prefix" -s "$suffix" -r "$stitch_result_directory"
exit 0
;;
### 选项7 退出 ###
"Quit")
echo -e "\033[35mSeg_data_run.sh Exiting...\033[0m"
exit 0
;;
*)
echo "Invalid option: $REPLY"
echo -e ""
break
;;
esac
done
done

View File

@@ -0,0 +1,14 @@
# 创建环境
conda create -n Deal_pics python=3.8
sudo apt install imagemagick
# 安装包
conda activate Deal_pics
pip install --upgrade pip
pip install opencv-python
# 解决BUG
# 命令python cv2.Canny(image, 50, 150)
# 错误cv2.error: OpenCV(4.5.5) /io/opencv/modules/imgproc/src/canny.cpp:829: error: (-215:Assertion failed) _src.depth() == CV_8U in function 'Canny'
# 错误原因Canny函数只对0~255起作用对0~1不起作用
# 解决方案image = (image*255).astype(np.uint8)

View File

@@ -0,0 +1,28 @@
# 相关程序所在位置:./1_Preprocess_pics已加入路径
1.对于图片批量重命名(允许只输入-i或-l一个参数
1_rename_pics.sh -i <ori_image_directory> -l <ori_label_directory> [-h]
2.对于图片大小批量修改(允许只输入-i或-l一个参数
2_reformate_pics.sh -i <ori_image_directory> -l <ori_label_directory> [ -w <width_of_pic> -h <height_of_pic> -help]
默认:-w=1920 -h=1080
3.对于原始图片、标签图片进行配对(必须输入-i和-l两个参数文件可带前缀或后缀
3_pair_ori_label.sh -i <ori_image_directory> -l <ori_label_directory> [ -p <prefix> -s <suffix> -h]
默认:-p="" -s=""
4.对于标签图片进行进一步处理
※ 如果Label有变请修改 4_deal_labels.py main 中的 Annotate_CLASSES、Annotate_PALETTE
4_rebuild_labels.sh -l <ori_label_directory> [ -h ]
5.TOOL - 对于image图像、label图片进行堆叠透明度可调文件可带前缀或后缀
5_TOOL_stack_pics.sh -i <ori_image_directory> -l <ori_label_directory> -r <stack_result_directory> [ -a <alpha> -p <prefix> -s <suffix> -h]
默认:-a=0.3 -p="" -s=""
6.TOOL - 对于image图像、label图像进行左右放置文件可带前缀或后缀
6_TOOL_stitch_pics.sh -i <ori_image_directory> -l <ori_label_directory> -r <stitch_result_directory> [ -p <prefix> -s <suffix> -h]
============ 用法 ============
1. 将原始Label与现有label进行匹配查看差异
bash 6_TOOL_stitch_pics.sh -i ./A_Label -l ./A_Label_pro_label_fold -r ./A_Label_Compare -s _label