python对检测分割数据集图像和标注进行切分
import cv2
import json
import math
import numpy as np
from utils import *
from tqdm import tqdm
class SliceAndSpliceMeta:
def __init__(self) -> None:
self.slice_starts = None
self.slice_ends = None
self.splice_starts = None
self.splice_ends = None
'''
get_meta:获取窗口的meta数据(meta:包含了切分区块的左上角和右下角的坐标)
image_side:原图边长
patch_side:区块边长
'''
def get_meta(image_side, patch_side):
meta = SliceAndSpliceMeta()
if image_side <= patch_side:
meta.slice_starts = [0]
meta.slice_ends = [patch_side]
meta.splice_starts = [0]
meta.splice_ends = [patch_side]
return meta
num = math.ceil(image_side / patch_side)
num_overlaps = num - 1
overlap_pixels = patch_side * num - image_side
base_overlap = math.floor(overlap_pixels / num_overlaps)
remain_pixels = overlap_pixels % num_overlaps
overlaps = [base_overlap] * num_overlaps
for i in range(remain_pixels):
overlaps[i] += 1
slice_starts = [None] * num
slice_ends = [None] * num
for i in range(num):
slice_starts[i] = patch_side * i - sum(ele for ele in overlaps[:i])
slice_ends[i] = patch_side * (i + 1) - sum(ele for ele in overlaps[:i])
rights = [math.floor(overlap / 2) for overlap in overlaps]
lefts = [overlap - right for overlap, right in zip(overlaps, rights)]
splice_starts = [0] + lefts
splice_ends = rights + [0]
tmp = [patch_side] * num
splice_ends = [t - splice_end for t, splice_end in zip(tmp, splice_ends)]
meta.slice_starts = slice_starts
meta.slice_ends = slice_ends
meta.splice_starts = splice_starts
meta.splice_ends = splice_ends
return meta
'''
存切片后的图和切片后的标签
img_patch: 区块图像
mask_patch_and_id_vec: 缺陷mask和对应id列表
area_thres:过滤阈值
path_to_img_patches: 存图地址
path_to_txt_patches: 存标注地址
image.split(".")[0]:图像名称
patch_idx:区块id
task:任务类型,seg或det
'''
def save_patch_and_txt(patch, mask_patch_and_id_vec, area_thres, path_to_img_patches, path_to_txt_patches, filename,
patch_idx, task):
if len(mask_patch_and_id_vec) == 0:
return
patch_h, patch_w = patch.shape[:2]
w_and_h = np.array([patch_w, patch_h], dtype=np.float64)
opened = False
for patch_mask, class_id in mask_patch_and_id_vec:
found_contours, hierarchy = cv2.findContours(patch_mask, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
for found_contour in found_contours:
contour_area = cv2.contourArea(found_contour, False)
if contour_area >= area_thres:
line = f"{class_id - 1} "
if task == "seg":
epsilon = 0.005 * cv2.arcLength(found_contour, True)
approx = cv2.approxPolyDP(found_contour, epsilon, True) if len(
found_contour.reshape(-1).tolist()) > 20 else found_contour
if len(approx.reshape(-1).tolist()) < 6:
continue
approx = approx / w_and_h
elif task == "det":
x1, y1 = found_contour.min(0)[0]
x2, y2 = found_contour.max(0)[0]
approx = np.array([(x1 + x2) / 2.0, (y1 + y2) / 2.0, x2 - x1, y2 - y1]) / np.concatenate(
[w_and_h, w_and_h])
else:
assert False, f"task: '{task}' not support"
line += " ".join(str(ele)[:5] for ele in list(approx.reshape(-1))) + "\n"
if not opened:
f = open(os.path.join(path_to_txt_patches, filename + f"_{patch_idx}.txt"), "w")
opened = True
f.write(line)
if opened:
cv2.imwrite(os.path.join(path_to_img_patches, filename + f"_{patch_idx}.bmp"), patch)
f.close()
def image_json_dynamic_slice(image_path, json_path, output_path, patch_h, patch_w, names2ids, area_thres):
image_path = image_path
json_path = json_path
'''
检测图像及标注
'''
task = "det"
path_to_img_patches = os.path.join(output_path,"det" ,"images")
path_to_txt_patches = os.path.join(output_path,"det" ,"txt")
makedir(path_to_img_patches)
makedir(path_to_txt_patches)
path_vis1 = os.path.join(output_path,"Vis1")
path_vis2 = os.path.join(output_path,"Vis2")
makedir(path_vis1)
makedir(path_vis2)
patch_h = patch_h
patch_w = patch_w
names2ids = names2ids
area_thres = area_thres
images = os.listdir(image_path)
for image in tqdm(images):
img = cv2.imread(os.path.join(image_path, image), cv2.IMREAD_COLOR)
srch, srcw = img.shape[:2]
meta_h = get_meta(srch, patch_h)
meta_w = get_meta(srcw, patch_w)
x1s = []
y1s = []
x2s = []
y2s = []
for x1, x2 in zip(meta_w.slice_starts, meta_w.slice_ends):
x1s.append(x1)
x2s.append(x2)
for y1, y2 in zip(meta_h.slice_starts, meta_h.slice_ends):
y1s.append(y1)
y2s.append(y2)
lts = []
for x1 in x1s:
for y1 in y1s:
lts.append((x1, y1))
rbs = []
for x2 in x2s:
for y2 in y2s:
rbs.append((x2, y2))
contours = []
ids = []
endFile = os.path.splitext(image)[-1]
with open(os.path.join(json_path, image.replace(endFile, ".json"))) as f:
label = json.load(f)
for shape in label["shapes"]:
assert shape["label"] in names2ids.keys(), f"{shape['label']} not in 'names2ids'."
contours.append(np.array(shape["points"], dtype=np.int32))
ids.append(names2ids[shape["label"]])
msk = np.zeros((srch, srcw), dtype=np.uint8)
# 绘画检测对象的的poly型mask到原图mask上
for contour, id_ in zip(contours, ids):
# 绘画检测对象 mask
msk = cv2.fillPoly(msk, [contour], id_)
# 画切片可视图(optional)
# 原图深拷贝
plot_img = img.copy()
# 原图mask深拷贝
plot_msk = msk.copy()
# 左上角点和右下角点
for lt, rb in zip(lts, rbs):
# 原图上绘制矩形框
plot_img = cv2.rectangle(plot_img, lt, rb, (255,255,255), 1)
# 在原图mask上绘制矩形框
plot_msk = cv2.rectangle(plot_msk, lt, rb, (4,4,4), 1)
# 可视化化存图路径
v1_path = os.path.join(path_vis1,image)
v2_path = os.path.join(path_vis2,image)
# 存绘画后的原图
cv2.imwrite(v1_path, plot_img)
# 存绘画后的mask
cv2.imwrite(v2_path, plot_msk * 60)
# 切片
# 区块id
patch_idx = 0
# 遍历左上角点和右下角点
for lt, rb in zip(lts, rbs):
'''
修改处:加上overlap .clip(0, x)用于防呆
'''
x1_overlap = lt[0]
x2_overlap = rb[0]
y1_overlap = lt[1]
y2_overlap = rb[1]
# 深拷贝原图区块
img_patch = img[lt[1]:rb[1], lt[0]:rb[0], :].copy()
# 深拷贝mask区块(重要)
msk_patch = msk[lt[1]:rb[1], lt[0]:rb[0]].copy()
# mask和id元组存储列表
mask_patch_and_id_vec = []
# 遍历所有标签类别id,获取所有id对应的缺陷mask
for id_ in names2ids.values():
# 获取对应缺陷类别id的mask(重要)
patch_mask = np.array(msk_patch == id_, dtype=np.uint8)
# 如果存在该缺陷类别的id的mask,则加入列表
if np.any(patch_mask):
mask_patch_and_id_vec.append((patch_mask, id_))
'''
img_patch: 区块图像
mask_patch_and_id_vec: 缺陷mask和对应id列表
area_thres:过滤阈值
path_to_img_patches: 存图地址
path_to_txt_patches: 存标注地址
image.split(".")[0]:图像名称
patch_idx:区块id
task:任务类型,seg或det
'''
save_patch_and_txt(img_patch, mask_patch_and_id_vec, area_thres,
path_to_img_patches, path_to_txt_patches, image.split(".")[0], patch_idx,task)
patch_idx += 1
'''
分割图像及标注
'''
task = "seg"
path_to_img_patches = os.path.join(output_path,"seg" ,"images")
path_to_txt_patches = os.path.join(output_path,"seg" ,"txt")
makedir(path_to_img_patches)
makedir(path_to_txt_patches)
for image in tqdm(images):
img = cv2.imread(os.path.join(image_path, image), cv2.IMREAD_COLOR)
srch, srcw = img.shape[:2]
meta_h = get_meta(srch, patch_h)
meta_w = get_meta(srcw, patch_w)
x1s = []
y1s = []
x2s = []
y2s = []
for x1, x2 in zip(meta_w.slice_starts, meta_w.slice_ends):
x1s.append(x1)
x2s.append(x2)
for y1, y2 in zip(meta_h.slice_starts, meta_h.slice_ends):
y1s.append(y1)
y2s.append(y2)
lts = []
for x1 in x1s:
for y1 in y1s:
lts.append((x1, y1))
rbs = []
for x2 in x2s:
for y2 in y2s:
rbs.append((x2, y2))
contours = []
ids = []
endFile = os.path.splitext(image)[-1]
with open(os.path.join(json_path, image.replace(endFile, ".json"))) as f:
label = json.load(f)
for shape in label["shapes"]:
assert shape["label"] in names2ids.keys(), f"{shape['label']} not in 'names2ids'."
contours.append(np.array(shape["points"], dtype=np.int32))
ids.append(names2ids[shape["label"]])
msk = np.zeros((srch, srcw), dtype=np.uint8)
for contour, id_ in zip(contours, ids):
msk = cv2.fillPoly(msk, [contour], id_)
# 切片
patch_idx = 0
for lt, rb in zip(lts, rbs):
img_patch = img[lt[1]:rb[1], lt[0]:rb[0], :].copy()
msk_patch = msk[lt[1]:rb[1], lt[0]:rb[0]].copy()
mask_patch_and_id_vec = []
for id_ in names2ids.values():
patch_mask = np.array(msk_patch == id_, dtype=np.uint8)
if np.any(patch_mask):
mask_patch_and_id_vec.append((patch_mask, id_))
save_patch_and_txt(img_patch, mask_patch_and_id_vec, area_thres,
path_to_img_patches, path_to_txt_patches, image.split(".")[0], patch_idx,task)
patch_idx += 1
if __name__ == '__main__':
try:
image_path = rf"D:\workplace\python\pythonProject2\SideArray\images\train"
json_path = rf"D:\workplace\python\pythonProject2\SideArray\Seg\train"
output_path = r"output"
patch_h = 1280
patch_w = 1280
names2ids ={"Dent": 1, "Scratch": 2, "Contamination": 3, "Discoloration": 4, "Pitting": 5, "Dust": 6, "HairScratch": 7, "Fiber": 8}
area_thres = 10
image_json_dynamic_slice(image_path=image_path, json_path=json_path, output_path=output_path, patch_h=patch_h, patch_w=patch_w, names2ids=names2ids, area_thres=area_thres)
except Exception as exp:
with open('log.txt', "a") as f:
f.writelines(exp + '\n')
import tkinter as tk
import tkinter.font as tkFont
from deploy import image_json_dynamic_slice
class App:
def __init__(self, root):
root.title("undefined")
width=685
height=494
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
self.GLineEdit_609=tk.Entry(root)
self.GLineEdit_609["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_609["font"] = ft
self.GLineEdit_609["fg"] = "#333333"
self.GLineEdit_609["justify"] = "center"
self.GLineEdit_609_content = tk.StringVar()
self.GLineEdit_609["textvariable"] = self.GLineEdit_609_content
self.GLineEdit_609.place(x=160,y=30,width=287,height=30)
GButton_201=tk.Button(root)
GButton_201["bg"] = "#f0f0f0"
ft = tkFont.Font(family='Times',size=10)
GButton_201["font"] = ft
GButton_201["fg"] = "#000000"
GButton_201["justify"] = "center"
GButton_201["text"] = "开始"
GButton_201.place(x=500,y=380,width=135,height=49)
GButton_201["command"] = self.GButton_201_command
GLabel_825=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_825["font"] = ft
GLabel_825["fg"] = "#333333"
GLabel_825["justify"] = "center"
GLabel_825["text"] = "图像目录"
GLabel_825.place(x=40,y=30,width=70,height=25)
GLabel_478=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_478["font"] = ft
GLabel_478["fg"] = "#333333"
GLabel_478["justify"] = "center"
GLabel_478["text"] = "分割标注目录"
GLabel_478.place(x=40,y=80,width=81,height=30)
self.GLineEdit_786=tk.Entry(root)
self.GLineEdit_786["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_786["font"] = ft
self.GLineEdit_786["fg"] = "#333333"
self.GLineEdit_786["justify"] = "center"
self.GLineEdit_786_content = tk.StringVar()
self.GLineEdit_786["textvariable"] = self.GLineEdit_786_content
self.GLineEdit_786.place(x=160,y=80,width=288,height=30)
GLabel_435=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_435["font"] = ft
GLabel_435["fg"] = "#333333"
GLabel_435["justify"] = "center"
GLabel_435["text"] = "结果输出目录"
GLabel_435.place(x=40,y=130,width=79,height=30)
self.GLineEdit_503=tk.Entry(root)
self.GLineEdit_503["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_503["font"] = ft
self.GLineEdit_503["fg"] = "#333333"
self.GLineEdit_503["justify"] = "center"
self.GLineEdit_503_content = tk.StringVar()
self.GLineEdit_503["textvariable"] = self.GLineEdit_503_content
self.GLineEdit_503.place(x=160,y=130,width=286,height=30)
GLabel_0=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_0["font"] = ft
GLabel_0["fg"] = "#333333"
GLabel_0["justify"] = "center"
GLabel_0["text"] = "切片高"
GLabel_0.place(x=40,y=180,width=70,height=25)
self.GLineEdit_994=tk.Entry(root)
self.GLineEdit_994["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_994["font"] = ft
self.GLineEdit_994["fg"] = "#333333"
self.GLineEdit_994["justify"] = "center"
self.GLineEdit_994_content = tk.StringVar()
self.GLineEdit_994["textvariable"] = self.GLineEdit_994_content
self.GLineEdit_994.place(x=160,y=180,width=158,height=30)
GLabel_469=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_469["font"] = ft
GLabel_469["fg"] = "#333333"
GLabel_469["justify"] = "center"
GLabel_469["text"] = "切片宽"
GLabel_469.place(x=40,y=220,width=70,height=25)
self.GLineEdit_597=tk.Entry(root)
self.GLineEdit_597["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_597["font"] = ft
self.GLineEdit_597["fg"] = "#333333"
self.GLineEdit_597["justify"] = "center"
self.GLineEdit_597_content = tk.StringVar()
self.GLineEdit_597["textvariable"] = self.GLineEdit_597_content
self.GLineEdit_597.place(x=160,y=220,width=160,height=30)
GLabel_213=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_213["font"] = ft
GLabel_213["fg"] = "#333333"
GLabel_213["justify"] = "center"
GLabel_213["text"] = "名称序号字典"
GLabel_213.place(x=40,y=260,width=90,height=30)
self.GLineEdit_82=tk.Entry(root)
self.GLineEdit_82["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_82["font"] = ft
self.GLineEdit_82["fg"] = "#333333"
self.GLineEdit_82["justify"] = "center"
self.GLineEdit_82_content = tk.StringVar()
self.GLineEdit_82["textvariable"] = self.GLineEdit_82_content
self.GLineEdit_82.place(x=160,y=260,width=291,height=30)
GLabel_431=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_431["font"] = ft
GLabel_431["fg"] = "#333333"
GLabel_431["justify"] = "center"
GLabel_431["text"] = "过滤阈值"
GLabel_431.place(x=40,y=310,width=70,height=25)
self.GLineEdit_270=tk.Entry(root)
self.GLineEdit_270["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_270["font"] = ft
self.GLineEdit_270["fg"] = "#333333"
self.GLineEdit_270["justify"] = "center"
self.GLineEdit_270_content = tk.StringVar()
self.GLineEdit_270["textvariable"] = self.GLineEdit_270_content
self.GLineEdit_270.place(x=160,y=310,width=165,height=30)
def GButton_201_command(self):
input1 = self.GLineEdit_609_content.get()
input2 = self.GLineEdit_786_content.get()
input3 = self.GLineEdit_503_content.get()
input4 = self.GLineEdit_994_content.get()
input5 = self.GLineEdit_597_content.get()
input6 = self.GLineEdit_82_content.get()
input7 = self.GLineEdit_270_content.get()
print(input1)
print(input2)
print(input3)
print(input4)
print(input5)
print(input6)
print(input7)
image_json_dynamic_slice(input1,input2,input3,int(input4),int(input5),eval(input6),int(input7))
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
import cv2
import json
import math
import numpy as np
from utils import *
from tqdm import tqdm
class SliceAndSpliceMeta:
def __init__(self) -> None:
self.slice_starts = None
self.slice_ends = None
self.splice_starts = None
self.splice_ends = None
'''
get_meta:获取窗口的meta数据(meta:包含了切分区块的左上角和右下角的坐标)
image_side:原图边长
patch_side:区块边长
'''
def get_meta(image_side, patch_side):
meta = SliceAndSpliceMeta()
if image_side <= patch_side:
meta.slice_starts = [0]
meta.slice_ends = [patch_side]
meta.splice_starts = [0]
meta.splice_ends = [patch_side]
return meta
num = math.ceil(image_side / patch_side)
num_overlaps = num - 1
overlap_pixels = patch_side * num - image_side
base_overlap = math.floor(overlap_pixels / num_overlaps)
remain_pixels = overlap_pixels % num_overlaps
overlaps = [base_overlap] * num_overlaps
for i in range(remain_pixels):
overlaps[i] += 1
slice_starts = [None] * num
slice_ends = [None] * num
for i in range(num):
slice_starts[i] = patch_side * i - sum(ele for ele in overlaps[:i])
slice_ends[i] = patch_side * (i + 1) - sum(ele for ele in overlaps[:i])
rights = [math.floor(overlap / 2) for overlap in overlaps]
lefts = [overlap - right for overlap, right in zip(overlaps, rights)]
splice_starts = [0] + lefts
splice_ends = rights + [0]
tmp = [patch_side] * num
splice_ends = [t - splice_end for t, splice_end in zip(tmp, splice_ends)]
meta.slice_starts = slice_starts
meta.slice_ends = slice_ends
meta.splice_starts = splice_starts
meta.splice_ends = splice_ends
return meta
'''
存切片后的图和切片后的标签
img_patch: 区块图像
mask_patch_and_id_vec: 缺陷mask和对应id列表
area_thres:过滤阈值
path_to_img_patches: 存图地址
path_to_txt_patches: 存标注地址
image.split(".")[0]:图像名称
patch_idx:区块id
task:任务类型,seg或det
'''
def save_patch_and_txt(patch, mask_patch_and_id_vec, area_thres, path_to_img_patches, path_to_txt_patches, filename,
patch_idx, task):
if len(mask_patch_and_id_vec) == 0:
return
patch_h, patch_w = patch.shape[:2]
w_and_h = np.array([patch_w, patch_h], dtype=np.float64)
opened = False
for patch_mask, class_id in mask_patch_and_id_vec:
found_contours, hierarchy = cv2.findContours(patch_mask, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
for found_contour in found_contours:
contour_area = cv2.contourArea(found_contour, False)
if contour_area >= area_thres:
line = f"{class_id - 1} "
if task == "seg":
epsilon = 0.005 * cv2.arcLength(found_contour, True)
approx = cv2.approxPolyDP(found_contour, epsilon, True) if len(
found_contour.reshape(-1).tolist()) > 20 else found_contour
if len(approx.reshape(-1).tolist()) < 6:
continue
approx = approx / w_and_h
elif task == "det":
x1, y1 = found_contour.min(0)[0]
x2, y2 = found_contour.max(0)[0]
approx = np.array([(x1 + x2) / 2.0, (y1 + y2) / 2.0, x2 - x1, y2 - y1]) / np.concatenate(
[w_and_h, w_and_h])
else:
assert False, f"task: '{task}' not support"
line += " ".join(str(ele)[:5] for ele in list(approx.reshape(-1))) + "\n"
if not opened:
f = open(os.path.join(path_to_txt_patches, filename + f"_{patch_idx}.txt"), "w")
opened = True
f.write(line)
if opened:
cv2.imwrite(os.path.join(path_to_img_patches, filename + f"_{patch_idx}.bmp"), patch)
f.close()
def image_json_dynamic_slice(image_path, json_path, output_path, patch_h, patch_w, names2ids, area_thres,overlap):
image_path = image_path
json_path = json_path
'''
检测图像及标注
'''
task = "det"
path_to_img_patches = os.path.join(output_path, "det", "images")
path_to_txt_patches = os.path.join(output_path, "det", "txt")
makedir(path_to_img_patches)
makedir(path_to_txt_patches)
path_vis1 = os.path.join(output_path, "Vis1")
path_vis2 = os.path.join(output_path, "Vis2")
makedir(path_vis1)
makedir(path_vis2)
patch_h = patch_h
patch_w = patch_w
names2ids = names2ids
area_thres = area_thres
images = os.listdir(image_path)
for image in tqdm(images):
if not (os.path.splitext(image)[-1] == ".bmp" or os.path.splitext(image)[-1] == ".jpg" or os.path.splitext(image)[-1] == ".png"):
continue
img = cv2.imdecode(np.fromfile(os.path.join(image_path, image), dtype=np.uint8), flags=cv2.IMREAD_COLOR)
try :
srch, srcw = img.shape[:2]
except Exception as exp:
print(exp)
meta_h = get_meta(srch, patch_h)
meta_w = get_meta(srcw, patch_w)
x1s = []
y1s = []
x2s = []
y2s = []
for x1, x2 in zip(meta_w.slice_starts, meta_w.slice_ends):
x1s.append(x1)
x2s.append(x2)
for y1, y2 in zip(meta_h.slice_starts, meta_h.slice_ends):
y1s.append(y1)
y2s.append(y2)
lts = []
for x1 in x1s:
for y1 in y1s:
lts.append((x1, y1))
rbs = []
for x2 in x2s:
for y2 in y2s:
rbs.append((x2, y2))
contours = []
ids = []
endFile = os.path.splitext(image)[-1]
if not os.path.exists(os.path.join(json_path, image.replace(endFile, ".json"))):
continue
with open(os.path.join(json_path, image.replace(endFile, ".json")),encoding='utf-8-sig',errors='ignore') as f:
label = json.load(f)
for shape in label["shapes"]:
assert shape["label"] in names2ids.keys(), f"{shape['label']} not in 'names2ids'."
contours.append(np.array(shape["points"], dtype=np.int32))
ids.append(names2ids[shape["label"]])
msk = np.zeros((srch, srcw), dtype=np.uint8)
# 绘画检测对象的的poly型mask到原图mask上
for contour, id_ in zip(contours, ids):
# 绘画检测对象 mask
try:
msk = cv2.fillPoly(msk, [contour], id_)
except Exception as exp:
print(exp)
# 画切片可视图(optional)
# 原图深拷贝
plot_img = img.copy()
# 原图mask深拷贝
plot_msk = msk.copy()
# 左上角点和右下角点
for lt, rb in zip(lts, rbs):
# 原图上绘制矩形框
plot_img = cv2.rectangle(plot_img, lt, rb, (255, 255, 255), 1)
# 在原图mask上绘制矩形框
plot_msk = cv2.rectangle(plot_msk, lt, rb, (4, 4, 4), 1)
# 可视化化存图路径
v1_path = os.path.join(path_vis1, image)
v2_path = os.path.join(path_vis2, image)
# 存绘画后的原图
cv2.imwrite(v1_path, plot_img)
# 存绘画后的mask
cv2.imwrite(v2_path, plot_msk * 60)
# 切片
# 区块id
patch_idx = 0
# 遍历左上角点和右下角点
for lt, rb in zip(lts, rbs):
'''
修改处:加上overlap .clip(0, x)用于防呆
'''
overlap = overlap
x1_overlap = np.array(lt[0]-overlap).clip(0, srcw)
x2_overlap = np.array(rb[0]+overlap).clip(0, srcw)
y1_overlap = np.array(lt[1]-overlap).clip(0, srch)
y2_overlap = np.array(rb[1]+overlap).clip(0, srch)
# 深拷贝原图区块
img_patch = img[y1_overlap:y2_overlap, x1_overlap:x2_overlap, :].copy()
# 深拷贝mask区块(重要)
msk_patch = msk[y1_overlap:y2_overlap, x1_overlap:x2_overlap].copy()
# mask和id元组存储列表
mask_patch_and_id_vec = []
# 遍历所有标签类别id,获取所有id对应的缺陷mask
for id_ in names2ids.values():
# 获取对应缺陷类别id的mask(重要)
patch_mask = np.array(msk_patch == id_, dtype=np.uint8)
# 如果存在该缺陷类别的id的mask,则加入列表
if np.any(patch_mask):
mask_patch_and_id_vec.append((patch_mask, id_))
'''
img_patch: 区块图像
mask_patch_and_id_vec: 缺陷mask和对应id列表
area_thres:过滤阈值
path_to_img_patches: 存图地址
path_to_txt_patches: 存标注地址
image.split(".")[0]:图像名称
patch_idx:区块id
task:任务类型,seg或det
'''
save_patch_and_txt(img_patch, mask_patch_and_id_vec, area_thres,
path_to_img_patches, path_to_txt_patches, image.split(".")[0], patch_idx, task)
patch_idx += 1
if __name__ == '__main__':
image_path = rf"F:\PUCPDataSet\Seg0516\A\image"
json_path = rf"F:\PUCPDataSet\Seg0516\A\Seg"
output_path = r"output1111"
patch_h = 2600
patch_w = 2600
names2ids = {"Dent": 1, "Scratch": 2, "Contamination": 3, "Discoloration": 4, "Pitting": 5, "Dust": 6,"HairScratch": 7, "Fiber": 8}
area_thres = 10
overlap = 400
image_json_dynamic_slice(image_path=image_path, json_path=json_path, output_path=output_path, patch_h=patch_h,
patch_w=patch_w, names2ids=names2ids, area_thres=area_thres,overlap=overlap)
import tkinter as tk
import tkinter.font as tkFont
from deploy_overlap import image_json_dynamic_slice
class App:
def __init__(self, root):
root.title("undefined")
width=685
height=494
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
self.GLineEdit_609=tk.Entry(root)
self.GLineEdit_609["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_609["font"] = ft
self.GLineEdit_609["fg"] = "#333333"
self.GLineEdit_609["justify"] = "center"
self.GLineEdit_609_content = tk.StringVar()
self.GLineEdit_609["textvariable"] = self.GLineEdit_609_content
self.GLineEdit_609.place(x=160,y=30,width=287,height=30)
GButton_201=tk.Button(root)
GButton_201["bg"] = "#f0f0f0"
ft = tkFont.Font(family='Times',size=10)
GButton_201["font"] = ft
GButton_201["fg"] = "#000000"
GButton_201["justify"] = "center"
GButton_201["text"] = "开始"
GButton_201.place(x=500,y=380,width=135,height=49)
GButton_201["command"] = self.GButton_201_command
GLabel_825=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_825["font"] = ft
GLabel_825["fg"] = "#333333"
GLabel_825["justify"] = "center"
GLabel_825["text"] = "图像目录"
GLabel_825.place(x=40,y=30,width=70,height=25)
GLabel_478=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_478["font"] = ft
GLabel_478["fg"] = "#333333"
GLabel_478["justify"] = "center"
GLabel_478["text"] = "分割标注目录"
GLabel_478.place(x=40,y=80,width=81,height=30)
self.GLineEdit_786=tk.Entry(root)
self.GLineEdit_786["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_786["font"] = ft
self.GLineEdit_786["fg"] = "#333333"
self.GLineEdit_786["justify"] = "center"
self.GLineEdit_786_content = tk.StringVar()
self.GLineEdit_786["textvariable"] = self.GLineEdit_786_content
self.GLineEdit_786.place(x=160,y=80,width=288,height=30)
GLabel_435=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_435["font"] = ft
GLabel_435["fg"] = "#333333"
GLabel_435["justify"] = "center"
GLabel_435["text"] = "结果输出目录"
GLabel_435.place(x=40,y=130,width=79,height=30)
self.GLineEdit_503=tk.Entry(root)
self.GLineEdit_503["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_503["font"] = ft
self.GLineEdit_503["fg"] = "#333333"
self.GLineEdit_503["justify"] = "center"
self.GLineEdit_503_content = tk.StringVar()
self.GLineEdit_503["textvariable"] = self.GLineEdit_503_content
self.GLineEdit_503.place(x=160,y=130,width=286,height=30)
GLabel_0=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_0["font"] = ft
GLabel_0["fg"] = "#333333"
GLabel_0["justify"] = "center"
GLabel_0["text"] = "切片高"
GLabel_0.place(x=40,y=180,width=70,height=25)
self.GLineEdit_994=tk.Entry(root)
self.GLineEdit_994["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_994["font"] = ft
self.GLineEdit_994["fg"] = "#333333"
self.GLineEdit_994["justify"] = "center"
self.GLineEdit_994_content = tk.StringVar()
self.GLineEdit_994["textvariable"] = self.GLineEdit_994_content
self.GLineEdit_994.place(x=160,y=180,width=158,height=30)
GLabel_469=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_469["font"] = ft
GLabel_469["fg"] = "#333333"
GLabel_469["justify"] = "center"
GLabel_469["text"] = "切片宽"
GLabel_469.place(x=40,y=220,width=70,height=25)
self.GLineEdit_597=tk.Entry(root)
self.GLineEdit_597["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_597["font"] = ft
self.GLineEdit_597["fg"] = "#333333"
self.GLineEdit_597["justify"] = "center"
self.GLineEdit_597_content = tk.StringVar()
self.GLineEdit_597["textvariable"] = self.GLineEdit_597_content
self.GLineEdit_597.place(x=160,y=220,width=160,height=30)
GLabel_213=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_213["font"] = ft
GLabel_213["fg"] = "#333333"
GLabel_213["justify"] = "center"
GLabel_213["text"] = "名称序号字典"
GLabel_213.place(x=40,y=260,width=90,height=30)
self.GLineEdit_82=tk.Entry(root)
self.GLineEdit_82["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_82["font"] = ft
self.GLineEdit_82["fg"] = "#333333"
self.GLineEdit_82["justify"] = "center"
self.GLineEdit_82_content = tk.StringVar()
self.GLineEdit_82["textvariable"] = self.GLineEdit_82_content
self.GLineEdit_82.place(x=160,y=260,width=291,height=30)
GLabel_431=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_431["font"] = ft
GLabel_431["fg"] = "#333333"
GLabel_431["justify"] = "center"
GLabel_431["text"] = "过滤阈值"
GLabel_431.place(x=40,y=310,width=70,height=25)
self.GLineEdit_270=tk.Entry(root)
self.GLineEdit_270["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_270["font"] = ft
self.GLineEdit_270["fg"] = "#333333"
self.GLineEdit_270["justify"] = "center"
self.GLineEdit_270_content = tk.StringVar()
self.GLineEdit_270["textvariable"] = self.GLineEdit_270_content
self.GLineEdit_270.place(x=160,y=310,width=165,height=30)
GLabel_324=tk.Label(root)
ft = tkFont.Font(family='Times',size=10)
GLabel_324["font"] = ft
GLabel_324["fg"] = "#333333"
GLabel_324["justify"] = "center"
GLabel_324["text"] = "Overlap"
GLabel_324.place(x=40,y=360,width=70,height=25)
self.GLineEdit_326=tk.Entry(root)
self.GLineEdit_326["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_326["font"] = ft
self.GLineEdit_326["fg"] = "#333333"
self.GLineEdit_326["justify"] = "center"
self.GLineEdit_326_content = tk.StringVar()
self.GLineEdit_326["textvariable"] = self.GLineEdit_326_content
self.GLineEdit_326.place(x=160,y=360,width=235,height=30)
def GButton_201_command(self):
input1 = self.GLineEdit_609_content.get()
input2 = self.GLineEdit_786_content.get()
input3 = self.GLineEdit_503_content.get()
input4 = self.GLineEdit_994_content.get()
input5 = self.GLineEdit_597_content.get()
input6 = self.GLineEdit_82_content.get()
input7 = self.GLineEdit_270_content.get()
input8 = self.GLineEdit_270_content.get()
print(input1)
print(input2)
print(input3)
print(input4)
print(input5)
print(input6)
print(input7)
image_json_dynamic_slice(input1,input2,input3,int(input4),int(input5),eval(input6),int(input7),int(input8))
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()