Sunday, 16 March 2014

A piece of advice.

Hi guys! Hope you're doing well.
So you must have got some idea of what OpenCV is! (pun intended :P)
Before moving further, I would like to advise you on how you must understand or write a code for OpenCV.
Mostly, you look through the code from top to bottom, look at the variables and functions and then understand it.
Try this once:

1. Observe the libraries included
2. Go to 'MAIN' function and study it first before looking at the user-defined functions. Understand what the 'main' function basically does.

  • Creates a trackbar? what are the lowest and highest values? What is the response function for trackbar? Having observed these, go to where you've left before jumping to 'MAIN' function. Then study those variables and functions.
  • Then again come back to 'Main' function where you had left and then study further and repeat the process.
In this way, you study the program in a manner you understand it.
Hope this helps.
Cheers!

Saturday, 15 March 2014

#7b. Detecting Corners

Let us get our hands on Edge Detection Technique.
-------------------------------------------------------------
Input image:

#include<iostream>
#include<cv.h>
#include<highgui.h>
#include<stdlib.h>
using namespace std;
using namespace cv;

Mat img,img_g;

int main()
{
img=imread("images/squares.jpg");
cvtColor(img,img_g,CV_RGB2GRAY);

vector<Point2d> corners;
//creates a 2D Vector

float quality=0.01;
int min_distance=10,max_corners=50;

goodFeaturesToTrack(img_g,corners,max_corners,quality,min_distance);
//tracks good features!
//img_g: target image
//corners: stores the position of corners
//max_corners: maximum number of corners; you can vary these
// quality, min_distance, refer documentation.

Mat img_corners=img.clone();

for(int i=0;i < corners.size();i++)
circle(img_corners,corners[i],4,CV_RGB(255,0,0),-1);
// draws circles
namedWindow("Image");
imshow("Image",img_corners);
while(char(waitKey(1)) != 'q') {}

return 0;
}
--------------------------------------------------
Result:
We are first converting the image to grayscale and then detecting the corners.

This algorithm was proposed by Shi and Tomasi.

Sources:



#7a. Detecting Edges with increased efficiency

Being Updated.

#6. User Interface: Creating a Trackbar

Now, I will deviate a bit from our image processing techniques and algorithms.
So far, we have seen how we can use 2D Convolution to process images.
In this post, I will show you how create a trackbar for user interface.

A simple example that increases brightness of the picture.
-----------------------------------------------------------------------------
Input image:


#include<iostream>
#include<cv.h>
#include<highgui.h>
using namespace std;
using namespace cv;

Mat img;
//STOP. Refer to 'main' function first.

int slider=0, slider_max=100;

// the following call back function takes two arguments
//first: the position of trackbar
// second: Null
// Refer documentation

void on_trackbar(int pos, void *){
Mat img_c;
img_c=img+Scalar(pos,pos,pos);
//This command varies brightness according to the position of trackbar.
imshow("Image",img_c);
}

int main()
{
img=imread("images/image.jpg",CV_LOAD_IMAGE_COLOR);
namedWindow("Image");
createTrackbar("Brightness","Image",&slider,slider_max,on_trackbar);

//createTrackbar creates a trackbar
//first argument "Brightness": Title of the Trackbar
//second argument "Image": The window name in which trackbar has to be created.
//third: minimum value of trackbar position
//NOTE: it has to be passed by reference. Refer documentation.
//fourth: maximum value
//fifth: the function which has to be called when the user interacts(i.e. Trackbar position is changed)

while(char(waitKey(0))!='q'){}
return 0;

}
-----------------------------------------------------------------
Result:

You can't see the trackbar here, but you've to believe in my code:P


Note: In previous tutorials, if you remember, I had commented against a variable that the value can be varied. You can actually try varying the values by creating a trackbar!
Do this as an exercise. In this way you can also go through all the tutorials until now, and believe me, your concepts will be more clear. Do comment if you have any doubts.

Friday, 14 March 2014

#5. Eroding and Dilating an Image

Now, continuing on the same concept of 2D Convolution, Eroding and Dilating works on the form and structure of the image.
In previous tutorials, we slid a kernel over an image and did operations like summing up all the element-wise multiplication pairs and storing it in an anchor point.

