GrabCut算法实现图像分割的一个案例

1.算法的基本原理

1.初始化:首先,用户需要手动指定一个包含前景的矩形框,作为算法的初始估计。然后,通过K均值聚类算法将图像中的像素分成前景和背景两类。
2.建立高斯混合模型:使用高斯混合模型来估计前景和背景的颜色分布。该模型包含若干个高斯成分,每个成分代表一个颜色分布。通过最大似然估计来确定混合模型的参数。
3.计算像素属于前景或背景的概率:根据高斯混合模型,计算每个像素属于前景或背景的概率。这可以通过贝叶斯定理来计算,其中像素的颜色作为观测值,混合模型的参数作为先验概率。
4.更新分割结果:根据像素属于前景或背景的概率,更新图像的分割结果。具体来说,根据概率将像素标记为前景或背景,并将不确定的像素标记为可能的前景或背景。
5.迭代更新:重复执行步骤3和步骤4,直到分割结果收敛或达到最大迭代次数。
2.结果演示(还是用一下孟姐的网图哈哈)

3.代码

#include <iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
    Mat img = imread("d:\\Images\\mengjie4.jpg", cv::IMREAD_UNCHANGED);
    if (img.empty())
    {
        printf("图像无法正常加载\n");
        return 0;
    }
    // 定义包含人物的矩形区域
    Rect rect(309, 66, 567, 514); // x, y, width, height
    cv::rectangle(img, rect, Scalar(0, 255, 0), 2);

    // 初始化掩码和模型
    Mat mask, bgModel, fgModel;
    mask.create(img.size(), CV_8UC1);
    mask.setTo(Scalar::all(GC_BGD)); // 初始设为背景
    (mask(rect)).setTo(Scalar(GC_PR_FGD)); // 矩形区域设为可能的前景

    // 应用 GrabCut 算法
    grabCut(img, mask, rect, bgModel, fgModel, 5, GC_INIT_WITH_RECT);

    // 提取前景区域(可能前景 + 确定前景)
    Mat foregroundMask = (mask == GC_PR_FGD) | (mask == GC_FGD);
    Mat result(img.size(), CV_8UC3, Scalar(255, 255, 255));
    img.copyTo(result, foregroundMask);
    
    namedWindow("original", WINDOW_FREERATIO);
    int window_width = 400;
    resizeWindow("original", Size(window_width, window_width * result.rows / result.cols));
    imshow("original", img);

    namedWindow("result", WINDOW_FREERATIO);
    resizeWindow("result", Size(window_width, window_width * result.rows / result.cols));
    imshow("result", result);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

 

posted @ 2025-07-10 14:35  Wind_Swing_Dunn  阅读(16)  评论(0)    收藏  举报