文章目录
提取方式一:背景为黑色
将 YOLO 语义分割的 txt 标注文件还原到原图中,并将目标区域填充为纯白色,背景区域填充为纯黑色
注意:该标注文件为txt格式,且是图像分割的标注文件(标准格式),不是目标识别的矩形框
python
import cv2
import numpy as np
'''
将txt标注文件中的目标区域还原为白色,背景区域为纯黑色
'''
def read_txt_labels(txt_file):
"""
从 txt 标注文件中读取标签
:param txt_file: txt 标注文件路径
:return: 标签列表
"""
with open(txt_file, "r") as f:
labels = []
for line in f.readlines():
label_data = line.strip().split(" ")
class_id = int(label_data[0])
# 解析边界框坐标
coordinates = [float(x) for x in label_data[1:]]
labels.append([class_id, coordinates])
return labels
def draw_labels(image, labels):
"""
在图像上绘制分割区域
:param image: 图像
:param labels: 标签列表
"""
for label in labels:
class_id, coordinates = label
# 将坐标转换为整数并重新塑形为多边形
points = [(int(x * image.shape[1]), int(y * image.shape[0])) for x, y in zip(coordinates[::2], coordinates[1::2])]
# 使用多边形填充纯白色
cv2.fillPoly(image, [np.array(points)], (255, 255, 255))
def main():
"""
将 YOLO 语义分割的 txt 标注文件还原到原图中,并将目标区域填充为纯白色,背景区域填充为纯黑色
"""
# 读取图像
image = cv2.imread("D:\Desktop\gasdata\\02images_remove_color\\0002.jpg")
# 初始化图像为纯黑色背景
image[:] = (0, 0, 0)
# 读取 txt 标注文件
txt_file = "D:\Desktop\gasdata\\04txt\\0002.txt"
labels = read_txt_labels(txt_file)
# 绘制分割区域
draw_labels(image, labels)
# 保存图片
cv2.imwrite('D:\\Desktop\\0002.jpg', image)
# 显示图片
cv2.imshow("Image", image)
cv2.waitKey(0)
if __name__ == "__main__":
main()
示例:
提取结果:
提取方式二:背景为指定图片
注意:该方式要求指定的背景图片要和原图大小一样
python
'''
提取出txt目标区域,放到background.jpg画布上,然后保存
'''
import cv2
import numpy as np
def read_txt_labels(txt_file):
"""
从 txt 标注文件中读取标签
:param txt_file: txt 标注文件路径
:return: 标签列表
"""
with open(txt_file, "r") as f:
labels = []
for line in f.readlines():
label_data = line.strip().split(" ")
class_id = int(label_data[0])
# 解析边界框坐标
coordinates = [float(x) for x in label_data[1:]]
labels.append([class_id, coordinates])
return labels
def draw_labels_on_background(image, labels, background):
"""
在背景图像上绘制分割区域
:param image: 源图像
:param labels: 标签列表
:param background: 背景图像
"""
mask = np.zeros_like(image, dtype=np.uint8) # 创建一个与源图像相同大小的遮罩
for label in labels:
class_id, coordinates = label
# 将坐标转换为整数并重新塑形为多边形
points = [(int(x * image.shape[1]), int(y * image.shape[0])) for x, y in
zip(coordinates[::2], coordinates[1::2])]
# 在遮罩上使用多边形填充纯白色
cv2.fillPoly(mask, [np.array(points)], (255, 255, 255))
# 将遮罩应用到背景上
fg = cv2.bitwise_and(image, mask)
bg = cv2.bitwise_and(background, cv2.bitwise_not(mask))
result = cv2.add(fg, bg)
return result
def main():
"""
将 YOLO 语义分割的 txt 标注文件还原到原图中,并将目标区域保存到background.jpg文件作为画布上
"""
# 读取源图像
image = cv2.imread("D:\\Desktop\\gasdata\\02images_remove_color\\0002.jpg")
# 读取背景图像
background = cv2.imread("D:\Desktop\yolov8\yolov8-main-low-color\\background.jpg")
# 读取 txt 标注文件
txt_file = "D:\\Desktop\\gasdata\\04txt\\0002.txt"
labels = read_txt_labels(txt_file)
# 在背景上绘制分割区域
result_image = draw_labels_on_background(image, labels, background)
# 保存图片
cv2.imwrite('D:\\Desktop\\0002_on_background.jpg', result_image)
# 显示图片
cv2.imshow("Image with Background", result_image)
cv2.waitKey(0)
cv2.destroyAllWindows() # 添加这行代码以确保所有窗口都会关闭
if __name__ == "__main__":
main()
提取方式三:背景为指定图片,对文件夹中所有图片进行提取
python
import cv2
import numpy as np
import os
def read_txt_labels(txt_file):
"""
从 txt 标注文件中读取标签
:param txt_file: txt 标注文件路径
:return: 标签列表
"""
with open(txt_file, "r") as f:
labels = []
for line in f.readlines():
label_data = line.strip().split(" ")
class_id = int(label_data[0])
# 解析边界框坐标
coordinates = [float(x) for x in label_data[1:]]
labels.append([class_id, coordinates])
return labels
def draw_labels_on_background(image, labels, background):
"""
在背景图像上绘制分割区域
:param image: 源图像
:param labels: 标签列表
:param background: 背景图像
"""
mask = np.zeros_like(image, dtype=np.uint8) # 创建一个与源图像相同大小的遮罩
for label in labels:
class_id, coordinates = label
# 将坐标转换为整数并重新塑形为多边形
points = [(int(x * image.shape[1]), int(y * image.shape[0])) for x, y in
zip(coordinates[::2], coordinates[1::2])]
# 在遮罩上使用多边形填充纯白色
cv2.fillPoly(mask, [np.array(points)], (255, 255, 255))
# 将遮罩应用到背景上
fg = cv2.bitwise_and(image, mask)
bg = cv2.bitwise_and(background, cv2.bitwise_not(mask))
result = cv2.add(fg, bg)
return result
def process_image(image_path, txt_path, background_path, save_path):
# 读取源图像
image = cv2.imread(image_path)
# 读取背景图像
background = cv2.imread(background_path)
# 确保背景图片与源图片大小相同
background = cv2.resize(background, (image.shape[1], image.shape[0]))
# 读取 txt 标注文件
labels = read_txt_labels(txt_path)
# 在背景上绘制分割区域
result_image = draw_labels_on_background(image, labels, background)
# 保存图片
cv2.imwrite(save_path, result_image)
def main():
# 源图像文件夹路径
images_folder = "D:\Desktop\\test0316_30pics\\"
# 标签文件夹路径
labels_folder = "D:\\Desktop\\gasdata\\04txt\\"
# 背景图像路径
background_path = "D:\\Desktop\\yolov8\\yolov8-main-low-color\\background.jpg"
# 保存结果图像的文件夹路径
save_folder = "D:\\Desktop\\processed_images\\"
# 确保保存文件夹存在
if not os.path.exists(save_folder):
os.makedirs(save_folder)
# 获取源图像文件夹中的所有文件名
images = os.listdir(images_folder)
for image_name in images:
if image_name.lower().endswith(('.png', '.jpg', '.jpeg')):
# 构造完整的文件路径
image_path = os.path.join(images_folder, image_name)
txt_path = os.path.join(labels_folder, os.path.splitext(image_name)[0] + '.txt')
save_path = os.path.join(save_folder, 'processed_' + image_name)
# 处理图像
process_image(image_path, txt_path, background_path, save_path)
print(f"Processed {image_name}")
if __name__ == "__main__":
main()