python opencv 根据坐标抠图背景透明
# -*- coding: utf-8 -*-#
from json import load
import shutil
from traceback import format_exc
import logging
from pathlib import Path
import cv2
import numpy as np
from progress.bar import Bar
from time import strftime, localtime, time
def log(log_name: str, p_type=""):
"""
@param log_name:log文件名字
@param p_type:输出类型
@return:日志对象
"""
journal = logging.getLogger(log_name)
journal.setLevel(logging.INFO)
log_file = f"{log_name}{strftime('%Y%m%d%H', localtime(time()))}.log"
format_content = '%(message)s'
if p_type == "time":
format_content = '%(asctime)s - %(levelname)s: %(message)s'
formatter = logging.Formatter(format_content)
# 创建日志文件对象
handler = logging.FileHandler(log_file, encoding="utf-8", mode="w")
handler.setLevel(logging.INFO)
handler.setFormatter(formatter)
# 创建日志流对象
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
# 添加文件和输出流到日志对象
journal.addHandler(handler)
journal.addHandler(console)
return journal
logger = log("KDDI锈迹标注", p_type="time")
def check_path_exist(path_list: list):
"""
:param path_list:路径列表
:return:True/False
"""
for path in path_list:
if not (Path(path).exists() and path != ""):
logger.error(f"{path}不存在或者为空")
return False
return True
def get_coordinates(coordinates):
"""
@param coordinates:列表
@return:列表
"""
if len(coordinates) > 1:
return coordinates
elif len(coordinates) == 1:
return get_coordinates(coordinates[0])
def read_json(file_path):
"""
@param file_path:json文件路径
@return:json内容
"""
file_json = None
try:
with open(file_path, mode='r', encoding="utf-8") as f:
file_json = load(f)
except Exception as e:
logger.error(f"读取json文件失败:{e}")
finally:
return file_json
def convert(json_file, img_file, output_file):
json_content = read_json(json_file)
if img_file:
img = cv2.imdecode(np.fromfile(str(img_file), dtype=np.uint8), cv2.IMREAD_UNCHANGED)
img = cv2.cvtColor(img,cv2.COLOR_BGR2BGRA)
# new_img = np.zeros((img.shape[0],img.shape[1],4), np.uint8)
new_img = np.ones((img.shape[0], img.shape[1], 4)) * (0, 0, 0, 0)
for data in json_content["dataList"]:
line_type = data["lineType"]
coordinates = get_coordinates(data["coordinates"])
if len(line_type)>1:
for i in range(len(line_type)):
area = np.array(coordinates[i])
new_img = cv2.fillPoly(new_img, [area], (255, 255, 255,255))
else:
area = np.array(coordinates)
new_img = cv2.fillPoly(new_img, [area], (255, 255, 2550, 255))
maskindex = np.where(new_img >0 )
new_img[maskindex] = img[maskindex]
cv2.imencode('.png', new_img)[1].tofile(output_file)
shutil.copy(json_file,output_file.parent)
shutil.copy(img_file,output_file.parent)
def get_json_img(input_path):
json_img_list = []
for json_file in input_path.rglob("*.json"):
img_file_list = [f for f in input_path.rglob(
f"{json_file.stem}.*") if f.suffix.lower() in [".png", ".bmp", ".jpg", ".jpeg"] and f.parent.name == json_file.parent.name]
if len(img_file_list) == 1:
json_img_list.append([json_file, img_file_list[0]])
else:
logger.error(f"{json_file}匹配图片失败:{img_file_list}")
return json_img_list
def main(input_path, output_path):
json_img_file = get_json_img(input_path)
with Bar(max=len(json_img_file), suffix='%(index)d/%(max)d in %(elapsed)ds (eta:%(eta_td)s)') as bar:
for file in json_img_file:
try:
json_file = file[0]
img_file = file[1]
output_file = output_path.joinpath(json_file.relative_to(input_path))
output_file = output_file.parent.joinpath(f"{output_file.stem}_mask.png")
output_file.parent.mkdir(parents=True, exist_ok=True)
convert(json_file, img_file, output_file)
except Exception as e:
logger.error(f"{file}运行失败,跳过这个文件。{e}\n{format_exc()}")
finally:
bar.next()
if __name__ == '__main__':
while True:
print("**** start ****")
input_folder = input("请输入平台标注结果文件夹:").strip("\"")
output_folder = input("请输入结果保存文件夹:").strip("\"")
# input_folder = r"C:\Users\Administrator\Desktop\王硕\KDDI锈迹标注\KDDI锈迹标注png生成\data\data1\【自检】锈迹标注-宽泛_092056"
# output_folder = r"C:\Users\Administrator\Desktop\王硕\KDDI锈迹标注\KDDI锈迹标注png生成\result"
if check_path_exist([input_folder, output_folder]):
try:
main(Path(input_folder), Path(output_folder))
except Exception as ee:
logger.error(f"{format_exc()}:{ee}")
finally:
print("**** finished ****")
c = input("请输入q(不区分大小写)回车退出,按其他任意键回车继续:")
if c.lower() == "q":
break
else:
continue
不论你在什么时候开始,重要的是开始之后就不要停止。
不论你在什么时候结束,重要的是结束之后就不要悔恨。