Closing Holes in Images

Microsoft Visual C++
Creator
Posts: 149
Joined: Tue Dec 16, 2008, 20:52
Location: Hannover, Germany
Contact:

Closing Holes in Images

Here I suggest to concider an "CloseHoles" algorithm, based on linear interpolation. The algorithm is realized by application of an iterative linear diffusion process to the areas of arbitrary image, marked as hole.
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();}`

Creator
Posts: 149
Joined: Tue Dec 16, 2008, 20:52
Location: Hannover, Germany
Contact:

Re: Closing Holes in Images

The algorithm first calculates the mask which designates pixels, belonging to holes. Then the hole pixels are initialized with the "last-good-value" from previouse pixels. That is done in order to speed up the convergence, but also multigrids could be applied. Afterwards the the linear diffusion (the Laplassian filter) is applied. Here is one result of processing a test image (the black color stay for the hole region):

Creator
Posts: 149
Joined: Tue Dec 16, 2008, 20:52
Location: Hannover, Germany
Contact:

Re: Closing Holes in Images

It is also possible to use OpenCV Inpainting methods.