Post by 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();
}
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 [i]hole[/i].
How about to optimize its main loop or discuss some more sophisiticated algorithms ?
[code]
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();
}
[/code]