How about to optimize its main loop or discuss some more sophisiticated algorithms ?
Code: Select all
void closeHoles()
{
const int nIt = 250; // Number of iterations
register int x, y;
register int c, i;
Mat tmp;
// Creating mask for informative pixels. (for simplicyty, pixel values = 0, are holes => mask there is 0, otherwise 1)
cvtColor(*this, tmp, CV_RGB2GRAY);
Mat mask(this->size(), CV_8UC1);
mask.setTo(1);
for (x = 0; x < this->cols; x++)
for (y = 0; y < this->rows; y++)
if (tmp.at<unsigned char>(y,x) == 0) mask.at<unsigned char>(y,x) = 0;
tmp.release();
erode(mask, mask, Mat());
// Converting "this" image to floating-point tmp image.
this->convertTo(tmp, CV_MAKETYPE(CV_32F, this->channels()));
vector<Mat> channels(tmp.channels());
split(tmp, channels);
// Initializing holes to speed up convergence (for simplicity)
float val = 0;
for (c = 0; c < tmp.channels(); c++)
for (x = 0; x < tmp.cols; x++)
for (y = 0; y < tmp.rows; y++) {
if (mask.at<unsigned char>(y,x) == 0) channels[c].at<float>(y,x) = val;
val = channels[c].at<float>(y,x);
}
// Main Loop
for (c = 0; c < tmp.channels(); c++) {
Mat buf;
channels[c].copyTo(buf);
for(i = 0; i < nIt; i++) {
for (x = 1; x < tmp.cols - 1; x++)
for (y = 1; y < tmp.rows - 1 ; y++)
if (mask.at<unsigned char>(y,x) == 0) buf.at<float>(y,x) = 0.25f * (channels[c].at<float>(y,x+1) + channels[c].at<float>(y,x-1)+channels[c].at<float>(y+1,x)+channels[c].at<float>(y-1,x));
buf.copyTo(channels[c]);
} // j
} // i
merge(channels, tmp);
mask.release();
for (c = 0; c < tmp.channels(); c++) channels[c].release();
channels.clear();
tmp.convertTo(*this, this->type());
tmp.release();
}