Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

How far is grabCut deterministic?

Hello everyone,

When running grabCut on an the same input in the loop every time I will get the different output, but if I restart the program, the output, even though different within the loop, will match the result of corresponding iteration from the previous run. I know, that grabCut will use some singletons so that the instance will be there through all the runs until the program will be terminated, but still, why do the separate runs of the algorithm interfere with each other (somehow) and what to do to get around that? I would need some level of determinism when the algorithm is running. Should I then restart the program after every single run? Does not make much sense...

I checked it with the unit test. If on one run I will save the results to disk like this:

TEST(PreprocessingTests, CutAndFilterSave)
{
    auto original_path = std::experimental::filesystem::current_path();
    std::experimental::filesystem::current_path("../tests/data/");

    std::string output_directory = "cutAndFilterPreviousRun";
    std::experimental::filesystem::create_directory(output_directory);

    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> images_to_save;
    images_to_save.emplace_back(hidden_mouth_image);
    images_to_save.emplace_back(whole_face_image);

    processImagesForComparison(images_to_save);

    cv::imwrite(output_directory + "/hidden_mouth_filtered.png", images_to_save.at(0));
    cv::imwrite(output_directory + "/whole_face_filtered.png", images_to_save.at(1));

    std::experimental::filesystem::current_path(original_path);
}

And on second run I will run this function

TEST(PreprocessingTests, CutAndFilterRead)
{
    auto original_path = std::experimental::filesystem::current_path();
    std::experimental::filesystem::current_path("../tests/data/");

    std::string output_directory = "cutAndFilterPreviousRun";
    if (std::experimental::filesystem::exists(output_directory))
    {
        cv::Mat hidden_mouth_image_filtered = cv::imread(output_directory + "/hidden_mouth_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image_filtered.data);
        cv::Mat whole_face_image_filtered = cv::imread(output_directory + "/whole_face_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image_filtered.data);

        std::vector<cv::Mat> previous_run_filtered_images;
        previous_run_filtered_images.emplace_back(hidden_mouth_image_filtered);
        previous_run_filtered_images.emplace_back(whole_face_image_filtered);

        cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image.data);
        cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image.data);

        std::vector<cv::Mat> test_images;
        test_images.emplace_back(hidden_mouth_image);
        test_images.emplace_back(whole_face_image);

        processImagesForComparison(test_images);
        EXPECT_TRUE(areTheSame(test_images, previous_run_filtered_images));
    }
    std::experimental::filesystem::current_path(original_path);
}

The "areTheSame" will return true. But if I run it in the loop:

TEST(PreprocessingTests, CutAndFilterTest)
{
    auto original_path = std::experimental::filesystem::current_path();
    std::experimental::filesystem::current_path("../tests/data/");

    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> original_images;
    for (int i=0; i < 1; i++)
    {
        original_images.emplace_back(hidden_mouth_image);
        original_images.emplace_back(whole_face_image);
    }

    auto copied_original_images = cloneMatVector(original_images);

    std::vector<cv::Mat> previous_filtered_images;
    for (int run = 0; run < 2; run++)
    {
        std::vector<cv::Mat> run_images = cloneMatVector(original_images);
        processImagesForComparison(run_images);

        if (!previous_filtered_images.empty())
            EXPECT_TRUE(areTheSame(run_images, previous_filtered_images));

        previous_filtered_images = cloneMatVector(run_images);    
    }
    EXPECT_TRUE(areTheSame(original_images, copied_original_images));

    std::experimental::filesystem::current_path(original_path);
}

then "areTheSame" will fail... In processImagesForComparison only my grabCut implementation will be run on each element:

