You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Mask RCNN从轮廓与掩码中提取无背景目标图像咨询

需求说明

我使用Mask RCNN完成图像分类,得到了分类结果图及对应的掩码,当前输出结果如下:
结果图

我希望提取轮廓周边的目标区域,得到去除背景的单独图像,当前使用的实现代码如下:

//Display the label at the top of the bounding box
int baseLine;
Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
box.y = max(box.y, labelSize.height);
//rectangle(frame, Point(box.x, box.y - round(1.5 * labelSize.height)), Point(box.x + round(1.5 * labelSize.width), box.y + baseLine), Scalar(255, 255, 255), FILLED);
//putText(frame, label, Point(box.x, box.y), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 0), 1);

// Resize the mask, threshold, color and apply it on the image
Scalar color = colors[classId % colors.size()];

// Resize the mask, threshold, color and apply it on the image
resize(objectMask, objectMask, Size(box.width, box.height));
Mat mask = (objectMask > maskThreshold);
Mat coloredRoi = (0.3 * color + 0.7 * frame(box));
coloredRoi.convertTo(coloredRoi, CV_8UC3);

// Draw the contours on the image
vector<Mat> contours;
Mat hierarchy;
mask.convertTo(mask, CV_8U);
findContours(mask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
drawContours(coloredRoi, contours, -1, color, 5, LINE_8, hierarchy, 100);
coloredRoi.copyTo(frame(box), mask);

imshow("img", coloredRoi);
cv::waitKey(0);

单独的掩码可视化图如下:
掩码图

原始输入图像如下:
原始图

请问如何调整代码,可实现提取无背景目标区域图像的需求?


解决方案

原有代码的逻辑是给目标区域叠加半透明颜色、绘制轮廓后回写到原图,没有做背景剔除,按以下方式修改即可得到无背景的目标单独图像,可根据需求选择生成纯色背景或者透明背景的结果:

方案1:生成纯色背景的目标图像

直接将掩码外的区域像素赋值为指定纯色即可,修改代码如下:

resize(objectMask, objectMask, Size(box.width, box.height));
Mat mask = (objectMask > maskThreshold);
mask.convertTo(mask, CV_8U); // 掩码转为8位单通道图,目标区域值为255,背景为0

// 取原图对应 bounding box 的区域
Mat roi = frame(box).clone();
// 遍历每个像素,非目标区域设为黑色,修改为Vec3b(255,255,255)就是白色背景
for (int i = 0; i < roi.rows; i++) {
    for (int j = 0; j < roi.cols; j++) {
        if (mask.at<uchar>(i,j) == 0) {
            roi.at<Vec3b>(i,j) = Vec3b(0,0,0);
        }
    }
}

// 可选:绘制目标轮廓
vector<Mat> contours;
Mat hierarchy;
findContours(mask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
drawContours(roi, contours, -1, Scalar(0,255,0), 2, LINE_8, hierarchy, 100);

// 显示和保存结果
imshow("无背景目标图", roi);
imwrite("output.jpg", roi);
waitKey(0);

方案2:生成带透明通道的PNG图像

如果需要背景透明的效果,给图像新增alpha通道控制透明度即可,代码如下:

resize(objectMask, objectMask, Size(box.width, box.height));
Mat mask = (objectMask > maskThreshold);
mask.convertTo(mask, CV_8U);

Mat roi = frame(box).clone();
// 创建四通道图像(BGR+Alpha)
Mat result(roi.size(), CV_8UC4);
for (int i = 0; i < roi.rows; i++) {
    for (int j = 0; j < roi.cols; j++) {
        Vec3b bgr = roi.at<Vec3b>(i,j);
        result.at<Vec4b>(i,j) = Vec4b(bgr[0], bgr[1], bgr[2], mask.at<uchar>(i,j));
    }
}

// 保存为PNG格式才能保留透明通道
imwrite("output_transparent.png", result);

内容的提问来源于stack exchange,提问作者Andre Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:24:03