Find the Center of the Largest Blob
The observation of @juvian, which pointed to the obvious mistake of copying vectors, is good. But I think that the main point is that of recognizing this is a pretty famous problem in Image Processing: Connected Components Labeling. Flood fill is one of the slowest solutions, because of its poor cache usage.

Here I'm using the SAUF algorithm published in Two Strategies to Speed up Connected Component Labeling Algorithms.

In particular this solution works by making two scans of the image and using Union-Find to manage label equivalences. One thing to note is that the second scan is not needed to solve the specific problem, because you can stop without getting the labeled image and just use the vector of blobs. This saves about 20% of the total time.

This takes few milliseconds for the specific image. 

I'm sorry for posting this extremely long piece of code, but a lot of additional code is needed for having a working example. What is needed is a way to store images, the UF data structure (here everything is static, but this is not needed), the PerformLabeling function. The PNG image was converted to PBM format for easy loading.

#include &lt;vector&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;cstdint&gt;
#include &lt;tuple&gt;

using namespace std;

template &lt;typename T&gt;
struct mat {
    size_t rows_, cols_;
    vector&lt;T&gt; data_;

    mat(size_t rows = 0, size_t cols = 0) : rows_(rows), cols_(cols), data_(rows*cols) {}

    const T&amp; operator()(size_t r, size_t c) const { return data_[cols_*r + c]; }
    T&amp; operator()(size_t r, size_t c) { return data_[cols_*r + c]; }

    const T* operator[](size_t r) const { return &amp;data_[cols_*r]; }
    T* operator[](size_t r) { return &amp;data_[cols_*r]; }
};

bool loadPBM(const string&amp; filename, mat&lt;uint8_t&gt;&amp; img)
{
    ifstream is(filename, ios::binary);
    if (!is)
        return false;

    string type;
    size_t w, h;
    is &gt;&gt; type &gt;&gt; w &gt;&gt; h;
    if (type!="P4" || is.get()!='\n')
        return false;

    img = mat&lt;uint8_t&gt;(h, w);

    for (size_t r = 0; r &lt; h; ++r) {
        uint8_t nbits = 0;
        uint8_t buffer;
        for (size_t c = 0; c &lt; w; ++c) {
            if (nbits == 0) {
                if (!is.get(reinterpret_cast&lt;char&amp;&gt;(buffer)))
                    return false;
                nbits = 8;
            }
            img(r, c) = 255 * (1 - (buffer &gt;&gt; --nbits &amp; 1));
        }
    }

    return is.good();
}

bool savePGM(const string&amp; filename, const mat&lt;uint8_t&gt;&amp; img)
{
    ofstream os(filename, ios::binary);
    if (!os)
        return false;

    os &lt;&lt; "P5\n" &lt;&lt; img.cols_ &lt;&lt; " " &lt;&lt; img.rows_ &lt;&lt; "\n255\n";
    os.write(reinterpret_cast&lt;const char*&gt;(&amp;img.data_[0]), img.cols_*img.rows_);

    return os.good();
}

// Union-find (UF)
class UF {
public:
    static void Alloc(unsigned max_length) {
        P_ = new unsigned[max_length];
    }
    static void Dealloc() {
        delete[] P_;
    }
    static void Setup() {
        P_[0] = 0;// First label is for background pixels
        length_ = 1;
    }
    static unsigned NewLabel() {
        P_[length_] = length_;
        return length_++;
    }
    static unsigned GetLabel(unsigned index) {
        return P_[index];
    }
    static unsigned GetLength() {
        return length_;
    }
    static unsigned Merge(unsigned i, unsigned j)
    {
        // FindRoot(i)
        while (P_[i] &lt; i) {
            i = P_[i];
        }
        // FindRoot(j)
        while (P_[j] &lt; j) {
            j = P_[j];
        }
        if (i &lt; j)
            return P_[j] = i;
        return P_[i] = j;
    }
    static unsigned Flatten()
    {
        unsigned k = 1;
        for (unsigned i = 1; i &lt; length_; ++i) {
            if (P_[i] &lt; i) {
                P_[i] = P_[P_[i]];
            }
            else {
                P_[i] = k;
                k = k + 1;
            }
        }
        return k;
    }
private:
    static unsigned *P_;
    static unsigned length_;
};
unsigned* UF::P_;
unsigned UF::length_;

struct blob {
    size_t x = 0, y = 0, count = 0;
    size_t left = SIZE_MAX, right = 0, top = SIZE_MAX, bottom = 0;
    blob() {}
    void accumulate(size_t r, size_t c) {
        x += c;
        y += r;
        ++count;

        if (left &gt; c)
            left = c;
        if (right &lt; c)
            right = c;
        if (top &gt; r)
            top = r;
        if (bottom &lt; r)
            bottom = r;
    }
    void accumulate(const blob&amp; b) {
        x += b.x;
        y += b.y;
        count += b.count;

        if (left &gt; b.left)
            left = b.left;
        if (right &lt; b.right)
            right = b.right;
        if (top &gt; b.top)
            top = b.top;
        if (bottom &lt; b.bottom)
            bottom = b.bottom;
    }
};