cv::Mat grabCutSegmentation(const cv::Mat& input)
{
    cv::Mat bgModel, fgModel;
    cv::Mat mask(input.rows, input.cols, CV_8U);
// let's set all of them to possible background first
    mask.setTo(cv::GC_PR_BGD);

// cut out a small area in the middle of the image
    int m_rows = 0.75 * input.rows;
    int m_cols = 0.6 * input.cols;
// the region of interest
    cv::Mat fg_seed = mask(cv::Range(input.rows/2 - m_rows/2, input.rows/2 + m_rows/2),
                           cv::Range(input.cols/2 - m_cols/2, input.cols/2 + m_cols/2));
// mark it as foreground
    fg_seed.setTo(cv::GC_FGD);

// select last 3 rows of the image as background
    cv::Mat1b bg_seed = mask(cv::Range(mask.rows-2, mask.rows),cv::Range::all());
    bg_seed.setTo(cv::GC_BGD);

    cv::Mat colour_input;
    cv::cvtColor(input , colour_input , CV_GRAY2RGB);

    cv::grabCut(colour_input, mask, cv::Rect(), bgModel, fgModel, 1, cv::GC_INIT_WITH_MASK);
    // let's get all foreground and possible foreground pixels
    cv::Mat mask_fgpf = ( mask == cv::GC_FGD) | ( mask == cv::GC_PR_FGD);
// and copy all the foreground-pixels to a temporary image
    cv::Mat output = cv::Mat::zeros(input.rows, input.cols, CV_8U);
    input.copyTo(output, mask_fgpf);

    return output;
}

What could be done regarding this? On which level may this problem emerge?

How far is grabCut deterministic?

Hello everyone,

When running grabCut on an the same input in the loop every time I will get the different output, but if I restart the program, the output, even though different within the loop, will match the result of corresponding iteration from the previous run. I know, that grabCut will use some singletons so that the instance will be there through all the runs until the program will be terminated, but still, why do the separate runs of the algorithm interfere with each other (somehow) and what to do to get around that? I would need some level of determinism when the algorithm is running. Should I then restart the program after every single run? Does not make much sense...

I checked it with the unit test. If on one run I will save the results to disk like this:

