My initial encounter with filters, convolution and correlation in OpenCV made me play around with the filters for Gaussian smooth, erosion and dilation operations on random image files. However I found the experience rather unsatisfactory and I wanted to get a real feel for the working of these operations. Suddenly a thought struck me. Could I restore an old family photograph of my parents? The photograph has areas of white patches that had to be removed.
So I started to dig a little more into the filters, convolution and correlation matrices to get a better understanding.
This is the original photograph.
As can be seen there are large patches in several places in the photograph. So I decided to use cvFloodFill to fill these areas.
a) cvFloodFill: Since I had to identify the spots where these patches occurred I took a dump of the cvMat of the image which I resized to about 29 x 42. By inspecting the data I could see that the patches typically corresponded to intensity values that were greater than 170. So I decided that the cvFloodFill should happen with the seed around these parts. So the code checks the intensity values > 170 and calls cvFloodFill. After much tweaking I could see that the white patches were now filled with gray (newval intensity= 150.0) So I was able to get rid of the white patches.
b) cvSmooth: The next step that I took was to perform a Gaussian smooth of the picture. This smoothed out the filled parts
c) cvErode & cvDilate: I followed this with cvErode to smooth out the dark areas and cvDilate to smooth out the bright areas.
d) cvFilter2D: I wanted to now sharpen the image. I did a lot of experiments with different kernel values but I found this to be extremely difficult to work with. After much trial and error I came with a kernel values of
The sharpening was reasonable but there are areas where there are white streaks. I still need to figure out a kernel that can sharpen images. For this also to understand what was happening I tried to dump the values of the image to get a feel of where the values lay.
e) cvSmooth: Finally I performed a cvSmooth of the filtered output.
While I have had fair success there is still a lot more left to be desired from the final version.
The complete process flow
The code is included below
int main(int argc, char** argv)
IplImage* img = cvLoadImage(“dad_mom.jpg”,0);
// get the image data
height = img->height;
width = img->width;
step = img->widthStep;
channels = img->nChannels;
data = (uchar *)img->imageData;
CvMat kernel= cvMat(3,3,CV_32FC1,a);
printf(“Processing a %d x %d image with %d channels\n”,height,width,channels);
// Create windows
// Original image
/* Flood fill in white patches intensity > 170.0 */
//printf(“Data = %d \n”,data[i*step+j*channels+k]);
if((data[i*step+j*channels+k]) > 170.0)
cvFloodFill(img,seed,newval,lodiff,highdiff, NULL,CV_FLOODFILL_FIXED_RANGE,NULL); }
// Gaussian smooth
dst = cvCloneImage(img);
cvSmooth( img, dst, CV_GAUSSIAN, 3, 3, 0, 0 );
// Erode the image
dst1 = cvCloneImage(img);
IplConvKernel* kern = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_RECT,values);
// Perform dilation operation
dst2 = cvCloneImage(img);
// Filter the image with convolution kernel. Sharpen the image
dst3 = cvCloneImage(img);
// Smoothen the image
dst4 = cvCloneImage(img);
cvSmooth( dst3, dst4, CV_MEDIAN, 3, 0, 0, 0 );
From my blog : http://gigadom.wordpress.com
Disclaimer: This does not represent IBM's views or strategies