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

posted @ 2022-02-14 17:27  不能说的秘密  阅读(585)  评论(0编辑  收藏  举报