In this tutorial, what we are gonna do is to calculate the minimum(Eroding) and maximum(Dilating) values of the element-wise multiplication and store it the anchor point.

For simplicity, we take all the kernel elements as ones.
Try visualizing this.
Now, slide the kernel over your image(2D Convolution).
Because all kernel elements are ones, applying this kernel(in Eroding) means replacing each pixel value with the minimum value in a rectangular region surrounding the pixel. You can imagine that this will cause the black areas in the image to “encroach” into the white areas (because pixel value for white is higher than that for black).

Dilating the image is the same, the only difference being that the response if defined as the maximum of
element-wise multiplications instead of minimum. This will cause the white regions to encroach into black regions.
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
 Mat img=imread("images/j.jpg"),img2,img3;

 Mat st_elem=getStructuringElement(MORPH_RECT,Size(5,5));

//I am defining my own kernel matrix here
//MORPH_RECT: Rectangular Morphological Matrix
//Size(5,5): 5x5 size matrix
// You can vary the size and shape

 erode(img,img2,st_elem);

 dilate(img,img3,st_elem);


 namedWindow("Image");
 namedWindow("Image2");
        namedWindow("Image3");

 imshow("Image",img);
 imshow("Image2",img2);
 imshow("Image3",img3);

 while(char(waitKey(0))!='q'){}
 return 0;

}

Input image:



Result:
Eroding

Dilating




-------------------------------------------------
More sources:
FILTERING(Optional)

Thursday, 13 March 2014

#4. Blurring an Image

Blurring is built on the same concept of 2D Convolution, difference being the change in kernel matrix.
Blurring averages the pixel values around one particular pixel.
Looks simple, but blurring is much more than just Convolution, it requires some more concepts of variance, averaging, etc.

A very simple kernel is a box kernel:

1   1   1   1   1
1   1   1   1   1
1   1   1   1   1 
1   1   1   1   1 
1   1   1   1   1 


This kernel deems every pixel equally important. A better kernel would be one that decreases the effect of a pixel as its distance from the central pixel increases. The Gaussian kernel does this, and is the most commonly used blurring kernel:
 
1    4   6    4   1
4  16  24  16  4
6  24  36  24  6
4  16  24  16  4
1    4   6    4   1
------------------------------------------------------------------------
#include<iostream>
#include<cv.h>
#include<highgui.h>
using namespace std;
using namespace cv;
int main()
{

 Mat img_b,img=imread("images/image.jpg");

 float blur[5][5]={{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1}};
// simple box kernel

//float blur[5][5]={{1,4,6,4,1},{4,16,24,16,4},{6,24,36,24,6},{4,16,24,16,4},{1,4,6,4,1}};
// Guassian kernel

 Mat filter_b=Mat(5,5,CV_32FC1,blur);

 filter2D(img,img_b,-1,filter_b);

 namedWindow("Image");
 namedWindow("Image_B");
 imshow("Image",img);
 imshow("Image_B",img_b);
 while(char(waitKey(0))!='q'){}
 return 0;

}
-------------------------------------------------------------------------

Note: Blurring is more than just Convolution. If you want to go further, please visit THIS documentation. Following is the basic application of 'GaussianBlur()' function.
--------------------------------------------------------------------------
Input Image:
 


#include<iostream>
#include<cv.h>
#include<highgui.h>
using namespace std;
using namespace cv;
int main()
{

 Mat img_b,img=imread("images/image.jpg");
 
 int k=5;
//you can vary the value of 'k' from 1 to 5, in this case.

 int sigma = 0.3 * ((k - 1) * 0.5 - 1) + 0.8;
 GaussianBlur(img, img_b, Size(k, k), sigma);

 namedWindow("Image");
 namedWindow("Image_B");
 imshow("Image",img);
 imshow("Image_B",img_b);
 while(char(waitKey(0))!='q'){}
 return 0;

}
-------------------------------------------------------------

Result:



#3d. Further discussion of 'filter2D' and Convolution in 2D

Under construction.