为了扣出一张图上的多个目标,代码不会写,怎么办?
这是原图
话不多说,直接上代码,里面注释很全。
from ultralytics import YOLO # 导入YOLO模型类
from matplotlib import pyplot as plt
import numpy as np
import cv2 # 导入OpenCV库
# 加载预训练的模型
model = YOLO('best_fenge.pt')
# 读取图片并调整其大小以匹配模型训练时的输入尺寸
orig_img = cv2.imread('mushroom144.jpg') # 使用cv2读取图片
# 这里特别注意,因为使用yolov8训练的时候默认会把图片resize成448*640的尺寸,所以这里也得改成你训练的尺寸
orig_img_resized = cv2.resize(orig_img, (640, 448)) # 调整图片大小
# 使用模型对调整后的图片进行推理
results = model(orig_img_resized, save=True)
# 初始化一个布尔数组掩码,用于合并所有检测到的物体掩码
combined_mask = np.zeros(orig_img_resized.shape[:2], dtype=np.bool_)
# 遍历检测到的所有掩码
for mask in results[0].masks.data:
mask_bool = mask.cpu().numpy().astype(np.bool_) # 将掩码转换为布尔数组
combined_mask |= mask_bool # 使用逻辑或操作合并掩码
# 使用合并后的掩码创建抠图
masked_image = np.zeros_like(orig_img_resized) # 初始化一个全黑的图片数组
masked_image[combined_mask] = orig_img_resized[combined_mask] # 应用掩码
# 创建一个带有透明背景的RGBA图像
alpha_channel = np.ones(combined_mask.shape, dtype=orig_img.dtype) * 255 # 创建全白的alpha通道
masked_image_rgba = np.dstack((masked_image, alpha_channel)) # 将RGB图像和alpha通道合并
masked_image_rgba[~combined_mask] = (0, 0, 0, 0) # 设置背景为透明
# 保存两种处理后的图像
cv2.imwrite('masked_image_all_objects.jpg', masked_image) # 保存带黑色背景的图像
cv2.imwrite('masked_image_all_objects.png', masked_image_rgba) # 保存带透明背景的图像
# 显示第一张处理后的图像
masked_image = cv2.resize(masked_image, (1200, 950)) # 调整图像大小
cv2.imshow("YOLOv8 Inference", masked_image) # 显示图像
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有OpenCV窗口
其中替换自己的模型和自己的图片就不用说了,我的模型和图片直接在我的工程中,可以直接调用,如果在其他位置,可以用绝对路径的形式。那结果就出来了。这张是黑色的背景图,背景颜色是可以改的。
这张是扣除背景的图,实现效果均在代码中体现了。
改背景的代码我写在这里,注意看,自定义背景色,上代码。
from ultralytics import YOLO # 导入YOLO模型类
import numpy as np
import cv2 # 导入OpenCV库
# 加载预训练的模型
model = YOLO('best_fenge.pt')
# 读取图片并调整其大小以匹配模型训练时的输入尺寸
orig_img = cv2.imread('mushroom144.jpg') # 使用cv2读取图片
# 这里特别注意,因为使用yolov8训练的时候默认会把图片resize成448*640的尺寸,所以这里也得改成你训练的尺寸
orig_img_resized = cv2.resize(orig_img, (640, 448)) # 调整图片大小
# 使用模型对调整后的图片进行推理
results = model(orig_img_resized, save=True)
# 初始化一个布尔数组掩码,用于合并所有检测到的物体掩码
combined_mask = np.zeros(orig_img_resized.shape[:2], dtype=np.bool_)
# 遍历检测到的所有掩码
for mask in results[0].masks.data:
mask_bool = mask.cpu().numpy().astype(np.bool_) # 将掩码转换为布尔数组
combined_mask |= mask_bool # 使用逻辑或操作合并掩码
# 定义自定义背景颜色,例如浅蓝色 (B, G, R)
background_color = (255, 210, 160)
# 创建一个和原始调整后图像相同大小,且为自定义背景颜色的背景图像
background_image = np.full_like(orig_img_resized, background_color, dtype=np.uint8)
# 使用合并后的掩码创建带有自定义背景颜色的图像
custom_bg_image = np.where(combined_mask[:,:,None], orig_img_resized, background_image)
# 创建一个带有透明背景的RGBA图像
alpha_channel = np.ones(combined_mask.shape, dtype=orig_img.dtype) * 255 # 创建全白的alpha通道
masked_image_rgba = np.dstack((custom_bg_image, alpha_channel)) # 将RGB图像和alpha通道合并
masked_image_rgba[~combined_mask] = (0, 0, 0, 0) # 设置背景为透明
# 保存带有自定义背景颜色的图像
cv2.imwrite('masked_image_custom_background.jpg', custom_bg_image)
# 保存带有透明背景的图像为PNG,以保持透明度信息
cv2.imwrite('masked_image_transparent_background.png', masked_image_rgba)
# 显示带有自定义背景颜色的图像
custom_bg_image_resized = cv2.resize(custom_bg_image, (1200, 950)) # 调整图像大小以便显示
cv2.imshow("YOLOv8 Inference with Custom Background", custom_bg_image_resized)
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有OpenCV窗口
效果如下。
有的同学就问了,单目标怎么做?话不多说,上代码。单目标代码来源于这篇文章。https://blog.csdn.net/qq_42452134/article/details/136272606
from ultralytics import YOLO
from matplotlib import pyplot as plt
import numpy as np
import cv2
# 加载sam模型,如果没有这个框架也会自动的为你下载
model = YOLO('best_fenge.pt')
# 读取一张图片,
orig_img = cv2.imread('mushroom144.jpg')
# 这里特别注意,因为使用yolov8训练的时候默认会把图片resize成448*640的尺寸,所以这里也得改成你训练的尺寸
orig_img = cv2.resize(orig_img, (640, 448)) # 注意OpenCV中尺寸是先宽度后高度
# 使用模型进行推理, 后面save=True的参数可以输出测试分割的图片
results = model(orig_img, save=True)
# 这里是我获取mask编码部分的。
mask = results[0].masks.data[0].cpu().numpy().astype(np.bool_)
# 应用掩码到原始图像
# 如果你想要背景是黑色的
masked_image = np.zeros_like(orig_img)
masked_image[mask] = orig_img[mask]
# 如果你想要背景透明(假设原始图像是RGB格式)
# 创建一个RGBA图像,其中背景是透明的
alpha_channel = np.ones(mask.shape, dtype=orig_img.dtype) * 255 # 创建alpha通道
masked_image_rgba = np.dstack((masked_image, alpha_channel)) # 将alpha通道添加到RGB通道
masked_image_rgba[~mask] = (0, 0, 0, 0) # 将非掩码区域设置为透明
# 保存图片,黑色背景
cv2.imwrite('masked_image_test.jpg', masked_image)
# 如果背景是透明的
cv2.imwrite('masked_image_test.png', masked_image_rgba)
效果如下,我的图像是多目标,所以只保留了第一个检测到的物体。
同学们,你们该不会需要修改单目标的背景色吧?