p
y
t
h
o
n
使
用
o
p
e
n
c
v
进
行
数
据
特
征
融
合
python使用opencv进行数据特征融合
python使用opencv进行数据特征融合
缺陷库准备
V1
import os
import json
import base64
import numpy as np
from PIL import Image
from labelme import utils
import cv2
''''
1.读取标签json和原图
'''
json_path = r".\annotations\38.json"
img_path = r".\images\38.bmp"
label_name_to_value = {'_background_': 0}
json_data = json.load(open(json_path))
with open(img_path, 'rb') as f:
imageData = f.read()
imageData = base64.b64encode(imageData).decode('utf-8')
img = utils.img_b64_to_arr(imageData)
''''
2.根据json,获取描边的最小外接矩形,然后进行抠图,获取原图和mask
'''
'''
构建类名和label的字典-label_name_to_value
'''
for shape in json_data['shapes']:
label_name = shape['label']
if label_name in label_name_to_value:
label_value = label_name_to_value[label_name]
else:
label_value = len(label_name_to_value)
label_name_to_value[label_name] = label_value
print('Found new class name:{}/ value: {}'.format(label_name, label_value))
lbl, _ = utils.shapes_to_label(img.shape, json_data['shapes'], label_name_to_value)
lbl = lbl*255
lbl = lbl.astype(np.uint8)
cv2.imwrite(r"./label_masks/mask.jpg",lbl)
contours, hierarchy = cv2.findContours(lbl, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
offset = 10
for c in contours:
if len(c) < 10:
continue
x, y, w, h = cv2.boundingRect(c)
crop = img[y-offset:y + h+offset, x-offset:x + w+offset]
mask = lbl[y-offset:y + h+offset, x-offset:x + w+offset]
cv2.imwrite('./defects/crop.jpg', crop)
cv2.imwrite('./masks/mask.jpg', mask)
V2
import os
import json
import base64
import numpy as np
from PIL import Image
from labelme import utils
import cv2
import time
from utils import *
def generate_defect(json_path,img_path,root_path):
label_name_to_value = {'_background_': 0}
json_data = json.load(open(json_path))
with open(img_path, 'rb') as f:
imageData = f.read()
imageData = base64.b64encode(imageData).decode('utf-8')
img = utils.img_b64_to_arr(imageData)
img_name = os.path.basename(img_path).split('.')[0]
''''
2.根据json,获取描边的最小外接矩形,然后进行抠图,获取原图和mask
'''
'''
构建类名和label的字典-label_name_to_value
'''
for index_shape,shape in enumerate(json_data['shapes']):
label_name = shape['label']
label_groupid = shape['group_id']
if label_name in label_name_to_value:
label_value = label_name_to_value[label_name]
else:
label_value = len(label_name_to_value)
label_name_to_value[label_name] = label_value
print('Found new class name:{}/ value: {}'.format(label_name, label_value))
lbl, _ = utils.shapes_to_label(img.shape, json_data['shapes'], label_name_to_value)
lbl = lbl * 255
lbl = lbl.astype(np.uint8)
cv2.imwrite(os.path.join(root_path, "label_masks", "label_masks"+"_"+str(time.time())+ ".jpg"), lbl)
contours, hierarchy = cv2.findContours(lbl, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
offset = 10
for c in contours:
if len(c) < 10:
continue
x, y, w, h = cv2.boundingRect(c)
crop = img[y - offset:y + h + offset, x - offset:x + w + offset]
mask = lbl[y - offset:y + h + offset, x - offset:x + w + offset]
dir_defect_path = os.path.join(root_path,"defects",label_name+"_"+str(label_groupid)+"_"+img_name+"_"+str(index_shape))
die_mask_path = os.path.join(root_path,"masks",label_name+"_"+str(label_groupid)+"_"+img_name+"_"+str(index_shape))
if not os.path.exists(dir_defect_path):
os.mkdir(dir_defect_path)
if not os.path.exists(die_mask_path):
os.mkdir(die_mask_path)
cv2.imwrite(os.path.join(dir_defect_path,label_name+"_"+str(label_groupid)+".jpg"), crop)
cv2.imwrite(os.path.join(die_mask_path,label_name+"_"+str(label_groupid)+".jpg"), mask)
def generate_defects(defect_repo_path):
''''
1.读取标签json和原图
'''
annotations_path = os.path.join(defect_repo_path,"annotations")
images_path = os.path.join(defect_repo_path,"images")
anns = get_files_path(annotations_path)
anns.sort()
imgs = get_files_path(images_path)
imgs.sort()
for i in range(len(anns)):
generate_defect(json_path=anns[i],img_path=imgs[i],root_path=defect_repo_path)
if __name__ == '__main__':
generate_defects(r"D:\workplace\python\RealAug\defects_repo");
2Augmentor缺陷库数据增强
V1
V2
import Augmentor
from utils import *
def enhance_defect(defect_dirpath, mask_dirpath, cfg ="",sample_num=3):
'''
步骤 1.创建管道Pipeline实例
'''
p = Augmentor.Pipeline(defect_dirpath)
p.ground_truth(mask_dirpath)
sample_num = sample_num
'''
设置标志位
'''
is_rotate = True
is_zoom = True
is_crop = False
is_flip = False
is_brightness = False
is_color = False
is_contrast = False
is_sheer = False
is_skew = False
is_distortion = False
is_erasing = False
'''
设置参数范围
'''
rotate_max_left_rotation = 60
rotate_max_right_rotation = 60
zoom_min_factor = 0.5
zoom_max_factor = 2
crop_percentage_area = 0.8
brightness_min_factor = 0.7
brightness_max_factor = 1.2
color_min_factor = 0.0
color_max_factor = 1.5
contrast_min_factor = 0.7
contrast_max_factor = 1.2
sheer_max_shear_left = 15
sheer_max_shear_right = 15
skew_tilt_magnitude = 1
skew_corner_magnitude = 0.5
distortion_grid_height = 5
distortion_grid_width = 16
distortion_magnitude = 8
erasing_rectangle_area = 0.5
'''
步骤 2:向管道添加数据增强(执行概率+参数范围)操作
'''
process_probability = 1
if is_rotate:
p.rotate_without_crop(probability=process_probability, max_left_rotation=rotate_max_left_rotation,
max_right_rotation=rotate_max_right_rotation)
if is_zoom:
p.zoom(probability=process_probability, min_factor=zoom_min_factor, max_factor=zoom_max_factor)
if is_crop:
p.crop_random(probability=process_probability, percentage_area=crop_percentage_area,
randomise_percentage_area=True)
if is_flip:
p.flip_random(probability=process_probability)
if is_brightness:
p.random_brightness(probability=process_probability, min_factor=brightness_min_factor,
max_factor=brightness_max_factor)
if is_color:
p.random_color(probability=process_probability, min_factor=color_min_factor, max_factor=color_max_factor)
if is_contrast:
p.random_contrast(probability=process_probability, min_factor=contrast_min_factor,
max_factor=contrast_max_factor)
if is_sheer:
p.shear(probability=process_probability, max_shear_left=sheer_max_shear_left,
max_shear_right=sheer_max_shear_right)
if is_skew:
p.skew_tilt(probability=process_probability, magnitude=skew_tilt_magnitude)
p.skew_corner(probability=process_probability, magnitude=skew_corner_magnitude)
if is_distortion:
p.random_distortion(probability=process_probability, grid_height=distortion_grid_height,
grid_width=distortion_grid_width, magnitude=distortion_magnitude)
if is_erasing:
p.random_erasing(probability=process_probability, rectangle_area=erasing_rectangle_area)
'''
步骤 3:生成数据增强后的图像和标签mask
'''
p.sample(sample_num)
p.process()
def enhance_defects(defect_repo_path,cfg,sample_num,is_delete=True):
import os
defects_path = os.path.join(defect_repo_path,"defects")
masks_path = os.path.join(defect_repo_path,"masks")
defects = get_dirs_path(defects_path)
defects.sort()
masks = get_dirs_path(masks_path)
masks.sort()
if is_delete:
for i in defects:
deletedir(os.path.join(i,"output"))
for i in range(len(defects)):
enhance_defect(defect_dirpath=defects[i],mask_dirpath=masks[i],cfg=cfg,sample_num=sample_num)
if __name__ == '__main__':
enhance_defects(defect_repo_path=r"D:\workplace\python\RealAug\defects_repo",cfg="",sample_num=3,is_delete=True)
单个特征融合
V1
import cv2
import numpy as np
from math import sqrt
from PIL import Image
img_back = Image.open(r".\images\85.bmp")
img_back = cv2.cvtColor(np.asarray(img_back), cv2.COLOR_RGB2BGR)
img_obj = cv2.imread(r"./defects/crop.jpg")
mask = cv2.imread(r"./masks/mask.jpg",0)
width,height,channels = img_back.shape
loaction = (height//2,width//2)
normal_clone = cv2.seamlessClone(img_obj,img_back,mask,loaction,cv2.NORMAL_CLONE)
normal_clone = cv2.seamlessClone(img_obj,normal_clone,mask,(height//4,width//2),cv2.NORMAL_CLONE)
cv2.imwrite("./out/normal_clone.jpg",normal_clone)
raw_img = cv2.imread(r"D:\workplace\python\RealAug\label_masks\mask.jpg",0)
w,h = mask.shape
start_x = int(width//2 -w/2)
start_y = int(height//2 - h/2)
for i in range(w):
for j in range(h):
raw_img[start_x + i, start_y + j] = mask[i, j]
cv2.imwrite("label_mask.jpg",raw_img)
![在这里插入图片描述](https://img-blog.csdnimg.cn/91cb87bcc717432384db25ef2245adb6.png)
V2
import cv2
import numpy as np
from math import sqrt
from PIL import Image
import os
def single_feat_merge(imgobj_path, imgback_path, mask_path, out_dir, loaction=(500,500)):
'''
1.生成特征融合图
'''
img_obj = cv2.imread(imgobj_path)
img_back = Image.open(imgback_path)
img_name = os.path.basename(imgback_path)
img_back = cv2.cvtColor(np.asarray(img_back), cv2.COLOR_RGB2BGR)
mask = cv2.imread(mask_path, 0)
loaction = loaction
seamlessClone_style = cv2.NORMAL_CLONE
img_back = cv2.seamlessClone(img_obj, img_back, mask, loaction, seamlessClone_style)
if not os.path.exists(os.path.join(out_dir,"images")):
os.mkdir(os.path.join(out_dir,"images"))
cv2.imwrite(os.path.join(out_dir,"images",img_name), img_back)
'''
2.生成label图
'''
label_img = np.zeros([img_back.shape[0],img_back.shape[1]],dtype=np.uint8)
w, h = mask.shape
start_x = int(width // 2 - w / 2)
start_y = int(height // 2 - h / 2)
for i in range(w):
for j in range(h):
label_img[start_x + i, start_y + j] = mask[i, j]
if not os.path.exists(os.path.join(out_dir,"masks")):
os.mkdir(os.path.join(out_dir,"masks"))
cv2.imwrite(os.path.join(out_dir,"masks",img_name), label_img)
def feat_merge(imgback_path, imgobj_paths, mask_paths, loactions, out_dir):
img_back = Image.open(imgback_path)
img_name = os.path.basename(imgback_path)
img_back = cv2.cvtColor(np.asarray(img_back), cv2.COLOR_RGB2BGR)
label_img = np.zeros([img_back.shape[0],img_back.shape[1]],dtype=np.uint8)
feats_list = []
for i in imgobj_paths:
feats_list.append(cv2.imread(i))
masks_list = []
for i in mask_paths:
masks_list.append(cv2.imread(i,0))
loactions_list = loactions
for i in range(len(feats_list)):
img_back = cv2.seamlessClone(feats_list[i], img_back, masks_list[i], loactions_list[i], cv2.NORMAL_CLONE)
w, h = masks_list[i].shape
start_x = int(loactions_list[i][0] - w / 2)
start_y = int(loactions_list[i][1] - h / 2)
for i_w in range(w):
for j_h in range(h):
label_img[start_x + i_w, start_y + j_h] = masks_list[i][i_w, j_h]
if not os.path.exists(os.path.join(out_dir,"images")):
os.mkdir(os.path.join(out_dir,"images"))
cv2.imwrite(os.path.join(out_dir,"images",img_name), img_back)
if not os.path.exists(os.path.join(out_dir,"masks")):
os.mkdir(os.path.join(out_dir,"masks"))
cv2.imwrite(os.path.join(out_dir,"masks",img_name), label_img)
def feats_merge():
imgback_path = r"D:\workplace\python\RealAug\images\34.bmp"
imgobj_paths = [r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\dc_1_34_0_original_dc_1.jpg_3c10e17f-522a-4b1c-bd33-41f5be9aaa2b.jpg",r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\dc_1_34_0_original_dc_1.jpg_9b6565f0-31de-4484-b93f-8907b1b57a18.jpg"]
mask_paths = [r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\_groundtruth_(1)_dc_1_34_0_dc_1.jpg_3c10e17f-522a-4b1c-bd33-41f5be9aaa2b.jpg",r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\_groundtruth_(1)_dc_1_34_0_dc_1.jpg_9b6565f0-31de-4484-b93f-8907b1b57a18.jpg"]
loactions = [(500,500),(1000,1000)]
feat_merge(imgback_path=imgback_path, imgobj_paths=imgobj_paths, mask_paths=mask_paths, loactions=loactions, out_dir=r"D:\workplace\python\RealAug\enhance")
if __name__ == '__main__':
feats_merge()
V3
import cv2
import numpy as np
from PIL import Image
import os
import random
from utils import *
import tqdm
from labelme import utils
import json
import os
import glob
import cv2
import json
def generate_segjson(label_mask_path, raw_json_path, group_id,out_dir):
json_data = json.load(open(raw_json_path))
raw_json_name = os.path.basename(raw_json_path)
'''
1.读取图像,获取图像的宽高
'''
mask_lbl = cv2.imread(label_mask_path, 0)
'''
2.findcontour,获取mask的所有点
'''
contours, hierarchy = cv2.findContours(mask_lbl, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
list_polygon_points = []
for c in contours:
if len(c) < 100:
continue
'''
生成分割任务的分割json
'''
points = c[:, 0, :]
list_polygon_points.append(points)
'''
3.对分割任务的分割json文件进行赋值
'''
shapes = list(json_data['shapes'])
for index_countour in list_polygon_points:
shape = {}
shape['points'] = index_countour.tolist()
shape['label'] = "dc"
shape['group_id'] = group_id
shape['shape_type'] = "polygon"
shapes.append(shape)
json_data['shapes'] = shapes
'''
4.生成json
'''
if not os.path.exists(os.path.join(out_dir, 'annotations')):
os.mkdir(os.path.join(out_dir, 'annotations'))
json_file = os.path.join(out_dir,'annotations' ,raw_json_name)
with open(json_file, 'w') as f:
json.dump(json_data, f, indent=2)
def feat_merge(imgback_path,label_json_path, imgobj_paths, mask_paths, loactions, group_id,out_dir):
if not os.path.exists(out_dir):
os.mkdir(out_dir)
img_back = Image.open(imgback_path)
img_name = os.path.basename(imgback_path).split(".")[0]
img_back = cv2.cvtColor(np.asarray(img_back), cv2.COLOR_RGB2BGR)
label_img = np.zeros([img_back.shape[0],img_back.shape[1]],dtype=np.uint8)
feats_list = []
for i in imgobj_paths:
feats_list.append(cv2.imread(i))
masks_list = []
for i in mask_paths:
masks_list.append(cv2.imread(i,0))
loactions_list = loactions
success_merge_num = 0
for i in range(len(loactions)):
h, w = masks_list[i].shape
start_x = int(loactions_list[i][0] - w / 2)
start_y = int(loactions_list[i][1] - h / 2)
if start_x < 0 or start_y < 0:
continue
for i_w in range(w):
for j_h in range(h):
try:
label_img[start_y + j_h, start_x + i_w] = masks_list[i][j_h, i_w]
except Exception as exp:
print(exp)
try:
img_back = cv2.seamlessClone(feats_list[i], img_back, masks_list[i], loactions_list[i], cv2.NORMAL_CLONE)
success_merge_num = success_merge_num +1
if success_merge_num == len(feats_list):
break
except Exception as exp:
print(exp)
if not os.path.exists(os.path.join(out_dir,"images")):
os.mkdir(os.path.join(out_dir,"images"))
cv2.imwrite(os.path.join(out_dir,"images",img_name+".jpg"), img_back)
if not os.path.exists(os.path.join(out_dir,"masks")):
os.mkdir(os.path.join(out_dir,"masks"))
cv2.imwrite(os.path.join(out_dir,"masks",img_name+".jpg"), label_img)
generate_segjson(label_mask_path=os.path.join(out_dir,"masks",img_name+".jpg"), raw_json_path=label_json_path, group_id=group_id, out_dir=out_dir)
def generate_locations(raw_img_path,sample_num,x_offset = 300,y_offset=300):
img_back = cv2.imread(raw_img_path , 0)
'''
1.阈值分割
2.获取最小外接矩形的x,y,x,y
3.设置offset
4.判定随机生成的坐标是否在此范围内
'''
y1 = 0
x1 = 0
y2 = img_back.shape[0]
x2 = img_back.shape[1]
x1_new = x1 + x_offset
y1_new = y1 + y_offset
x2_new = x2 - x_offset
y2_new = y2 - y_offset
locations = []
for index_3dd in range(sample_num):
locations.append((int(random.uniform(x1_new, x2_new)), int(random.uniform(y1_new, y2_new))))
return locations
def feats_merge(img_paths="images",anno_json_path="annotations",defects_masks_path="defects_repo/defects",group_id=1,defects_num=3,out_dir=r"D:\workplace\python\RealAug\enhance"):
imgs_list = get_files_path(img_paths)
imgs_list.sort()
anno_json_list = get_files_path(anno_json_path)
anno_json_list.sort()
for index_imgpath ,img_path in enumerate(tqdm.tqdm(imgs_list)):
imgback_path = img_path
label_json_path = anno_json_list[index_imgpath]
loactions_list = generate_locations(raw_img_path=imgback_path,sample_num=100,x_offset=800,y_offset=700)
imgobj_paths = [r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\dc_1_34_0_original_dc_1.jpg_3c10e17f-522a-4b1c-bd33-41f5be9aaa2b.jpg",r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\dc_1_34_0_original_dc_1.jpg_9b6565f0-31de-4484-b93f-8907b1b57a18.jpg"]
mask_paths = [r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\_groundtruth_(1)_dc_1_34_0_dc_1.jpg_3c10e17f-522a-4b1c-bd33-41f5be9aaa2b.jpg",r"D:\workplace\python\RealAug\defects_repo\defects\dc_1_34_0\output\_groundtruth_(1)_dc_1_34_0_dc_1.jpg_9b6565f0-31de-4484-b93f-8907b1b57a18.jpg"]
feat_merge(imgback_path=imgback_path, label_json_path=label_json_path,imgobj_paths=imgobj_paths, mask_paths=mask_paths, loactions=loactions_list, group_id=group_id,out_dir=out_dir)
if __name__ == '__main__':
feats_merge(img_paths="images",anno_json_path="annotations",defects_masks_path="defects_repo/defects", group_id=1, defects_num=3)
随机生成坐标点
import numpy as np
point_num = 10
'''
随机生成坐标
'''
width = 1200
height = 800
X = np.random.rand(1, point_num) * width
X = X.flatten()
Y = np.random.rand(1, point_num) * height
Y = Y.flatten()
points = []
for i in range(len(X)):
points.append((int(X[i]),int(Y[i])))
print(points)
随机多特征融合
'''
1.读取标签json和原图,获取
'''
import cv2
import numpy as np
from math import sqrt
from PIL import Image
img_back = Image.open(r".\images\85.bmp")
img_back = cv2.cvtColor(np.asarray(img_back), cv2.COLOR_RGB2BGR)
img_obj = cv2.imread(r"./defects/crop.jpg")
mask = cv2.imread(r"./masks/masks.jpg")
point_num = 100
'''
随机生成坐标
'''
width,height,channels = img_back.shape
X = np.random.rand(1, point_num) * width
X = X.flatten()
Y = np.random.rand(1, point_num) * height
Y = Y.flatten()
points = []
for i in range(len(X)):
points.append((int(X[i]),int(Y[i])))
for i_location in points:
try:
img_back = cv2.seamlessClone(img_obj, img_back, mask, i_location, cv2.NORMAL_CLONE)
cv2.imwrite("./out/normal_clone.jpg", img_back)
except Exception as e:
print(e)
5生成融合后分割json
import os
import glob
import cv2
import json
'''
1.读取图像,获取图像的宽高
'''
mask_lbl = cv2.imread(r"D:\workplace\python\RealAug\label_masks\label_mask.jpg",0)
'''
2.findcontour,获取mask的所有点
'''
contours, hierarchy = cv2.findContours(mask_lbl, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
list_rect = []
list_polygon_points = []
for c in contours:
if len(c) < 10:
continue
'''
生成检测任务的检测json
'''
x, y, w, h = cv2.boundingRect(c)
list_rect.append((x, y, w, h))
'''
生成分割任务的分割json
'''
points = c[ :, 0, :]
list_polygon_points.append(points)
'''
3.对分割任务的分割json文件进行赋值
'''
json_str = {}
json_str['version'] = "0.0.1"
json_str['flags'] = {}
shapes = []
width, height = mask_lbl.shape
imagePath = ""
imageData = ""
cls_name = "dc"
group_id = 1
for index_countour in list_polygon_points:
shape = {}
shape['points'] = index_countour.tolist()
shape['label'] = cls_name
shape['group_id'] = group_id
shape['shape_type'] = "polygon"
shapes.append(shape)
json_str['shapes'] = shapes
json_str['imagePath'] = imagePath
json_str['imageData'] = imageData
json_str['imageHeight'] = height
json_str['imageWidth'] = width
'''
4.生成json
'''
json_file = os.path.join("./", 'out1.json')
with open(json_file, 'w') as f:
json.dump(json_str, f, indent=2)
{
"version": "0.0.1",
"flags": {},
"shapes": [
{
"points": ,
"label": "dc",
"group_id": 1,
"shape_type": "polygon"
},
{
"points": ,
"label": "dc",
"group_id": 1,
"shape_type": "polygon"
}
],
"imagePath": "",
"imageData": "",
"imageHeight": 5120,
"imageWidth": 2000
}
6生成融合后检测json
import os
import cv2
import json
'''
1.读取图像,获取图像的宽高
'''
mask_lbl = cv2.imread(r"D:\workplace\python\RealAug\label_masks\label_mask.jpg",0)
width, height = mask_lbl.shape
image_data = None
img_path = ""
'''
2.findcontour,获取mask的所有点
'''
contours, hierarchy = cv2.findContours(mask_lbl, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
list_rect = []
list_polygon_points = []
for c in contours:
if len(c) < 10:
continue
'''
生成检测任务的检测json
'''
x, y, w, h = cv2.boundingRect(c)
list_rect.append([x, y, w, h])
'''
3.对检测任务的检测json文件进行赋值
'''
json_res = []
json_str = {}
annotations = []
width, height = mask_lbl.shape
imagePath = ""
imageData = ""
cls_name = "dc"
group_id = 1
for index_rect in list_rect:
annotation = {}
annotation['label'] = cls_name
annotation['group_id'] = group_id
coordinates = {}
coordinates['x'] = index_rect[0]
coordinates['y'] = index_rect[1]
coordinates['width'] = index_rect[2]
coordinates['height'] = index_rect[3]
annotation['coordinates'] = coordinates
annotations.append(annotation)
json_str['image'] = "Image"
json_str['annotations'] = annotations
json_str['isReasoned'] = False
json_res.append(json_str)
'''
4.生成json
'''
json_file = os.path.join("./", 'out_rect.json')
with open(json_file, 'w') as f:
json.dump(json_res, f, indent=2)
[
{
"image": "Image",
"annotations": [
{
"label": "dc",
"group_id": 1,
"coordinates": {
"x": 2904,
"y": 1392,
"width": 128,
"height": 104
}
},
{
"label": "dc",
"group_id": 1,
"coordinates": {
"x": 2496,
"y": 948,
"width": 131,
"height": 107
}
}
],
"isReasoned": false
}
]
Frm1_缺陷录入
import tkinter as tk
import tkinter.font as tkFont
from utils import *
import cv2
import json
import base64
import numpy as np
from PIL import Image
from labelme import utils
class App1:
def __init__(self, root):
root.title("undefined")
width=660
height=541
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_865=tk.Entry(root)
self.GLineEdit_865["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_865["font"] = ft
self.GLineEdit_865["fg"] = "#333333"
self.GLineEdit_865["justify"] = "center"
self.GLineEdit_865_content = tk.StringVar()
self.GLineEdit_865["textvariable"] = self.GLineEdit_865_content
self.GLineEdit_865.place(x=60,y=50,width=260,height=30)
self.GLineEdit_758=tk.Entry(root)
self.GLineEdit_758["borderwidth"] = "1px"
ft = tkFont.Font(family='Times',size=10)
self.GLineEdit_758["font"] = ft
self.GLineEdit_758["fg"] = "#333333"
self.GLineEdit_758["justify"] = "center"
self.GLineEdit_758_content = tk.StringVar()
self.GLineEdit_758["textvariable"] = self.GLineEdit_758_content
self.GLineEdit_758.place(x=60,y=100,width=260,height=30)
GButton_409=tk.Button(root)
GButton_409["bg"] = "#f0f0f0"
ft = tkFont.Font(family='Times',size=10)
GButton_409["font"] = ft
GButton_409["fg"] = "#000000"
GButton_409["justify"] = "center"
GButton_409["text"] = "选取json"
GButton_409.place(x=370,y=50,width=156,height=30)
GButton_409["command"] = self.GButton_409_command
GButton_674=tk.Button(root)
GButton_674["bg"] = "#f0f0f0"
ft = tkFont.Font(family='Times',size=10)
GButton_674["font"] = ft
GButton_674["fg"] = "#000000"
GButton_674["justify"] = "center"
GButton_674["text"] = "选取原图"
GButton_674.place(x=370,y=100,width=156,height=30)
GButton_674["command"] = self.GButton_674_command
GButton_287=tk.Button(root)
GButton_287["bg"] = "#f0f0f0"
ft = tkFont.Font(family='Times',size=10)
GButton_287["font"] = ft
GButton_287["fg"] = "#000000"
GButton_287["justify"] = "center"
GButton_287["text"] = "录入缺陷"
GButton_287.place(x=370,y=160,width=159,height=30)
GButton_287["command"] = self.GButton_287_command
def GButton_409_command(self):
'''
json文件
:return:
'''
print("command")
self.jsonfile_path = openfile()
print(self.jsonfile_path)
self.GLineEdit_865_content.set(self.jsonfile_path)
def GButton_674_command(self):
'''
原图文件
:return:
'''
print("command")
self.img_path = openfile()
print(self.img_path)
self.GLineEdit_758_content.set(self.img_path)
def GButton_287_command(self):
'''
录入缺陷
:return:
'''
''''
1.读取标签json和原图
'''
json_path = self.GLineEdit_865_content.get()
img_path = self.GLineEdit_758_content.get()
label_name_to_value = {'_background_': 0}
json_data = json.load(open(json_path))
with open(img_path, 'rb') as f:
imageData = f.read()
imageData = base64.b64encode(imageData).decode('utf-8')
img = utils.img_b64_to_arr(imageData)
''''
2.根据json,获取描边的最小外接矩形,然后进行抠图,获取原图和mask
'''
'''
构建类名和label的字典-label_name_to_value
'''
for shape in json_data['shapes']:
label_name = shape['label']
if label_name in label_name_to_value:
label_value = label_name_to_value[label_name]
else:
label_value = len(label_name_to_value)
label_name_to_value[label_name] = label_value
print('Found new class name:{}/ value: {}'.format(label_name, label_value))
lbl, _ = utils.shapes_to_label(img.shape, json_data['shapes'], label_name_to_value)
lbl = lbl * 255
lbl = lbl.astype(np.uint8)
cv2.imwrite(r"./label_masks/crop11.jpg", lbl)
contours, hierarchy = cv2.findContours(lbl, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
offset = 10
for c in contours:
if len(c) < 10:
continue
x, y, w, h = cv2.boundingRect(c)
crop = img[y - offset:y + h + offset, x - offset:x + w + offset]
mask = lbl[y - offset:y + h + offset, x - offset:x + w + offset]
cv2.imwrite('./defects/crop11.jpg', crop)
cv2.imwrite('./masks/crop11.jpg', mask)
if __name__ == "__main__":
root = tk.Tk()
app = App1(root)
root.mainloop()
Frm2_缺陷增强
Frm3_选取融合
import cv2
import numpy as np
from PIL import Image
import os
import random
from utils import *
import tqdm
from labelme import utils
import json
import os
import glob
import cv2
import json
def generate_segjson(label_mask_path, raw_json_path, group_id,out_dir):
json_data = json.load(open(raw_json_path))
raw_json_name = os.path.basename(raw_json_path)
'''
1.读取图像,获取图像的宽高
'''
mask_lbl = cv2.imread(label_mask_path, 0)
'''
2.findcontour,获取mask的所有点
'''
contours, hierarchy = cv2.findContours(mask_lbl, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
list_polygon_points = []
for c in contours:
if len(c) < 100:
continue
'''
生成分割任务的分割json
'''
points = c[:, 0, :]
list_polygon_points.append(points)
'''
3.对分割任务的分割json文件进行赋值
'''
shapes = list(json_data['shapes'])
for index_countour in list_polygon_points:
shape = {}
shape['points'] = index_countour.tolist()
shape['label'] = "dc"
shape['group_id'] = group_id
shape['shape_type'] = "polygon"
shapes.append(shape)
json_data['shapes'] = shapes
'''
4.生成json
'''
if not os.path.exists(os.path.join(out_dir, 'annotations')):
os.mkdir(os.path.join(out_dir, 'annotations'))
json_file = os.path.join(out_dir,'annotations' ,raw_json_name)
with open(json_file, 'w') as f:
json.dump(json_data, f, indent=2)
def feat_merge(imgback_path,label_json_path, imgobj_paths, mask_paths, loactions, group_id,out_dir):
if not os.path.exists(out_dir):
os.mkdir(out_dir)
img_back = Image.open(imgback_path)
img_name = os.path.basename(imgback_path).split(".")[0]
img_back = cv2.cvtColor(np.asarray(img_back), cv2.COLOR_RGB2BGR)
label_img = np.zeros([img_back.shape[0],img_back.shape[1]],dtype=np.uint8)
feats_list = []
for i in imgobj_paths:
feats_list.append(cv2.imread(i))
masks_list = []
for i in mask_paths:
masks_list.append(cv2.imread(i,0))
loactions_list = loactions
success_merge_num = 0
for i in range(len(loactions)):
h, w = masks_list[i].shape
start_x = int(loactions_list[i][0] - w / 2)
start_y = int(loactions_list[i][1] - h / 2)
if start_x < 0 or start_y < 0:
continue
for i_w in range(w):
for j_h in range(h):
try:
label_img[start_y + j_h, start_x + i_w] = masks_list[i][j_h, i_w]
except Exception as exp:
print(exp)
try:
img_back = cv2.seamlessClone(feats_list[i], img_back, masks_list[i], loactions_list[i], cv2.NORMAL_CLONE)
success_merge_num = success_merge_num +1
if success_merge_num == len(feats_list):
break
except Exception as exp:
print(exp)
if not os.path.exists(os.path.join(out_dir,"images")):
os.mkdir(os.path.join(out_dir,"images"))
cv2.imwrite(os.path.join(out_dir,"images",img_name+".jpg"), img_back)
if not os.path.exists(os.path.join(out_dir,"masks")):
os.mkdir(os.path.join(out_dir,"masks"))
cv2.imwrite(os.path.join(out_dir,"masks",img_name+".jpg"), label_img)
generate_segjson(label_mask_path=os.path.join(out_dir,"masks",img_name+".jpg"), raw_json_path=label_json_path, group_id=group_id, out_dir=out_dir)
def generate_locations(raw_img_path,sample_num,x_offset = 300,y_offset=300):
img_back = cv2.imread(raw_img_path , 0)
'''
1.阈值分割
2.获取最小外接矩形的x,y,x,y
3.设置offset
4.判定随机生成的坐标是否在此范围内
'''
y1 = 0
x1 = 0
y2 = img_back.shape[0]
x2 = img_back.shape[1]
x1_new = x1 + x_offset
y1_new = y1 + y_offset
x2_new = x2 - x_offset
y2_new = y2 - y_offset
locations = []
for index_3dd in range(sample_num):
locations.append((int(random.uniform(x1_new, x2_new)), int(random.uniform(y1_new, y2_new))))
return locations
def feats_merge(img_paths="images",anno_json_path="annotations",defects_masks_path="defects_repo/defects",group_id=1,defects_num=3,out_dir=r"D:\workplace\python\RealAug\enhance"):
'''
批量缺陷融合
:param img_paths:
:param anno_json_path:
:param defects_masks_path:
:param group_id:
:param defects_num:
:param out_dir:
:return:
'''
'''
1.缺陷选择
'''
support_selected_defect_dirs = get_dirs_path(defects_masks_path)
support_defect_dirs = []
for defect_dir in support_selected_defect_dirs:
if os.path.basename(defect_dir).split("_")[1] == str(group_id):
support_defect_dirs.append(defect_dir)
enhance_defect_dirs = random.choices(support_defect_dirs,k=defects_num)
imgobj_paths = []
mask_paths = []
for enhance_defect_dir in enhance_defect_dirs:
defect_file_paths = get_files_path(os.path.join(enhance_defect_dir,"output"))
defect_file_paths.sort()
imgobj_paths.append(defect_file_paths[0])
num = int(len(defect_file_paths) / 2)
mask_paths.append(defect_file_paths[num])
'''
2.确定原图和json路径
'''
imgs_list = get_files_path(img_paths)
imgs_list.sort()
anno_json_list = get_files_path(anno_json_path)
anno_json_list.sort()
'''
3.批量融合
'''
for index_imgpath ,img_path in enumerate(tqdm.tqdm(imgs_list)):
imgback_path = img_path
label_json_path = anno_json_list[index_imgpath]
loactions_list = generate_locations(raw_img_path=imgback_path,sample_num=100,x_offset=800,y_offset=700)
feat_merge(imgback_path=imgback_path, label_json_path=label_json_path,imgobj_paths=imgobj_paths, mask_paths=mask_paths, loactions=loactions_list, group_id=group_id,out_dir=out_dir)
if __name__ == '__main__':
feats_merge(img_paths=r"D:\defects_repo\images",anno_json_path=r"D:\defects_repo/annotations",defects_masks_path=r"D:\defects_repo/defects", group_id=1, defects_num=3,out_dir=r"D:\enhance")
import cv2
import numpy as np
from PIL import Image
import os
import random
from utils import *
import tqdm
from labelme import utils
import json
import os
import glob
import cv2
import json
def generate_segjson(label_mask_path, raw_json_path, group_id,out_dir):
json_data = json.load(open(raw_json_path))
raw_json_name = os.path.basename(raw_json_path)
'''
1.读取图像,获取图像的宽高
'''
mask_lbl = cv2.imread(label_mask_path, 0)
'''
2.findcontour,获取mask的所有点
'''
contours, hierarchy = cv2.findContours(mask_lbl, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
list_polygon_points = []
for c in contours:
if len(c) < 100:
continue
'''
生成分割任务的分割json
'''
points = c[:, 0, :]
list_polygon_points.append(points)
'''
3.对分割任务的分割json文件进行赋值
'''
shapes = list(json_data['shapes'])
for index_countour in list_polygon_points:
shape = {}
shape['points'] = index_countour.tolist()
shape['label'] = "dc"
shape['group_id'] = group_id
shape['shape_type'] = "polygon"
shapes.append(shape)
json_data['shapes'] = shapes
'''
4.生成json
'''
if not os.path.exists(os.path.join(out_dir, 'annotations')):
os.mkdir(os.path.join(out_dir, 'annotations'))
json_file = os.path.join(out_dir,'annotations' ,raw_json_name)
with open(json_file, 'w') as f:
json.dump(json_data, f, indent=2)
def feat_merge(imgback_path,label_json_path, imgobj_paths, mask_paths, loactions, group_id,out_dir):
'''
缺陷融合
:param imgback_path:
:param label_json_path:
:param imgobj_paths:
:param mask_paths:
:param loactions:
:param group_id:
:param out_dir:
:return:
'''
if not os.path.exists(out_dir):
os.mkdir(out_dir)
img_back = Image.open(imgback_path)
img_name = os.path.basename(imgback_path).split(".")[0]
img_back = cv2.cvtColor(np.asarray(img_back), cv2.COLOR_RGB2BGR)
label_img = np.zeros([img_back.shape[0],img_back.shape[1]],dtype=np.uint8)
feats_list = []
for i in imgobj_paths:
feats_list.append(cv2.imread(i))
masks_list = []
for i in mask_paths:
masks_list.append(cv2.imread(i,0))
loactions_list = loactions
success_merge_num = 0
for i in range(len(loactions)):
h, w = masks_list[i].shape
start_x = int(loactions_list[i][0] - w / 2)
start_y = int(loactions_list[i][1] - h / 2)
if start_x < 0 or start_y < 0:
continue
for i_w in range(w):
for j_h in range(h):
try:
label_img[start_y + j_h, start_x + i_w] = masks_list[i][j_h, i_w]
except Exception as exp:
print(exp)
try:
img_back = cv2.seamlessClone(feats_list[i], img_back, masks_list[i], loactions_list[i], cv2.NORMAL_CLONE)
success_merge_num = success_merge_num +1
if success_merge_num == len(feats_list):
break
except Exception as exp:
print(exp)
if not os.path.exists(os.path.join(out_dir,"images")):
os.mkdir(os.path.join(out_dir,"images"))
cv2.imwrite(os.path.join(out_dir,"images",img_name+".jpg"), img_back)
if not os.path.exists(os.path.join(out_dir,"masks")):
os.mkdir(os.path.join(out_dir,"masks"))
cv2.imwrite(os.path.join(out_dir,"masks",img_name+".jpg"), label_img)
generate_segjson(label_mask_path=os.path.join(out_dir,"masks",img_name+".jpg"), raw_json_path=label_json_path, group_id=group_id, out_dir=out_dir)
def generate_locations(raw_img_path,sample_num,x_offset = 300,y_offset=300,is_hard=False):
img_back = cv2.imread(raw_img_path , 0)
locations = []
'''
1.阈值分割
2.获取最小外接矩形的x,y,x,y
3.设置offset
4.判定随机生成的坐标是否在此范围内
'''
if is_hard:
y1 = 0
x1 = 0
y2 = img_back.shape[0]
x2 = img_back.shape[1]
x1_new = x1 + x_offset
y1_new = y1 + y_offset
x2_new = x2 - x_offset
y2_new = y2 - y_offset
for index_3dd in range(sample_num):
locations.append((int(random.uniform(x1_new, x2_new)), int(random.uniform(y1_new, y2_new))))
else:
ret, th1 = cv2.threshold(img_back, 30, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(th1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
lens_contour = []
for c in contours:
lens_contour.append(len(c))
lens_c_value = max(lens_contour)
max_contour_index = lens_contour.index(lens_c_value)
z = np.random.random(size=[len(contours[max_contour_index]), 999])
max_contour = contours[max_contour_index]
img_back = cv2.imread(raw_img_path)
xx = max_contour[:,0,0]
yy = max_contour[:,0,1]
x = (z / sum(z)).T.dot(xx)
y = (z / sum(z)).T.dot(yy)
for i_x in range(sample_num):
index_points = int(random.uniform(0, 999))
locations.append((int(x[index_points]),int(y[index_points])))
return locations
def feats_merge(img_paths="images",anno_json_path="annotations",defects_masks_path="defects_repo/defects",group_id=1,defects_num=3,out_dir=r"D:\workplace\python\RealAug\enhance"):
'''
批量缺陷融合
:param img_paths:
:param anno_json_path:
:param defects_masks_path:
:param group_id:
:param defects_num:
:param out_dir:
:return:
'''
'''
1.缺陷选择
'''
support_selected_defect_dirs = get_dirs_path(defects_masks_path)
support_defect_dirs = []
for defect_dir in support_selected_defect_dirs:
if os.path.basename(defect_dir).split("_")[1] == str(group_id):
support_defect_dirs.append(defect_dir)
enhance_defect_dirs = random.choices(support_defect_dirs,k=defects_num)
imgobj_paths = []
mask_paths = []
for enhance_defect_dir in enhance_defect_dirs:
defect_file_paths = get_files_path(os.path.join(enhance_defect_dir,"output"))
defect_file_paths.sort()
mask_paths.append(defect_file_paths[0])
num = int(len(defect_file_paths) / 2)
imgobj_paths.append(defect_file_paths[num])
'''
2.确定原图和json路径
'''
imgs_list = get_files_path(img_paths)
imgs_list.sort()
anno_json_list = get_files_path(anno_json_path)
anno_json_list.sort()
'''
3.批量融合
'''
for index_imgpath ,img_path in enumerate(tqdm.tqdm(imgs_list)):
imgback_path = img_path
label_json_path = anno_json_list[index_imgpath]
loactions_list = generate_locations(raw_img_path=imgback_path,sample_num=100,x_offset=800,y_offset=700,is_hard=False)
feat_merge(imgback_path=imgback_path, label_json_path=label_json_path,imgobj_paths=imgobj_paths, mask_paths=mask_paths, loactions=loactions_list, group_id=group_id,out_dir=out_dir)
if __name__ == '__main__':
feats_merge(img_paths=r"D:\defects_repo\images",anno_json_path=r"D:\defects_repo/annotations",defects_masks_path=r"D:\defects_repo/defects", group_id=1, defects_num=3,out_dir=r"D:\enhance")