前提准备:
掩码制作见最后
原图一张
掩码图一张
例如:
代码
import numpy as np
import cv2
from PIL import Image
mask = Image.open(r'D:\Water_level_gauge\data\video_img\crop_img\stream0\mask\crop_5_18_stream0_day_0.jpg') # 掩码图
img = Image.open(r'D:\Water_level_gauge\data\video_img\crop_img\stream0\img\crop_5_18_stream0_day_0.jpg') # 原图
########################## 原图旋转 ###########################
resize_img = img.resize((int(img.size[0] * 0.3), int(img.size[1] * 0.3)))
resize_img = resize_img.rotate(45)
########################## 掩码旋转 ###########################
resize_mask = mask.resize((int(mask.size[0] * 0.3), int(mask.size[1] * 0.3)))
resize_mask = resize_mask.rotate(45)
########################## 从mask中随便找一个通道,cat到RGB后面做为掩码,最后转成RGBA ###########################
res = np.concatenate((np.array(resize_img), np.array(resize_mask)[:, :, 0:1]), -1)
resize_img = Image.fromarray(res.astype('uint8'), mode='RGBA')
img.paste(resize_img)
img.show()
掩码制作
先用 精灵标注助手 将想要抠图的区域进行抠图,输出格式选择XML
from xml.dom.minidom import parse
import os
from PIL import Image, ImageDraw
import cv2
import numpy as np
# 将标注好的图片生成掩码图片
from xml.dom.minidom import parse
import os
from PIL import Image, ImageDraw
import cv2
import numpy as np
# 将标注好的图片生成掩码图片
def generate_mask(size, position):
'''
:param size: [w, h]
:param position: list数据类型,点按顺序[x0,y0,x1,y1,x2,y2,x3,y3]
:return: 返回PIL数据类型
'''
# 创建而背景图
background = np.zeros([size[1], size[0], 3], dtype=np.uint8)
# 创建mask掩码
pts = np.array([[[position[0], position[1]], [position[2], position[3]],
[position[4], position[5]], [position[6], position[7]]]])
cv2.fillPoly(background, [pts], (255, 255, 255))
# 通道转换
img_cv2 = cv2.cvtColor(background, cv2.COLOR_BGR2RGB)
# 转成PIL数据格式
img = Image.fromarray(img_cv2)
# img.show()
return img
def save_mask_png(xml_path, save_mask, is_save=False):
for xml in os.listdir(xml_path):
print(xml)
xml_file = os.path.join(xml_path, xml)
dom = parse(xml_file) # 通过parse函数创建一个文件操作对象
root = dom.documentElement # 通过文本解析documentElement创建一个文本解析对象
img_name = root.getElementsByTagName("path")[0].childNodes[0].data.split('\\')[-1]
# 获取图片尺寸
try:
size = root.getElementsByTagName("size")[0]
img_w = int(size.getElementsByTagName("width")[0].childNodes[0].data)
img_h = int(size.getElementsByTagName("height")[0].childNodes[0].data)
# print(img_w,img_h)
# 创建背景图
background = Image.new("RGB", (img_w, img_h), (0, 0, 0))
draw = ImageDraw.Draw(background)
object = root.getElementsByTagName("item")
for box in object:
# 如果超过4个点,就在后面继续添加即可
x1 = int(box.getElementsByTagName("x1")[0].childNodes[0].data.split('.')[0])
y1 = int(box.getElementsByTagName("y1")[0].childNodes[0].data.split('.')[0])
x2 = int(box.getElementsByTagName("x2")[0].childNodes[0].data.split('.')[0])
y2 = int(box.getElementsByTagName("y2")[0].childNodes[0].data.split('.')[0])
x3 = int(box.getElementsByTagName("x3")[0].childNodes[0].data.split('.')[0])
y3 = int(box.getElementsByTagName("y3")[0].childNodes[0].data.split('.')[0])
x4 = int(box.getElementsByTagName("x4")[0].childNodes[0].data.split('.')[0])
y4 = int(box.getElementsByTagName("y4")[0].childNodes[0].data.split('.')[0])
mask_img = generate_mask((img_w, img_h), [x1, y1, x2, y2, x3, y3, x4, y4])
if is_save:
mask_img.save(os.path.join(save_mask, img_name))
else:
mask_img.show()
except:
x = 0
# print('此图不生成样本')
if __name__ == '__main__':
xml_path = r'D:\coding\Water_level_gauge\data\output\outputs'
save_mask = r'D:\coding\Water_level_gauge\data\mask_png'
save_mask_png(xml_path, save_mask,is_save=False)