Blender, 3D, Development, OpenGL, Computer Vision, OpenCV, Flash and more…
14 Nov
In this tutorial we go to introduce to the pattern recognitions basics in openCV.
In pattern recognitions before we can classificate an element we need train our system. We go to train with 3 class with 100 samples each one.
Then we create 2 matrix trainData and traninClasses with 300 samples:
int train_sample_count = 300;
CvRNG rng_state = cvRNG(-1);
CvMat* trainData = cvCreateMat( train_sample_count, 2, CV_32FC1 );
CvMat* trainClasses = cvCreateMat( train_sample_count, 1, CV_32FC1 );
Where our 100 first data are class 1, the range 100 to 200 are class 2 and last 100 data are class 3, then we set our trainClasses matrix data:
cvGetRows( trainClasses, &trainClasses1, 0, 100 );
cvSet( &trainClasses1, cvScalar(1) );cvGetRows( trainClasses, &trainClasses2, 100, 200 );
cvSet( &trainClasses2, cvScalar(2) );cvGetRows( trainClasses, &trainClasses3, 200, 300 );
cvSet( &trainClasses3, cvScalar(3) );
cvGetRows function set a CvMat structure (matrix structure) with selected rows of source matrix.
cvGetRows( srcMatrix, destMatrix, first_row, last_row );
And set all rows to dest class witn cvSet, this function set all values of matrix to a scalar
cvSet( matrix, cv_scalar_value );
We go to use in this tutorial a random normalized sample in 2D (2D gaussian mixture) that we generate in openCV with cvRandArr function. For create data sample we need create to cvRandArr, one for x values and other for y values.
//Train sample class 1
cvGetRows( trainData, &trainData1, 0, 100 );
cvGetCol( &trainData1, &colData1x, 0);
cvGetCol( &trainData1, &colData1y, 1);
cvRandArr( &rng_state, &colData1x, CV_RAND_NORMAL, cvScalar(200), cvScalar(50) );
cvRandArr( &rng_state, &colData1y, CV_RAND_NORMAL, cvScalar(200), cvScalar(50) );
//Train sample class 2
cvGetRows( trainData, &trainData2, 100, 200 );
cvGetCol( &trainData2, &colData2x, 0);
cvGetCol( &trainData2, &colData2y, 1);
cvRandArr( &rng_state, &colData2x, CV_RAND_NORMAL, cvScalar(300), cvScalar(50) );
cvRandArr( &rng_state, &colData2y, CV_RAND_NORMAL, cvScalar(300), cvScalar(50) );
//Train sample class 3
cvGetRows( trainData, &trainData3, 200, 300 );
cvGetCol( &trainData3, &colData3x, 0);
cvGetCol( &trainData3, &colData3y, 1);
cvRandArr( &rng_state, &colData3x, CV_RAND_NORMAL, cvScalar(100), cvScalar(30) );
cvRandArr( &rng_state, &colData3y, CV_RAND_NORMAL, cvScalar(400), cvScalar(30) );
Now we can train our classifier. In this basic tutorial, we go to use the k nearest neighbour classifier.
This classifier is the most simplest but it’s used in more cases. This algorithm classify an object by a majority vote of its nearest neighbors.
Then we use CvKNearest openCV class
CvKNearest knn( trainData, trainClasses, 0, false, K );
Where first parameter is train data, second the classes, and last parameter is the nomber of k-neighbour value with maximum value is 32.
Now we have in knn instance a k-nn classifier. Now if we want know in wich class is classified point only need call knn.find_nearest and return the nearest class.
Then we go to classify a values for range [0,0] to [500,500] this our classifier, this is the result:
Red points: Train data of class 1.
Green points: Train data of class 2.
Blue points: Train data of class 3.
Red area: classify as class 1 with more than 5 neighbours in class 1
Light red area: classify as class 1 with less than 5 neighbours in class 1
Green area: classify as class 2 with more than 5 neighbours in class 2
Light green area: classify as class 2 with less than 5 neighbours in class 2
Blue area: classify as class 3 with more than 5 neighbours in class 3
Light blue area: classify as class 2 with less than 5 neighbours in class 2
Orange area: don’t classify
11 Nov
Last day, i’m developing an application with hsqldb and java swing with jpa entites classes, and whe i set a primary key or class attribute as int, integer, long or similar number type, when it parsed to sql statment with toplink it’s created as Number instead as integer.
Before i looking many hours in Google i find the solution thanks to this web
The solution is include in persistence.xml this line:
<property name=“toplink.target-database” value=“HSQL”/>
We need specify to Toplink JPA the target database to HSQL.
But we can specify more types or database as Attunity, Cloudspace, Database, MySQL4, Oracle… You can find the documentation and databases suport in Toplink Essential JPA Extension Reference
7 Nov
In this basic tutorial we go to learn some basic instructions to work in OpenCV, mouse event, trackbar controler, create image, save image and draw basic circle.
First step is create two windows, one is our canvas image, and other to color selector as we see in last tutorials.
//Create window
cvNamedWindow( “Demo”, 0 );
cvNamedWindow( “ColorSelector”,0);
Second step is creat the trackbars to control the color, then we need 3 trackbars, one by color.
//Create track Bar
cvCreateTrackbar(”Red”,”ColorSelector”, &red,255,&changeColor);
cvCreateTrackbar(”Green”,”ColorSelector”, &green,255,&changeColor);
cvCreateTrackbar(”Blue”,”ColorSelector”, &blue,255,&changeColor);
The trackbar function has these parameter and definition:
int cvCreateTrackbar( const char* trackbar_name, const char* window_name,
int* value, int count, CvTrackbarCallback on_change );trackbar_name Name of created trackbar.
window_name Name of the window which will e used as a parent for created trackbar.
value Pointer to the integer variable, which value will reflect the position of the slider. Upon the creation the slider position is defined by this variable.
count Maximal position of the slider. Minimal position is always 0.
on_change Pointer to the function to be called every time the slider changes the position. This function should be prototyped as void Foo(int);Can be NULL if callback is not required.
In our tutorial we have a changeColor function asociated to set a color preview:
void changeColor(int pos){
cvSet(imgColor, CV_RGB(red,green,blue),NULL);
}
The cvSet function set all matrix values to a scalar value. The cvSet function and params are:
void cvSet( CvArr* arr, CvScalar value, const CvArr* mask=NULL );
arr The destination array.
value Fill value.
mask Operation mask, 8-bit single channel array; specifies elements of destination array to be changed.The function cvSet copies scalar value to every selected element of the destination array:
arr(I)=value if mask(I)!=0
If array arr is of IplImage type, then is ROI used, but COI must not be set.
To get mouse events we use cvSetMouseCallback where first parameter is window name we want give events, and the second parameter the pointer to callback function, we can pass third parameter as callback optional parameters.
cvSetMouseCallback(”Demo”,&on_mouse, 0 );
The mouse event callback function must defined a:
void on_mouse( int event, int x, int y, int flags, void* param )
Where
event is a constant that give this values and define the mouse event:
#define CV_EVENT_MOUSEMOVE 0
#define CV_EVENT_LBUTTONDOWN 1
#define CV_EVENT_RBUTTONDOWN 2
#define CV_EVENT_MBUTTONDOWN 3
#define CV_EVENT_LBUTTONUP 4
#define CV_EVENT_RBUTTONUP 5
#define CV_EVENT_MBUTTONUP 6
#define CV_EVENT_LBUTTONDBLCLK 7
#define CV_EVENT_RBUTTONDBLCLK 8
#define CV_EVENT_MBUTTONDBLCLK 9x, y: integer mouse position in our image
flag is another constant value:
#define CV_EVENT_FLAG_LBUTTON 1
#define CV_EVENT_FLAG_RBUTTON 2
#define CV_EVENT_FLAG_MBUTTON 4
#define CV_EVENT_FLAG_CTRLKEY 8
#define CV_EVENT_FLAG_SHIFTKEY 16
#define CV_EVENT_FLAG_ALTKEY 32
3 Nov
In last tutorial we learn how to get frames of our camera, now we go to learn some basic OpenCV functions to work with our captured frames or video. There is nothing special, but it’s the first steps to introduce to work with OpenCV
Imagine we want create a basic OpenCV program that get a video o camera capture and process the images to get a binary image difference between actual frame and last frame.
Then we have a actual image, lastImage, diffImage where we store the difference images, and the bitImage result that are IplImage instance.
IplImage* image;
IplImage* lastImage;
IplImage* diffImage;
IplImage* bitImage;
Whe need create these variables and initialize with cvCreateImage, this function create and allocate in memory the structure and headers of our image, this function need as attribute image size, depth and number of channels. We get frame as reference to initialize the variables.
image=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
The frame whe get sure is a RGB image, but we go to working with gray level images the we need conver captured frame to Gray Level. The cvCvtColor conver color spaces of image to another and is defined:
void cvCvtColor( const CvArr* src, CvArr* dst, int code );
cvCvtColor(frame, image, CV_BGR2GRAY);
We can get a new copy in memory of image withcvCloneImage
lastImage=cvCloneImage(image);
To get the image differences we use cvAbsDiff function, to get absolute diference between images:
cvAbsDiff(image,lastImage,diffImage);
The function definition
void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );
Then to finish we only need get a threshold of image, and we do it with cvThreshold function
cvThreshold(diffImage,bitImage,tr,255,CV_THRESH_BINARY);
And this function have this definition:
double cvThreshold( const CvArr* src, CvArr* dst, double threshold,
double max_value, int threshold_type );
src or 8-bit, threshold is the threshold value, max_value is the maximum value to use with CV_THRESH_BINARY and CV_THRESH_BINARY_INV thresholding types, and threshold_type is thresholding typeThis is the main loop program:
for(;;){
IplImage* frame = 0;
int c;frame = cvQueryFrame( capture );
if( !frame )
break;
//If is the first frame
if(!image){
//Create image header same as frame but with 1 channel to gray
image=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
bitImage=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
}
//Convert frame to gray and store in image
cvCvtColor(frame, image,CV_BGR2GRAY);//If is the first frame
if(!lastImage){//If no lastImage clone actual image;
lastImage=cvCloneImage(image);
}
if(!diffImage){
//Create image header same as frame but with 1 channel to gray
diffImage=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
}cvShowImage( “CamSub”, frame );
//Differences with actual and last image
cvAbsDiff(image,lastImage,diffImage);
//threshold image
cvThreshold(diffImage,bitImage,tr,255,CV_THRESH_BINARY);
//Change datas;
lastImage=cvCloneImage(image);cvShowImage(”CamSub 1″,bitImage);
c = cvWaitKey(10);
if( (char) c == 27 )
break;
}
29 Oct
Working in opencv with cameras is very easy, we only need a camera and our opencv libraries.
The structure that we store the camera link is CvCapture, here we store this link, then to get this link we need call to cvCaptureFromCAM function, this function need only one param, the index of the camera to be used. If there is only one camera or it does not matter what camera to use -1 may be passed.
Then this is our basic line to retrive our camera link
CvCapture* capture = cvCaptureFromCAM( 0 );
Then we only need get each frame we can capture with cam, to do this we can use the cvQuetyFrame passing as param our camera link and it return a IplImage* struct that we can show.
IplImage* frame = cvQueryFrame( capture );
With this easy lines we can get all frames we need from our camera.
27 Oct
To create a easy and valid percent bar or tipicall star bar we can use a schemma as you can see below.
With this html code:
<span class="percent"><span style="width:25%">25%</span></span>
And this stylesheet:
.percent{
display: block;
float: left;
background:url(images/percent.png) top left no-repeat;
height: 17px;
width:75px;
}
.percent span{
background:url(images/percent.png) bottom right no-repeat;
display:block;
float:left;
height:17px;
}
This is the result of our percent image:
36%45%89%66%
26 Oct
For 3d plot gnuplot use command splot.
splot sin(sqrt((x*x+y*y)))/sqrt(x*x+y*y) t “weaves”
We can add the style pm3d to add a gradient surface texture
splot sin(sqrt((x*x+y*y)))/sqrt(x*x+y*y) with pm3d t “weaves”
But you can see we need more resolution, then we must set more isosamples:
set isosamples 75,75
For more info go to gnuplot page
23 Oct
AWK is a general purpose programing language that is designed for processing text-based data. This unix command is very powerful and with it we can calculate the mean, min and max of a data stored in file.
data.txt:
10
20
50
100
200
500
awk command:
awk ‘{if(min==”"){min=max=$1}; if($1>max) {max=$1}; if($1< min) {min=$1}; total+=$1; count+=1} END {print total/count, min, max}’ data.txt
Result:
146.667 10 500
23 Oct
Hi, this is my new Blog, in wordpress, why? Because to maintain my old site and do it atractive need a lot of time, and I don’t have time, then i installed a wordpress blog in my little server to do the task of maintain the site more easy.
I want publish more post now…
21 Oct
In this tutorial we see how we can acces to OpenCV functions and use the images we process with it to use in our OpenGL program.
To use an OpenCV image (IplImage) and use it as an OpenGL textures we mus use this function.
int loadTexture_Ipl(IplImage *image, Ttexture *dest) {
unsigned char *pixels;if (dest==NULL) return -1;
dest->width=image->width;
dest->height=image->height;
pixels=(unsigned char*)image->imageData;dest->tmode=GL_REPLACE;
dest->minMode=GL_NEAREST;
dest->maxMode=GL_NEAREST;
dest->wrap_s=GL_REPEAT;
dest->wrap_t=GL_REPEAT;glGenTextures(1, &dest->texid);
setTexture(dest);glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 4, dest->width, dest->height,0, GL_BGR,
GL_UNSIGNED_BYTE, pixels);
return 0;
}
This function only get data image and store it as an image Texture.
We can get a camera image and use it to texture aplane, to do it we need a function to update the texture data, this we can do in OpenGL main loop or in glutiddleFunc as show
//En la funcion donde se actualizen los datos
frame = cvQueryFrame( capture );
if( frame ){
loadTexture_Ipl(frame, &texs[0]);
}