template &lt;typename Blob&gt;
size_t PerformLabeling(const mat&lt;uint8_t&gt;&amp; img, mat&lt;unsigned&gt;&amp; img_labels, vector&lt;Blob&gt;&amp; blobs)
{
    size_t h = img.rows_;
    size_t w = img.cols_;

    img_labels = mat&lt;unsigned&gt;(h, w); // Allocation + initialization of the output image

    UF::Alloc(((img.rows_ + 1) / 2) * ((img.cols_ + 1) / 2) + 1); // Memory allocation of the labels solver
    UF::Setup(); // Labels solver initialization

    vector&lt;Blob&gt; temp_blobs(((img.rows_ + 1) / 2) * ((img.cols_ + 1) / 2) + 1);

    // Rosenfeld Mask
    // +-+-+-+
    // |p|q|r|
    // +-+-+-+
    // |s|x|
    // +-+-+

    // First scan
    for (size_t r = 0; r &lt; h; ++r) {
        // Get row pointers
        const unsigned char *img_row = img[r];
        const unsigned char *img_row_prev = img_row - img.cols_;
        unsigned *img_labels_row = img_labels[r];
        unsigned *img_labels_row_prev = img_labels_row - img_labels.cols_;

        for (size_t c = 0; c &lt; w; ++c) {
#define CONDITION_P c &gt; 0 &amp;&amp; r &gt; 0 &amp;&amp; img_row_prev[c - 1] &gt; 0
#define CONDITION_Q r &gt; 0 &amp;&amp; img_row_prev[c] &gt; 0
#define CONDITION_R c &lt; w - 1 &amp;&amp; r &gt; 0 &amp;&amp; img_row_prev[c + 1] &gt; 0
#define CONDITION_S c &gt; 0 &amp;&amp; img_row[c - 1] &gt; 0
#define CONDITION_X img_row[c] &gt; 0

#define ACTION_1 // nothing to do 
#define ACTION_2 img_labels_row[c] = UF::NewLabel(); // new label
#define ACTION_3 img_labels_row[c] = img_labels_row_prev[c - 1]; // x &lt;- p
#define ACTION_4 img_labels_row[c] = img_labels_row_prev[c]; // x &lt;- q
#define ACTION_5 img_labels_row[c] = img_labels_row_prev[c + 1]; // x &lt;- r
#define ACTION_6 img_labels_row[c] = img_labels_row[c - 1]; // x &lt;- s
#define ACTION_7 img_labels_row[c] = UF::Merge(img_labels_row_prev[c - 1], img_labels_row_prev[c + 1]); // x &lt;- p + r
#define ACTION_8 img_labels_row[c] = UF::Merge(img_labels_row[c - 1], img_labels_row_prev[c + 1]); // x &lt;- s + r

            if (CONDITION_X) {
                if (CONDITION_Q) {
                    ACTION_4
                }
                else {
                    if (CONDITION_R) {
                        if (CONDITION_P) {
                            ACTION_7
                        }
                        else {
                            if (CONDITION_S) {
                                ACTION_8
                            }
                            else {
                                ACTION_5
                            }
                        }
                    }
                    else {
                        if (CONDITION_P) {
                            ACTION_3
                        }
                        else {
                            if (CONDITION_S) {
                                ACTION_6
                            }
                            else {
                                ACTION_2
                            }
                        }
                    }
                }
            }
            else {
                ACTION_1
                continue;
            }

            temp_blobs[img_labels_row[c]].accumulate(r, c);
        }
    }

    size_t n_labels = UF::Flatten();

    blobs.resize(n_labels);
    for (size_t i = 0; i &lt; UF::GetLength(); ++i) {
        blobs[UF::GetLabel(i)].accumulate(temp_blobs[i]);
    }

    // Second scan
    for (size_t r = 0; r &lt; img_labels.rows_; ++r) {
        unsigned *img_row_start = img_labels[r];
        unsigned *img_row_end = img_row_start + img_labels.cols_;
        for (; img_row_start != img_row_end; ++img_row_start) {
            *img_row_start = UF::GetLabel(*img_row_start);
        }
    }

    UF::Dealloc(); // Memory deallocation of the labels solver

    return n_labels;
}

int main() {
    mat&lt;uint8_t&gt; img;
    if (!loadPBM("mD6sL.pbm", img))
        return EXIT_FAILURE;

    mat&lt;unsigned&gt; img_labels;

    vector&lt;blob&gt; blobs;
    auto n = PerformLabeling(img, img_labels, blobs);

    blob bmax;
    for (const auto&amp; b :  blobs) {
        if (bmax.count &lt; b.count)
            bmax = b;
    }
    bmax.x /= bmax.count;
    bmax.y /= bmax.count;

    mat&lt;uint8_t&gt; out(img.rows_, img.cols_);
    copy(begin(img_labels.data_), end(img_labels.data_), begin(out.data_));

    for (int i = -50; i &lt;= 50; ++i) {
        out(bmax.y + i, bmax.x) = 255;
        out(bmax.y, bmax.x + i) = 255;
    }
    for (size_t i=bmax.left;i&lt;=bmax.right;++i) {
        out(bmax.top, i) = 255;
        out(bmax.bottom, i) = 255;
    }
    for (size_t i = bmax.top; i &lt;= bmax.bottom; ++i) {
        out(i, bmax.left) = 255;
        out(i, bmax.right) = 255;
    }

    if (!savePGM("out.pgm", out))
        return EXIT_FAILURE;

    return EXIT_SUCCESS;
}