c++ - 如何提供从一个图像构建的前景和背景模型到其他图像以执行 Grabcut?

标签 c++ opencv

我正在使用调用函数 grabcut() 的 opencv 的 grabcut.cpp 和 graphcut.cpp 代码。我必须找到一种方法来保存从某个图像计算出的背景和前景模型并将其应用于另一个图像。如何保存“bgdmodel”和“fgdmodel”以备将来使用?

这是我写的代码-

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>

using namespace std;
using namespace cv;

int main()
{

    // Load an image
    Mat img = imread("1.png",1);
    const Mat* img_0;
    img_0= &img;
    // Create the mask
    Mat mask;
    mask.create( img_0->size(), CV_8UC1);
    mask.setTo( GC_BGD );



    Mat bgdModel, fgdModel;
    Rect rect;
    rect.x=0;
    rect.y=0;
    rect.width=img.cols-1;
    rect.height=img.rows-1;
    (mask(rect)).setTo( Scalar(GC_BGD) );
    grabCut(img, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_RECT);


    // Save model to file

        FileStorage fs("mymodels.xml", FileStorage::WRITE);
        fs << "BgdModel" << bgdModel;
        fs << "FgdModel" << fgdModel;
        fs.release();



    // Load another image
    Mat img1 = imread( "abc.png", 1);
    const Mat* img_1;
    img_1= &img1;
    // Load models from file
    Mat bgdModel1, fgdModel1;
    Mat mask1;


        FileStorage fs1("mymodels.xml", FileStorage::READ);

        fs1["BgdModel"] >> bgdModel1;

        fs1["FgdModel"] >> fgdModel1;

        fs1.release();
    // Create a mask
    mask1.create( img_1->size(), CV_8UC1);
    mask1.setTo( GC_PR_FGD );
    Rect rect1;
    rect1.x=0;
    rect1.y=0;
    rect1.width=0;//img.cols;
    rect1.height=0;//img.rows;
    (mask1(rect1)).setTo( Scalar(GC_BGD) );


    grabCut(img1, mask1, rect1, bgdModel1, fgdModel1, 1, GC_EVAL);




   FileStorage fs2("finalmask.xml", FileStorage::WRITE);

        fs2 << "Final_MASK" << mask1;

        fs2.release();

     for (int i=0;i<img1.rows;i++)
     {
        for(int j=0;j<img1.cols;j++)
        {
            if(mask1.at<uchar>(i,j)==0||mask1.at<uchar>(i,j)==2)
            {
                img1.at<cv::Vec3b>(i,j)[0] = 0;
                img1.at<cv::Vec3b>(i,j)[1] = 0;
                img1.at<cv::Vec3b>(i,j)[2] = 0;
            }

        }
     }   


    imshow("Result of Grabcut", img1);
   waitKey(0);


return 0;
}

我需要确保为 *image 学习的 bgdModel 和 fgdModel 也适用于 image1。

最佳答案

您可以使用 FileStorage 保存背景和前景模型 Mat,然后将它们加载回去以用于下一张图像。

这个例子应该阐明这一点:

#include <opencv2\opencv.hpp>
using namespace cv;

int main()
{
    {
        // Load an image
        Mat3b img = imread("path_to_image");

        // Create the mask
        Mat1b mask(img.rows, img.cols, uchar(GC_PR_BGD));
        circle(mask, Point(img.cols / 2, img.rows / 2), 20, Scalar(GC_FGD), -1);

        Mat bgdModel, fgdModel;
        grabCut(img, mask, Rect(), bgdModel, fgdModel, 1);

        imshow("Mask", mask);
        waitKey(1);

        // Save model to file
        {
            FileStorage fs("mymodels.yml", FileStorage::WRITE);
            fs << "BgdModel" << bgdModel;
            fs << "FgdModel" << fgdModel;
        }
    }

    {
        // Load another image
        Mat3b img = imread("path_to_another_image");

        // Load models from file
        Mat bgdModel, fgdModel;

        {
            FileStorage fs("mymodels.yml", FileStorage::READ);
            fs["BgdModel"] >> bgdModel;
            fs["FgdModel"] >> fgdModel;
        }

        // Create a mask
        Mat1b mask(img.rows, img.cols, uchar(GC_PR_BGD));
        circle(mask, Point(img.cols / 2, img.rows / 2), 20, Scalar(GC_FGD), -1);

        grabCut(img, mask, Rect(), bgdModel, fgdModel, 1);

        imshow("Other Mask", mask);
        waitKey(1);

    }
    return 0;
}

关于c++ - 如何提供从一个图像构建的前景和背景模型到其他图像以执行 Grabcut?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32766885/

相关文章:

python - Opencv - python - 将线段检测器(LSD)中的线段连接起来形成一条线

python - VideoCapture()读取多个视频和帧分辨率问题

c++ - 创建大小为 int arr[1000000][1000000] 的大型二维数组

c++ - Libpurple 无法连接 - Purple_presence_is_online 失败

c++ - OpenCV 视频稳定

linux - openCV 中缺少 libcxcore.so.2

python - 在 openCV 中使用单应性将 PNG 粘贴到图像上

c++ - 向调用线程发出信号,表明资源已在使用中

c++ - "vector of objects"与 "vector of Object pointers"的大小

C++:将指针变量传递给函数