Closing Holes in Images

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

Closing Holes in Images

Postby Creator » Thu May 12, 2011, 00:28

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();
}

User avatar
Creator
Posts: 157
Joined: Tue Dec 16, 2008, 20:52
Location: Hannover, Germany
Contact:

Re: Closing Holes in Images

Postby Creator » Mon May 16, 2011, 17:31

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):
cat.jpg
Original image with a hole (black-color-coded)

cat_closed.jpg
Restored image

User avatar
Creator
Posts: 157
Joined: Tue Dec 16, 2008, 20:52
Location: Hannover, Germany
Contact:

Re: Closing Holes in Images

Postby Creator » Mon Jun 06, 2011, 15:14

It is also possible to use OpenCV Inpainting methods.
Read more here http://en.wikipedia.org/wiki/Inpainting


Return to “Programming”

Who is online

Users browsing this forum: No registered users and 4 guests