TEST(PreprocessingTests, CutAndFilterSave)
{
    auto original_path = std::experimental::filesystem::current_path();
    std::experimental::filesystem::current_path("../tests/data/");
{  
    std::string output_directory = "cutAndFilterPreviousRun";
    std::experimental::filesystem::create_directory(output_directory);

    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> images_to_save;
    images_to_save.emplace_back(hidden_mouth_image);
    images_to_save.emplace_back(whole_face_image);

    processImagesForComparison(images_to_save);

    cv::imwrite(output_directory + "/hidden_mouth_filtered.png", images_to_save.at(0));
    cv::imwrite(output_directory + "/whole_face_filtered.png", images_to_save.at(1));

    std::experimental::filesystem::current_path(original_path);
}

And on second run I will run this function

TEST(PreprocessingTests, CutAndFilterRead)
{
    auto original_path = std::experimental::filesystem::current_path();
    std::experimental::filesystem::current_path("../tests/data/");

    std::string output_directory = "cutAndFilterPreviousRun";
    if (std::experimental::filesystem::exists(output_directory))
    {
        cv::Mat hidden_mouth_image_filtered = cv::imread(output_directory + "/hidden_mouth_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image_filtered.data);
        cv::Mat whole_face_image_filtered = cv::imread(output_directory + "/whole_face_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image_filtered.data);

        std::vector<cv::Mat> previous_run_filtered_images;
        previous_run_filtered_images.emplace_back(hidden_mouth_image_filtered);
        previous_run_filtered_images.emplace_back(whole_face_image_filtered);

        cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image.data);
        cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image.data);

        std::vector<cv::Mat> test_images;
        test_images.emplace_back(hidden_mouth_image);
        test_images.emplace_back(whole_face_image);

        processImagesForComparison(test_images);
        EXPECT_TRUE(areTheSame(test_images, previous_run_filtered_images));
    }
    std::experimental::filesystem::current_path(original_path);
}

The "areTheSame" will return true. But if I run it in the loop:

TEST(PreprocessingTests, CutAndFilterTest)
{
    auto original_path = std::experimental::filesystem::current_path();
    std::experimental::filesystem::current_path("../tests/data/");
{ 
    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> original_images;
    for (int i=0; i < 1; i++)
    {
        original_images.emplace_back(hidden_mouth_image);
        original_images.emplace_back(whole_face_image);
    }

    auto copied_original_images = cloneMatVector(original_images);

    std::vector<cv::Mat> previous_filtered_images;
    for (int run = 0; run < 2; run++)
    {
        std::vector<cv::Mat> run_images = cloneMatVector(original_images);
        processImagesForComparison(run_images);

        if (!previous_filtered_images.empty())
            EXPECT_TRUE(areTheSame(run_images, previous_filtered_images));

        previous_filtered_images = cloneMatVector(run_images);    
    }
    EXPECT_TRUE(areTheSame(original_images, copied_original_images));

    std::experimental::filesystem::current_path(original_path);
}

then "areTheSame" will fail... In processImagesForComparison only my grabCut implementation will be run on each element:

cv::Mat grabCutSegmentation(const cv::Mat& input)
{
    cv::Mat bgModel, fgModel;
    cv::Mat mask(input.rows, input.cols, CV_8U);
// let's set all of them to possible background first
    mask.setTo(cv::GC_PR_BGD);

// cut out a small area in the middle of the image
    int m_rows = 0.75 * input.rows;
    int m_cols = 0.6 * input.cols;
// the region of interest
    cv::Mat fg_seed = mask(cv::Range(input.rows/2 - m_rows/2, input.rows/2 + m_rows/2),
                           cv::Range(input.cols/2 - m_cols/2, input.cols/2 + m_cols/2));
// mark it as foreground
    fg_seed.setTo(cv::GC_FGD);

// select last 3 rows of the image as background
    cv::Mat1b bg_seed = mask(cv::Range(mask.rows-2, mask.rows),cv::Range::all());
    bg_seed.setTo(cv::GC_BGD);

    cv::Mat colour_input;
    cv::cvtColor(input , colour_input , CV_GRAY2RGB);

    cv::grabCut(colour_input, mask, cv::Rect(), bgModel, fgModel, 1, cv::GC_INIT_WITH_MASK);
    // let's get all foreground and possible foreground pixels
    cv::Mat mask_fgpf = ( mask == cv::GC_FGD) | ( mask == cv::GC_PR_FGD);
// and copy all the foreground-pixels to a temporary image
    cv::Mat output = cv::Mat::zeros(input.rows, input.cols, CV_8U);
    input.copyTo(output, mask_fgpf);

    return output;
}

What could be done regarding this? On which level may this problem emerge?

How far is grabCut deterministic?

Hello everyone,

When running grabCut on an the same input in the loop every time I will get the different output, but if I restart the program, the output, even though different within the loop, will match the result of corresponding iteration from the previous run. I know, that grabCut will use some singletons so that the instance will be there through all the runs until the program will be terminated, but still, why do the separate runs of the algorithm interfere with each other (somehow) and what to do to get around that? I would need some level of determinism when the algorithm is running. Should I then restart the program after every single run? Does not make much sense...that?

I checked it with the unit test. If on one run I will save the results to disk like this:

TEST(PreprocessingTests, CutAndFilterSave)
{  
    std::string output_directory = "cutAndFilterPreviousRun";
    std::experimental::filesystem::create_directory(output_directory);

    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> images_to_save;
    images_to_save.emplace_back(hidden_mouth_image);
    images_to_save.emplace_back(whole_face_image);

    processImagesForComparison(images_to_save);

    cv::imwrite(output_directory + "/hidden_mouth_filtered.png", images_to_save.at(0));
    cv::imwrite(output_directory + "/whole_face_filtered.png", images_to_save.at(1));
}

And on second run I will run this function

TEST(PreprocessingTests, CutAndFilterRead)
{
    std::string output_directory = "cutAndFilterPreviousRun";
    if (std::experimental::filesystem::exists(output_directory))
    {
        cv::Mat hidden_mouth_image_filtered = cv::imread(output_directory + "/hidden_mouth_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image_filtered.data);
        cv::Mat whole_face_image_filtered = cv::imread(output_directory + "/whole_face_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image_filtered.data);

        std::vector<cv::Mat> previous_run_filtered_images;
        previous_run_filtered_images.emplace_back(hidden_mouth_image_filtered);
        previous_run_filtered_images.emplace_back(whole_face_image_filtered);

        cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image.data);
        cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image.data);

        std::vector<cv::Mat> test_images;
        test_images.emplace_back(hidden_mouth_image);
        test_images.emplace_back(whole_face_image);

        processImagesForComparison(test_images);
        EXPECT_TRUE(areTheSame(test_images, previous_run_filtered_images));
    }
}

The "areTheSame" will return true. But if I run it in the loop:

TEST(PreprocessingTests, CutAndFilterTest)
{ 
    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> original_images;
    for (int i=0; i < 1; i++)
    {
        original_images.emplace_back(hidden_mouth_image);
        original_images.emplace_back(whole_face_image);
    }

    auto copied_original_images = cloneMatVector(original_images);

    std::vector<cv::Mat> previous_filtered_images;
    for (int run = 0; run < 2; run++)
    {
        std::vector<cv::Mat> run_images = cloneMatVector(original_images);
        processImagesForComparison(run_images);

        if (!previous_filtered_images.empty())
            EXPECT_TRUE(areTheSame(run_images, previous_filtered_images));

        previous_filtered_images = cloneMatVector(run_images);    
    }
    EXPECT_TRUE(areTheSame(original_images, copied_original_images));
}

then "areTheSame" will fail... In processImagesForComparison only my grabCut implementation will be run on each element:

cv::Mat grabCutSegmentation(const cv::Mat& input)
{
    cv::Mat bgModel, fgModel;
    cv::Mat mask(input.rows, input.cols, CV_8U);
// let's set all of them to possible background first
    mask.setTo(cv::GC_PR_BGD);

// cut out a small area in the middle of the image
    int m_rows = 0.75 * input.rows;
    int m_cols = 0.6 * input.cols;
// the region of interest
    cv::Mat fg_seed = mask(cv::Range(input.rows/2 - m_rows/2, input.rows/2 + m_rows/2),
                           cv::Range(input.cols/2 - m_cols/2, input.cols/2 + m_cols/2));
// mark it as foreground
    fg_seed.setTo(cv::GC_FGD);

// select last 3 rows of the image as background
    cv::Mat1b bg_seed = mask(cv::Range(mask.rows-2, mask.rows),cv::Range::all());
    bg_seed.setTo(cv::GC_BGD);

    cv::Mat colour_input;
    cv::cvtColor(input , colour_input , CV_GRAY2RGB);

    cv::grabCut(colour_input, mask, cv::Rect(), bgModel, fgModel, 1, cv::GC_INIT_WITH_MASK);
    // let's get all foreground and possible foreground pixels
    cv::Mat mask_fgpf = ( mask == cv::GC_FGD) | ( mask == cv::GC_PR_FGD);
// and copy all the foreground-pixels to a temporary image
    cv::Mat output = cv::Mat::zeros(input.rows, input.cols, CV_8U);
    input.copyTo(output, mask_fgpf);

    return output;
}

What could be done regarding this? On which level may this problem emerge?

How far is grabCut deterministic?

Hello everyone,

When running grabCut on an the same input in the loop every time I will get the different output, but if I restart the program, the output, even though different within the loop, will match the result of corresponding iteration from the previous run. I know, that grabCut will use some singletons so that the instance will be there through all the runs until the program will be terminated, but still, why do the separate runs of the algorithm interfere with each other (somehow) and what to do to get around that?

I checked it with the unit test. If on one run I will save the results to disk like this:

TEST(PreprocessingTests, CutAndFilterSave)
{  
    std::string output_directory = "cutAndFilterPreviousRun";
    std::experimental::filesystem::create_directory(output_directory);

    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> images_to_save;
    images_to_save.emplace_back(hidden_mouth_image);
    images_to_save.emplace_back(whole_face_image);

    processImagesForComparison(images_to_save);

    cv::imwrite(output_directory + "/hidden_mouth_filtered.png", images_to_save.at(0));
    cv::imwrite(output_directory + "/whole_face_filtered.png", images_to_save.at(1));
}

And on second run I will run this function

TEST(PreprocessingTests, CutAndFilterRead)
{
    std::string output_directory = "cutAndFilterPreviousRun";
    if (std::experimental::filesystem::exists(output_directory))
    {
        cv::Mat hidden_mouth_image_filtered = cv::imread(output_directory + "/hidden_mouth_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image_filtered.data);
        cv::Mat whole_face_image_filtered = cv::imread(output_directory + "/whole_face_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image_filtered.data);

        std::vector<cv::Mat> previous_run_filtered_images;
        previous_run_filtered_images.emplace_back(hidden_mouth_image_filtered);
        previous_run_filtered_images.emplace_back(whole_face_image_filtered);

        cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image.data);
        cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image.data);

        std::vector<cv::Mat> test_images;
        test_images.emplace_back(hidden_mouth_image);
        test_images.emplace_back(whole_face_image);

        processImagesForComparison(test_images);
        EXPECT_TRUE(areTheSame(test_images, previous_run_filtered_images));
    }
}

The "areTheSame" will return true. But if I run it in the loop:

TEST(PreprocessingTests, CutAndFilterTest)
{ 
    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> original_images;
    for (int i=0; i < 1; i++)
    {
        original_images.emplace_back(hidden_mouth_image);
        original_images.emplace_back(whole_face_image);
    }

    auto copied_original_images = cloneMatVector(original_images);

    std::vector<cv::Mat> previous_filtered_images;
    for (int run = 0; run < 2; run++)
    {
        std::vector<cv::Mat> run_images = cloneMatVector(original_images);
        processImagesForComparison(run_images);

        if (!previous_filtered_images.empty())
            EXPECT_TRUE(areTheSame(run_images, previous_filtered_images));

        previous_filtered_images = cloneMatVector(run_images);    
    }
    EXPECT_TRUE(areTheSame(original_images, copied_original_images));
}

then "areTheSame" will fail... In processImagesForComparison only my grabCut implementation will be run on each element:

cv::Mat grabCutSegmentation(const cv::Mat& input)
{
    cv::Mat bgModel, fgModel;
    cv::Mat mask(input.rows, input.cols, CV_8U);
// let's set all of them to possible background first
    mask.setTo(cv::GC_PR_BGD);

// cut out a small area in the middle of the image
    int m_rows = 0.75 * input.rows;
    int m_cols = 0.6 * input.cols;
// the region of interest
    cv::Mat fg_seed = mask(cv::Range(input.rows/2 - m_rows/2, input.rows/2 + m_rows/2),
                           cv::Range(input.cols/2 - m_cols/2, input.cols/2 + m_cols/2));
// mark it as foreground
    fg_seed.setTo(cv::GC_FGD);

// select last 3 rows of the image as background
    cv::Mat1b bg_seed = mask(cv::Range(mask.rows-2, mask.rows),cv::Range::all());
    bg_seed.setTo(cv::GC_BGD);

    cv::Mat colour_input;
    cv::cvtColor(input , colour_input , CV_GRAY2RGB);

    cv::grabCut(colour_input, mask, cv::Rect(), bgModel, fgModel, 1, cv::GC_INIT_WITH_MASK);
    // let's get all foreground and possible foreground pixels
    cv::Mat mask_fgpf = ( mask == cv::GC_FGD) | ( mask == cv::GC_PR_FGD);
// and copy all the foreground-pixels to a temporary image
    cv::Mat output = cv::Mat::zeros(input.rows, input.cols, CV_8U);
    input.copyTo(output, mask_fgpf);

    return output;
}

What could be done regarding this? On which level may this problem emerge?

How far is Difference between output of grabCut deterministic?between runs

Hello everyone,

When running grabCut on an the same input in the loop every time I will get the different output, but if I restart the program, the output, even though different within the loop, will match the result of corresponding iteration from the previous run. I know, that grabCut will use some singletons so that the instance will be there through all the runs until the program will be terminated, but still, why do the separate runs of the algorithm interfere with each other (somehow) and what to do to get around that?

I checked it with the unit test. If on one run I will save the results to disk like this:

TEST(PreprocessingTests, CutAndFilterSave)
{  
    std::string output_directory = "cutAndFilterPreviousRun";
    std::experimental::filesystem::create_directory(output_directory);

    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> images_to_save;
    images_to_save.emplace_back(hidden_mouth_image);
    images_to_save.emplace_back(whole_face_image);

    processImagesForComparison(images_to_save);

    cv::imwrite(output_directory + "/hidden_mouth_filtered.png", images_to_save.at(0));
    cv::imwrite(output_directory + "/whole_face_filtered.png", images_to_save.at(1));
}

And on second run I will run this function

TEST(PreprocessingTests, CutAndFilterRead)
{
    std::string output_directory = "cutAndFilterPreviousRun";
    if (std::experimental::filesystem::exists(output_directory))
    {
        cv::Mat hidden_mouth_image_filtered = cv::imread(output_directory + "/hidden_mouth_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image_filtered.data);
        cv::Mat whole_face_image_filtered = cv::imread(output_directory + "/whole_face_filtered.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image_filtered.data);

        std::vector<cv::Mat> previous_run_filtered_images;
        previous_run_filtered_images.emplace_back(hidden_mouth_image_filtered);
        previous_run_filtered_images.emplace_back(whole_face_image_filtered);

        cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(hidden_mouth_image.data);
        cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
        EXPECT_TRUE(whole_face_image.data);

        std::vector<cv::Mat> test_images;
        test_images.emplace_back(hidden_mouth_image);
        test_images.emplace_back(whole_face_image);

        processImagesForComparison(test_images);
        EXPECT_TRUE(areTheSame(test_images, previous_run_filtered_images));
    }
}

The "areTheSame" Here areTheSame will return true. But if I run it in the loop:

TEST(PreprocessingTests, CutAndFilterTest)
{ 
    cv::Mat hidden_mouth_image = cv::imread("hidden_mouth.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(hidden_mouth_image.data);
    cv::Mat whole_face_image = cv::imread("whole_face.png", cv::IMREAD_GRAYSCALE);
    EXPECT_TRUE(whole_face_image.data);

    std::vector<cv::Mat> original_images;
    for (int i=0; i < 1; i++)
    {
        original_images.emplace_back(hidden_mouth_image);
        original_images.emplace_back(whole_face_image);
    }

    auto copied_original_images = cloneMatVector(original_images);

    std::vector<cv::Mat> previous_filtered_images;
    for (int run = 0; run < 2; run++)
    {
        std::vector<cv::Mat> run_images = cloneMatVector(original_images);
        processImagesForComparison(run_images);

        if (!previous_filtered_images.empty())
            EXPECT_TRUE(areTheSame(run_images, previous_filtered_images));

        previous_filtered_images = cloneMatVector(run_images);    
    }
    EXPECT_TRUE(areTheSame(original_images, copied_original_images));
}

then "areTheSame" areTheSame will fail... In processImagesForComparison only processImagesForComparison my grabCut implementation will be run on each vector element:

cv::Mat grabCutSegmentation(const cv::Mat& input)
{
    cv::Mat bgModel, fgModel;
    cv::Mat mask(input.rows, input.cols, CV_8U);
// let's set all of them to possible background first
    mask.setTo(cv::GC_PR_BGD);

// cut out a small area in the middle of the image
    int m_rows = 0.75 * input.rows;
    int m_cols = 0.6 * input.cols;
// the region of interest
    cv::Mat fg_seed = mask(cv::Range(input.rows/2 - m_rows/2, input.rows/2 + m_rows/2),
                           cv::Range(input.cols/2 - m_cols/2, input.cols/2 + m_cols/2));
// mark it as foreground
    fg_seed.setTo(cv::GC_FGD);

// select last 3 rows of the image as background
    cv::Mat1b bg_seed = mask(cv::Range(mask.rows-2, mask.rows),cv::Range::all());
    bg_seed.setTo(cv::GC_BGD);

    cv::Mat colour_input;
    cv::cvtColor(input , colour_input , CV_GRAY2RGB);

    cv::grabCut(colour_input, mask, cv::Rect(), bgModel, fgModel, 1, cv::GC_INIT_WITH_MASK);
    // let's get all foreground and possible foreground pixels
    cv::Mat mask_fgpf = ( mask == cv::GC_FGD) | ( mask == cv::GC_PR_FGD);
// and copy all the foreground-pixels to a temporary image
    cv::Mat output = cv::Mat::zeros(input.rows, input.cols, CV_8U);
    input.copyTo(output, mask_fgpf);

    return output;
}

What could be done regarding this? On which level may this problem emerge?