Using the Image Filters in OpenCV
This tutorial is the 3rd in its series, and assumes that you have already completed the Tutorial 1 and Tutorial 2. OpenCV library have a well
defined set of functions for filtering our image. When an image is acquired from a camera it is not proper. The image will be having random
variations in the color intensity and contrast. We have to makethe image process-able so that we get improved results from the application of
various image processing algorithms. This is when the image filtering techniques comes into picture. These basic but slightly complex
algorithms are useful in removing all the abnormalities in our input image making it ready for processing. Therefore the image filtering can
be thought of as the first step in any image processing code. And That it the reason why this tutorial is classified as a basic beginner level
OpenCV tutorial. The image filtering techniques which we are going to deal with in this tutorial are Erode, Dilate, Laplace,Smooth, and
Sobel. I will explain each of them at a primary level before going into the implementation.
Kernel
The basic defenition that you need to know inorder to be able to follow this tutorial is about a kernel. A kernel is nothing but a fixed dimensional
array of numeric coefficients which is used to manipulate an image in some manner. For example, we can imagine a 2×2 identity matrix being
multiplied with an image after slicing the image into a number of matrices. Now if we rejoin the resulting matrices, we will obtain a transformed
image. This means that a 2×2 kernel was used to transform the image in some fashion.
If you want to read more : Kernel
Erode
Inorder to understand Eroding properly, consider a kernel of some size which if operated upon another matrix finds the local minima of that matrix. Now
consider that the our input image is sliced into matrices of size sufficient so that the kernel can operate upon. If the Kernel is convoluted with such a matrix,
it will return the local minima of the matrix. When such a kernel is scanned over the whole image, effectively all the matrices containg a dark element will
become dark. So effectively it means that the dark parts of image become significant/brighter. This can be used to fill smalll white noise in a black/dark background.
Dilate
Inorder to understand Dilate properly, consider a kernel of some size which if operated upon another matrix finds the local maxima of that matrix. Now consider that the our input image is sliced into matrices of size sufficient so that the kernel can operate upon. If the Kernel is convoluted with such a matrix, it will return the local maxima of the matrix. When such a kernel is scanned over the whole image, effectively all the matrices containg a lighter element will become lighter. So effectively it means that the lighter parts of image become significant/brighter. This can be used to fill smalll black noise in a white/light background. I deliberately copied and pasted the same paragraph to make you understand that the concept remains the same for both Erode and Dilate.
Smooth
Smoothing is done to remove the noise in an image. This is done by using a kernel which will find the weighted sum of the input matrix. There are different methods for snoothing. The difference in all of these techhniques is the kernel used. It may be a normalised unity matrix, gaussian,etc.
To read more : Smoothing
To read more : Smoothing
Laplace
Laplace basically helps us find the edges in an image. In an image, an edge is characterized by a high intensity variation. Therefore, if we take the first derivative of the same we will find a local maxima at the edge. This is just basic mathematics. Isn’t it. Now consider that we take the second derivative of the image. We will get a zero at the edge. This is actually the method used in mathematics to check whether a point is a local maxima or not. So this is what laplace also does. Actually laplacian operator is the sum of the second derivative of the image or matrix or whatever in all the possible dimensions. So in the case of a single channel image, laplacian operator is the sum of second derivative of image in the two dimensions namely x and y.
Sobel
Sobel Operater is a discrete differential operator with gaussian smoothing. This means that it is the first step of laplace. Sobel can be used to find edges in an image. The edged will appear white on a dark background.
Erode,Dilate and Smooth
C implementation#include <cv.h> #include <highgui.h> int main() { //variables required in the program int erodecount = 1, dilatecount = 1; int smoothsize = 1, smoothheight = 1; int maxsmooth = 20, maxerode = 20, maxdilate = 20,max_ss = 10, max_sh = 10; //window names are initialized here const char *eimage = "Eroded Image", *dimage = "Dilated Image", *simage = "Smoothed Image"; //trackbar names are initialized here const char *etrack = "Erode", *dtrack = "Dilate", *sstrack = "Smooth Size", *shtrack = "Smooth Height"; //The images are initialized here. IplImage *im = cvLoadImage("F:\image.jpg"); IplImage *imerode = cvCreateImage(cvGetSize(im), 8,3),*imdilate = cvCreateImage(cvGetSize(im), 8,3); IplImage *imsmooth = cvCreateImage(cvGetSize(im), 8,3); cvNamedWindow(eimage); cvNamedWindow(dimage); cvNamedWindow(simage,3); //The required trackbars are created here. cvCreateTrackbar(etrack, eimage, &erodecount, maxerode, NULL); cvCreateTrackbar(dtrack, dimage, &dilatecount, maxdilate, NULL); cvCreateTrackbar(sstrack, simage, &smoothsize, max_ss, NULL); cvCreateTrackbar(shtrack, simage, &smoothheight, max_sh, NULL); while(cvWaitKey(10) != 27) { //Applying the filters cvErode(im, imerode, 0, erodecount); cvDilate(im, imdilate, 0, dilatecount); cvSmooth(im, imsmooth, CV_GAUSSIAN, 2*smoothsize-1,2*smoothheight-1); //Showing the images cvShowImage(eimage, imerode); cvShowImage(dimage, imdilate); cvShowImage(simage, imsmooth); cvShowImage("Original Image", im); } } |
C++ implementation#include <opencv2\opencv.hpp> using namespace cv; int main() { //variables required in the program int erodecount = 1, dilatecount = 1; int smoothheight = 1, smoothwidth = 1; int maxerode = 20, maxdilate = 20,max_sw = 20, max_sh = 20; //window names are initialized here const char *eimage = "Eroded Image", *dimage = "Dilated Image", *simage = "Smoothed Image"; //trackbar names are initialized here const char *etrack = "Erode", *dtrack = "Dilate", *swtrack = "Smooth Width", *shtrack = "Smooth Height"; //The images are initialized here. Mat im = imread("F:\image.jpg"); Mat imerode, imdilate,imsmooth; //creating a copy of image header only for illustration purpose imerode.create(im.size(),im.type()); namedWindow(eimage); namedWindow(dimage); namedWindow(simage,3); //Creating the trackbars createTrackbar(etrack, eimage, &erodecount, maxerode, NULL); createTrackbar(dtrack, dimage, &dilatecount, maxdilate, NULL); createTrackbar(swtrack, simage, &smoothwidth, max_sw, NULL); createTrackbar(shtrack, simage, &smoothheight, max_sh, NULL); while(waitKey(10) != 27) { //Appplying the image filters erode(im, imerode, Mat(), Point(-1, -1), erodecount); dilate(im, imdilate, Mat(), Point(-1, -1), dilatecount); GaussianBlur(im, imsmooth, Size(2*smoothwidth-1,2*smoothheight-1), 0, 0); //Displaying the images imshow("Original Image", im); imshow(eimage, imerode); imshow(dimage, imdilate); imshow(simage, imsmooth); } } |
Explanation
In the previous tutorials we haven’t done any manipulation on the image. But in this tutorial, i have created a dynamic program which can allows the user to adjust the erosion, dilation, smoothness using the track bar feature of OpenCV. So now i will explain the newly introduced functions briefly.
IplImage *imsmooth = cvCreateImage(cvGetSize(im), 8,3); cvCreateImage(CvSize size, int bitDepth, int channels) is used to create and allocate image data. CvSize is an OpenCV structure that stores height and width.
To read more : CvSize Now the second parameter is the depth of image. the value can be 8,16,32. The 3rd paramater is the number of channels in the image. To read more : cvCreateImage cvCreateTrackbar(etrack, eimage, &erodecount, maxerode, NULL); |
imerode.create(im.size(),im.type()); The above line has no effect in the code. But was included so that the reader understands the various usages of Mat member functions.
Mat::create(Size size, int type) is used to create and allocate the space for image data. In this example we are allocating the same size and type of im to the image imerode. The Member functions Mat::size() and Mat::type() has been used to copy the image properties of im to imerode. To read more : Mat::create createTrackbar(etrack, eimage, &erodecount, maxerode, NULL); |
The explanation for both the functions are given together only because there is not much of a difference in the function declaration.
cvCreateTrachBar(const char* trackbarName, const char* windowName, int* value, int count, CvTrackbarCallback onChange)
can be used to create track bars in our OpenCV programs. Now Lets understand what are the parameters:
cvCreateTrachBar(const char* trackbarName, const char* windowName, int* value, int count, CvTrackbarCallback onChange)
can be used to create track bars in our OpenCV programs. Now Lets understand what are the parameters:
- The first parameter is the name of the track bar This will be displayed in the window.
- The second parameter is the name of the window. The window must be created using cvNamedWindow/namedWindow before creating track bar.
- The third parameter is the address of the integer variable. This variable will contain the value that we change using track bar.
- The fourth parameter is the maximum value the former variable can take.
- The fifth parameter is the name of the callback function to be called when the track bar value is changed. If not required give it as NULL.
cvErode(im, imerode, 0, erodecount); cvDilate(im, imdilate, 0, dilatecount);erode, NULL); |
erode(im, imerode, Mat(), Point(-1, -1), erodecount); dilate(im, imdilate, Mat(), Point(-1, -1), dilatecount); |
Even though the C and C++ functions for erode and dilate have a lot of difference, the structure of the function is same when we check cvErode and cvDilate. Therefore, I will be explaining only Erode function as you can easily understand how cvDilate works from the former.
cvErode(const CvArr* src, CvArr* dst, IplConvKernel* element, int iterations) is the function which is used to erode an image. Actually this is pretty easy use this function if you properly knows the function parameters.
cvSmooth(im, imsmooth, CV_GAUSSIAN, 2*smoothsize-1,2*smoothheight-1); cvSmooth(const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int param1=3, int param2=0, double param3=0, double param4=0)
is the function used to smoothen an image.
|
erode(const Mat& src, Mat& dst, const Mat& element, Point anchor=Point(-1, -1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue())
is the C++ equivalent of erode function. As we can see from the function declaration, it is highly flexible. It is possible to change the anchor point of kernel using the erode function itself. Now let us understand the function clearly
GaussianBlur(im, imsmooth, Size(2*smoothwidth-1,2*smoothheight-1), 0, 0); GaussianBlur(const Mat& src, Mat& dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT)
is the C++ equivalent of cvSmooth with CV_GAUSSIAN kernel.
|
Write more, thats all I have to say. Literally, it seems as though you relied on the video to make your point.
You obviously know what youre talking about, why waste your intelligence on just posting videos to your blog when you could be giving us something
enlightening to read?
Simply incredible! I understand you have put a lot of effort into this and I really wanted to tell you how grateful I am! Hope you placed out also much more remarkable stuff in the near future and also I will certainly come back and read it!
“I think this is a real great post.Much thanks again. Great.”