Professional Documents
Culture Documents
Using OpenCV With MFC PDF
Using OpenCV With MFC PDF
Looking into the Yahoo OpenCV Community I noticed that a lot of the questions to the
message board, was related to how start working with the Library, this page will give a
newcomer a easy way to be able to use the library and a little tutorial on MFC using
Microsoft Visual Studio.
My background is embedded programming in C, not C++ or MFC so the structure and
methods used might not be "by the book", but I will try to explain my steps in a simple and
intuitive way, if you have any suggestion or corrections I will be very glad to receive them.
Before start the OpenCV must be downloaded and installed. I strongly advice to use the
default folder: "C:\Program Files\Intel\OpenCV" (some regional windows settings puts the
installed programs in a "localized" folder making it difficult to use downloaded visual studio
workspaces), remember that the library dll's must be in the system search path.
Open the project "CV.dsp" in the "C:\Program Files\Intel\opencv\cv\make" folder and do a
rebuild all -If any errors occur (ignore the warnings) do not continue with this tutorial. Solve
all problems before continuing!
If any problems occurs under the installation -do remember to read the FAQ before sending
any questions to the OpenCV Community. A good installation description can be found in
this message #11925. A lot of the questions from newcomers (and others) is also duplicates
of older questions -Use the search facility to find related questions, there are a great chance
that your question have been answered before (At the beginning of 2003 way over 10.000
messages have been submitted to the Community, your question/problem might be among
them).
Now Let's start:
In Visual Studio (VS) click on "File" and "New" to create a new project. Mark the "MFC
AppWizard (exe)" and specify the project name e.g. "MyApplication". Click Ok.
In the first step of the MFC AppWizard choose a Dialog Based application and specify the
language, click Next two times to get to step 3 of 4.
Click on the thumbnail to view the wizard step one dialog box.
In step 3 of 4 of the MFC App wizard set a mark in the radio button "As a static linked
library" in "How would you use the MFC Library?". Somehow the memory leaks is
avoided by this setting!!. Click Next, Finish and Ok.
The next step is to embed the OpenCV workspace into the project, it is described very well in
the FAQ. But I will give it another try here. Press Alt+F7 or click on "Project" in the menu bar
and then on "Settings" to get the "Project Settings" dialog. Mark the Project
"MyApplication". Choose "All Configuration" in the "Settings for" roll down menu.
Click on the tab "C/C++" and "Preprocessor" in the roll down menu.
In the "Additional include directories" write a comma separated list of include directories.
You can use either relative or absolute paths, write: "C:\Program
Files\Intel\opencv\cv\include,C:\Program Files\Intel\opencv\otherlibs\highgui".
Click on the thumbnail to view the Project Settings dialog box for include directories.
Still with "All Configuration" in the "Settings for" roll down menu. Choose the "Link" Tab
and "input" in the "Category" roll down menu.
Write, again a comma separated list of the relevant library paths: "C:\Program
Files\Intel\opencv\lib" in the "Additional Library Path" edit box.
Click on the thumbnail to view the Project Settings dialog box for additional libraries.
Now the Debug and release versions of the libraries must be specified.
With "Win32 Debug" marked in the "Settings for" roll down menu.
Choose the "Link" Tab and "input" in the "Category" roll down menu.
Write a space separated list of libraries: "cvd.lib HighGUId.lib" in the "Object/library
modules "edit box.
Change the "Settings for" roll down menu to "Win32 Release". Write "cv.lib HighGUI.lib" in
the "Object/library modules" edit box and press OK.
The OpenCV workspace is inserted in the workspace by choosing the "Project" menu and
then "Insert Project into Workspace". Browse to and select "C:\Program
Files\Intel\opencv\cv\make\cv.dsp" and "C:\Program
Files\Intel\opencv\otherlibs\highgui\highgui.dsp".
Specify the Dependencies by clicking on the menu point "Project" and then
"Dependencies...". Select "MyApplication" in the roll down menu and set a mark in the
"CV" and "HighGUI" box, then select "HighGUI" in the rolldown and set a mark in "CV" and
click on close.
The Work space browser can be used to browse the project by the
ClassView/ResourceView/FileView (CVB,RVB,FVB)panes and is a fast way to access the
code
Now right click on "MyApplication Files" in the FVB and roll down to "Set as active
project" to specify this project as the one to build and debug on.
#include "cv.h"
#include "HighGUI.h"
#define IMAGE_WIDTH 128
#define IMAGE_HEIGHT 128
#define IMAGE_CHANNELS 3
- - - End cut'n paste - - -
BITMAPINFO* bmi;
BITMAPINFOHEADER* bmih;
RGBQUAD* palette;
unsigned int buffer[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256];
- - - End cut'n paste - - -
Double click on OnInitDialog() again in the CVB and add the following lines after the "//
TODO: Add extra initialization here" comment:
- - - Start cut'n paste - - -
This creates a IPL image and initializes the image data to a grayscale ramp function, black in
top and white in bottom.
Just below the code inserted above insert the following code:
CPaintDC dc(this);
CDC* pDC = &dc;
int res = StretchDIBits(
pDC->GetSafeHdc(), //dc
0, //x dest
0, //y dest
int(IMAGE_WIDTH), //x dest dims
int(IMAGE_HEIGHT), //y dest dims
0, // src x
0, // src y
IMAGE_WIDTH, // src dims
IMAGE_HEIGHT, // src dims
TheImage->imageData, // array of DIB bits
(BITMAPINFO*)bmi, // bitmap information
DIB_RGB_COLORS, // RGB or palette indexes
DisplayMyData();
- - - End cut'n paste - - -
cvReleaseImage(&dlg.TheImage);
- - - End cut'n paste - - -
This creates and adds two new files to the project work space, "MyIplClass.ccp" and
"MyIplClass.h" can be seen in the FVB, with constructor MyIplClass() destructor
~MyIplClass() in the CVB.
Double click on "MyApplication.h" and add the line:
- - - Start cut'n paste - - -
#include "MyIplClass.h"
- - - End cut'n paste - - -
Below the "include resource.h" and move the other include directives to "MyIplClass.h"
(double click on FVB to get there) just before the class declaration also do a include of
ipl.h:
- - - Start cut'n paste - - -
#include "cv.h"
#include "HighGUI.h"
#define IMAGE_WIDTH 128
#define IMAGE_HEIGHT 128
- - - End cut'n paste - - -
Right click on "MyIplClass" in the CVB and add a public member variable "IplImage*"
called "m_Ipl". Double click on the constructor "MyIplClas()" to get to the code and add
the following lines:
- - - Start cut'n paste - - -
And double click on the destructor ~MyIplClass() in the CVB and add the code:
- - - Start cut'n paste - - -
cvReleaseImage(&m_Ipl);
- - - End cut'n paste - - -
Right click on "MyIplClass" in the CVB and add a member function called
GetIplData(IplImage* ipl) and of type void. Double click on the new function and add
the line:
- - - Start cut'n paste - - -
Right click on "MyIplClass" in the CVB and add a member function called
LoadBMP(CString FileName) of type void with the lines:
- - - Start cut'n paste - - -
// Do it the easy way with HighGUI BMP, DIB,JPEG, JPG, JPE,PNG,PBM, PGM,
PPM, SR, RAS, TIFF, TIF
// m_Ipl = cvLoadImage( FileName, 0);
// Or the hard way:
BOOL ok = TRUE;
CFile SrcFile;
char *ReadBuffer; // Pointer to read buffer
char *OutputBuffer; // Pointer to output buffer
BITMAPFILEHEADER BmpFileHeader;
unsigned int BmpHeadSize;
char *BmpHeadPtr;
BITMAPINFOHEADER *BmpInfoPtr;
int i;
if ( !SrcFile.Open( FileName, ( CFile::modeRead | CFile::typeBinary), NULL ) )
{
AfxMessageBox("Could not open file");
}
// Read the BMP File header
ok = ok && ( SrcFile.Read( &BmpFileHeader, sizeof( BmpFileHeader )) ==
sizeof( BmpFileHeader ));
// Test settings in BMP file header.
ok = ok && ( BmpFileHeader.bfType == 'MB' ); /* Bitmap file */
// Find the size of the rest of the BMP header
BmpHeadSize = BmpFileHeader.bfOffBits - sizeof( BmpFileHeader );
// Allocate space for the rest of the BMP header
BmpHeadPtr = new char[ BmpHeadSize ];
ok = ok && ( BmpHeadPtr != NULL );
// Read the rest of the BMP header - Info part and color table part
ok = ok && ( SrcFile.Read( BmpHeadPtr, BmpHeadSize ) == BmpHeadSize );
// Make a cast to the type we think is the Info part of the header
BmpInfoPtr = ( BITMAPINFOHEADER* ) BmpHeadPtr;
// Test settings in BMP info header.
ok = ok && ( BmpInfoPtr->biSize == sizeof( BITMAPINFOHEADER ) );
ok = ok && ( BmpInfoPtr->biWidth == IMAGE_WIDTH );
ok = ok && ( BmpInfoPtr->biHeight == IMAGE_HEIGHT );
ok = ok && ( BmpInfoPtr->biPlanes == 1 );
ok = ok && ( BmpInfoPtr->biBitCount == 8 );
// Use this line if the bitmap is 24 bit
// ok = ok && ( BmpInfoPtr->biBitCount == 24 );
ok = ok && ( BmpInfoPtr->biCompression == BI_RGB );
ok = ok && ( BmpInfoPtr->biSizeImage == IMAGE_HEIGHT * IMAGE_WIDTH );
// Use this line if the bitmap is 24 bit
//ok = ok && ( BmpInfoPtr->biSizeImage == IMAGE_HEIGHT * IMAGE_WIDTH *
3 );
if (ok)
{
// Allocate a buffer for destination data
ReadBuffer = new char[ BmpInfoPtr->biSizeImage ];
// Read the BMP data from the source file
SrcFile.Read( ReadBuffer, BmpInfoPtr->biSizeImage );
// Allocate a buffer for upside down corrected data
OutputBuffer = new char[ BmpInfoPtr->biSizeImage ];
for(i = 0; i < IMAGE_HEIGHT; i++)
{
memcpy(&OutputBuffer[(IMAGE_HEIGHT - i - 1) * IMAGE_WIDTH],
&ReadBuffer[i * IMAGE_WIDTH], IMAGE_WIDTH);
// Use this line if the bitmap is 24 bit
// memcpy(&OutputBuffer[(IMAGE_HEIGHT - i - 1) * IMAGE_WIDTH*3],
&ReadBuffer[i * IMAGE_WIDTH*3], IMAGE_WIDTH*3);
}
// Now copy the read data to the IPL structure
memcpy(m_Ipl->imageData, OutputBuffer, BmpInfoPtr->biSizeImage );
delete OutputBuffer;
delete ReadBuffer;
}
else
{
AfxMessageBox("Wrong image size");
}
delete BmpHeadPtr;
SrcFile.Close();
- - - End cut'n paste - - -
Now click on the RVB (Resource View Browser), then on "MyApplication resources"
then double click on "ID_MYAPPLICATION_DIALOG" this brings you to the Dialog
Editor Window.
Drag a button from the tool line to a corner of your dialog, right click on the button and
then click on the "Properties"to be able to edit the properties for this control. In the
"ID:" field write "IDC_PROCESS" and in the "Caption" field write "Process" close the
properties window.
Double click on the created button to make a function named "OnProcess" and get to
the code part of this function. Add the lines:
Thats it hit F5 to build and run, when the "Process" button is pressed the ring appears.
Using
OpenCV
with
MFC
IplImage *IplTmp1,*IplTmp2,*IplTmp3;
IplTmp1 = cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),
IPL_DEPTH_8U, 1 );
IplTmp2 = cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),
IPL_DEPTH_8U, 1 );
IplTmp3 = cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),
IPL_DEPTH_8U, 1 );
int ThressValue = 90;
float alpha = 3;
float beta = 5;
float gamma = 2;
CvSize win;
CvTermCriteria criteria;
int jumpPoint;
CvPoint *WholePointArray;
CvPoint *PointArray;
const int NUMBER_OF_SNAKE_POINTS= 50;
PointArray = (CvPoint *)malloc(NUMBER_OF_SNAKE_POINTS *
sizeof(CvPoint));
cvCopyImage( m_Ipl,IplTmp3); //IplTmp3 is the image to draw temp results to
cvCopyImage( m_Ipl, IplTmp1);//(src,dst) copy to Working ipl image (IplTmp1 and
IplTmp2 is working containers)
// Make a average filtering
cvSmooth(IplTmp1,IplTmp2,CV_BLUR,31,15);
// iplBlur( IplTmp1, IplTmp2, 31, 31, 15, 15); //Don't use IPL
//Do a threshold
cvThreshold(IplTmp2,IplTmp1,ThressValue,255,CV_THRESH_BINARY);
//iplThreshold(IplTmp2,IplTmp1,ThressValue); // DistImg is thressholded image
(IplTmp1)//Don't use IPL
// expand the thressholded image of ones -smoothing the edge.
//And move start position of snake out since there are no ballon force
cvDilate( IplTmp1, IplTmp2, NULL, 3);
//Find the contours
CvMemStorage *storage;
CvSeq* contour = NULL;
storage = cvCreateMemStorage (0);
cvFindContours( IplTmp2,storage, &contour,sizeof(CvContour), CV_RETR_LIST,
CV_CHAIN_APPROX_NONE );
//Run through the found coutours
while( contour != NULL )
{
if ( contour ->total >= NUMBER_OF_SNAKE_POINTS)
{
cvSmooth(m_Ipl,IplTmp2,CV_BLUR,7,3);
//iplBlur( m_Ipl, IplTmp2, 7, 7, 3, 3); // Put blured image in TempImg//Don't
use IPL
WholePointArray = (CvPoint *)malloc(contour->total * sizeof(CvPoint));
cvCvtSeqToArray(contour, WholePointArray, CV_WHOLE_SEQ); //Copy
the contour to a array
Then go to the OnProcess() through the CVB and add following line just after the line
"Img->LoadBMP(filename);"
- - - Start cut'n paste - - -
Img->ProcessIpl();
- - - End cut'n paste - - -
Thats it hit F5 to build and run, when the "Process" button is pressed the ring appears
with a superimposed "snake".
#include "tiff.h"
#include "tiffio.h"
- - - End cut'n paste - - -
In the CVB right click on "MyIplClass" and add the void member function
"LoadTiff(CString FileName)" and add the following code to the function body:
- - - Start cut'n paste - - -
int npixels;
unsigned int w,h,Width,Height;
unsigned long* TIFFImageData;
TIFF* tif= TIFFOpen(FileName, "r"); // Open filename
if (tif!=NULL)
{
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &Width); // get size
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &Height);
if ( (Width == IMAGE_WIDTH) ||
(Height == IMAGE_HEIGHT) )
{
npixels = Width * Height;
TIFFImageData = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); //
allocate temp memory
if (TIFFImageData == NULL)
m_Ipl = NULL;
if ( !TIFFReadRGBAImage(tif, Width, Height, TIFFImageData, 0) )
m_Ipl = NULL;
for ( w = 0; w < Width; w++ )
for (h = 0; h < Height; h++)
m_Ipl->imageData[Height*w + h]=(char)TIFFImageData[Height*w +
h]; // Copy data to ipl
_TIFFfree(TIFFImageData); // Release temp memory
}
else
{
AfxMessageBox("Wrong size of tiff image");
}
TIFFClose(tif);
}
- - - End cut'n paste - - -
Now find a program to convert ring.bmp to a tiff file e.g. Paint Shop Pro and save it as
"ring.tif" in the same folder, go to "OnProcess()" with the CVB and change the lines
with the file name and load function to:
- - - Start cut'n paste - - -
Thats it hit F5 to build and run, when the "Process" button is pressed the ring appears
with a superimposed "snake".
The interesting fact is that the final snake have another appearance compared with the
result from the bmp-file.
The step one here and two here must have been run through before this section can be
used.
Press Alt+F7 or click on "Project" in the menu bar and then on "Settings" to get the "Project
Settings" dialog. Mark the Project "MyApplication". Choose "All Configuration" in the
"Settings for" roll down menu.
Click on the tab "C/C++" and "Preprocessor" in the roll down menu.
In the "Additional include directories" add "C:\Program Files\Matrox Imaging\mil\include"
to the comma separated list.
Still with "All Configuration" in the "Settings for" roll down menu. Choose the "Link" Tab
and "input" in the "Category" roll down menu and add "C:\Program Files\Matrox
Imaging\mil\library\winnt\msc\dll" to the comma separated "Additional Library path".
Add "mil.lib" to the space separated "Object/library modules" list.
Open MyIplClass.h and add the following include directive under the others.
- - - Start cut'n paste - - -
#include "mil.h"
- - - End cut'n paste - - -
Double click on TheImage member variable of CMyApplicationDlg in the CVB and add the
following code below it:
- - - Start cut'n paste - - -
Doubleclick on OnInitDialog() and add the following code to allocate and initialize the Matrox
Meteor Framegrabber before the "return TRUE;" statement.
// Allocate an application
MappAlloc(M_DEFAULT,&MilApplication);
// Allocate a system
MsysAlloc(M_SYSTEM_SETUP,M_DEF_SYSTEM_NUM,M_COMPLETE,&MilSystem);
// Inquire number of digitizers available on the system
MsysInquire(MilSystem,M_DIGITIZER_NUM,&NumberOfDigitizer);
// Digitizer is available
if (NumberOfDigitizer)
{
// Allocate a digitizer
MdigAlloc(MilSystem,M_DEFAULT,M_CAMERA_SETUP,M_DEFAULT,&MilDigitizer
);
// Stop live grab when window is disable
MsysControl(MilSystem,M_STOP_LIVE_GRAB_WHEN_DISABLED,M_ENABLE);
// Inquire digitizer informations
MdigInquire(MilDigitizer,M_SIZE_X,&DigSizeX);
MdigInquire(MilDigitizer,M_SIZE_Y,&DigSizeY);
MdigInquire(MilDigitizer,M_SIZE_BAND,&Band);
MbufAlloc2d(MilSystem, DigSizeX, DigSizeY,8L+M_UNSIGNED,
M_IMAGE+M_GRAB, &MilImage);
MdispAlloc(MilSystem, M_DEF_DISPLAY_NUM, M_DEF_DISPLAY_FORMAT,
M_WINDOWED, &MilDisplay);
if (DigSizeX > M_DEF_IMAGE_SIZE_X_MAX)
DigSizeX = M_DEF_IMAGE_SIZE_X_MAX;
if (DigSizeY > M_DEF_IMAGE_SIZE_Y_MAX)
DigSizeY = M_DEF_IMAGE_SIZE_Y_MAX;
}
// Digitizer is not available
else
{
SizeX = M_DEF_IMAGE_SIZE_X_MIN;
SizeY = M_DEF_IMAGE_SIZE_Y_MIN;
Band = M_DEF_IMAGE_NUMBANDS_MIN;
}
// Initialize the state of the grab
GrabIsStarted = FALSE;
In the ResourceView Browser click on MyApplication resources then Dialog and finally
double click on IDD_MYAPPLICATION_DIALOG to be able to edit the dialog. Resize the
dialog to a size fitting the video output and remember also to adjust the two #defines
IMAGE_WIDTH and IMAGE_HEIGHT. Add a button to the lower right part of the dialog
-Right click on it and through properties change the ID: to "IDC_GRAB" and the Caption to
"Grab". Close the Properties dialog box and double click on the new button to add a function
called "OnGrab" Press OK to get to the code. Paste the following into the function:
- - - Start cut'n paste - - -
In the function CMyApplicationDlg::OnPaint() change the code in the else part to:
- - - Start cut'n paste - - -
if (!GrabIsStarted)
DisplayMyData(); //Only redraw iplimage if not grabbing
CDialog::OnPaint();
- - - End cut'n paste - - -
Add a function "SetIplData(IplImage *ipl)" returning void, to the class MyIplClass. and add
the code:
- - - Start cut'n paste - - -
Thats it! hit F5 to build and run your application! Press the Grab button to start grabbing, then
on Stop and on Process to use OpenCV on the grabbed image.
Press on the link to go back to the start go the tutorial.
I finally bought a USB camera and on this page I will show how to acquire and process
images from an USB camera.
Before continuing with this guide be sure that the installation of the USB camera is
correct - test the installation with e.g the HMMDemo application. Do not start with this
guide before you your camera are working properly with the examples in OpenCV.
The step one here must have been run through before this section can be used.
Add the cvcam.dsp project into your workspace by pressing "Project", "Insert Project
into workspace" and browse to the folder "C:\Program
Files\Intel\opencv\otherlibs\cvcam\make_win", remember to right click on the project
MyApplication and make it the the active project again. Click on "Project" then on
"Dependencies" and with "MyApplication" active put an mark in the "cvcam" box
and press OK.
Press Alt+F7 or click on "Project" in the menu bar and then on "Settings" to get the
"Project Settings" dialog. Mark the Project "MyApplication". Choose "All
Configuration" in the "Settings for" roll down menu.
Click on the tab "C/C++" and "Preprocessor" in the roll down menu.
In the "Additional include directories" add ",C:\Program
Files\Intel\opencv\otherlibs\cvcam\include" to the comma separated list.
With "Win32 debug" active in the "Settings for" roll down menu. Choose the "Link"
Tab and "input" in the "Category" roll down menu.
Add "cvcamd.lib" to the space separated "Object/library modules" list.
Add "cvcam.lib" to the space separated "Object/library modules" list with "Win32
Release" active.
Add "vfw32.lib" to the space separated "Object/library modules" list with "All
Configurations" active.
Add the line "#include "cvcam.h" " below your other include directives either in
MyApplication.h or MyIplClass.h if this file exists.
Add the following line just below the include directive to make an global function:
- - - Start cut'n paste - - -
In the CVB double click on the variable buffer and ad the following variables:
- - - Start cut'n paste - - -
HWND hWnd;
int cvcamone;
BOOL GrabIsStarted;
int ncams;
- - - End cut'n paste - - -
In the CVB double click on OnInitDialog() and add the code before the "return TRUE"
command.
- - - Start cut'n paste - - -
GrabIsStarted = FALSE;
hWnd = AfxGetMainWnd()->m_hWnd;
ncams = cvcamGetCamerasCount(); // returns the number of available cameras in
the system
cvcamSetProperty(0, CVCAM_PROP_ENABLE, &cvcamone); // Selects the 1-st
found camera
cvcamSetProperty(0, CVCAM_PROP_RENDER, &cvcamone); // We'll render
stream from this source
cvcamSetProperty(0, CVCAM_PROP_WINDOW, &hWnd); // Selects this window
for video rendering
cvcamSetProperty(0, CVCAM_PROP_CALLBACK, LiveProcess); // this callback
will process every frame
cvcamInit();
- - - End cut'n paste - - -
pButton->SetWindowText("Stop");
}
else
{
cvcamStop( );
GrabIsStarted = FALSE;
pButton = GetDlgItem(IDC_USB_GRAB);
pButton->SetWindowText("USB Grab");
}
- - - End cut'n paste - - -
Double click on OnPaint() in the CVB and add the following code in the else statement.
- - - Start cut'n paste - - -
if(GrabIsStarted != TRUE)
DisplayMyData();
CDialog::OnPaint();
- - - End cut'n paste - - -
In the FVB double click on MyApplication.ccp to open up this file and add the code
after the first "#endif", this code does the real time processing of the acquired images
from the USB camera.
- - - Start cut'n paste - - -
cvcamExit();
- - - End cut'n paste - - -
Thats it! hit F5 to build and run your application! Press the Grab button to start
grabbing, then on Stop. The callback function LiveProcess() uses OpenCV to do real
time processing on the Images acquired from the USB camera.
Well, now we have a hole through, lets do something more interesting than drawing
blue lines on the grabbed images:
At this url I found some image filters I would like to try.
In the file MyApplication.h add the include directive "#include "math.h"" after the other
include directives, and add the define "#define PI 3.1415926535f" under the other
defines then add the following line after the "void LiveProcess(IplImage *image);"
- - - Start cut'n paste - - -
void InitMatrix();
unsigned int* Matrix;
- - - End cut'n paste - - -
Go to the implementation of the function LiveProcess and add another global function
below it:
- - - Start cut'n paste - - -
void InitMatrix()
{
Matrix = new unsigned
int[IMAGE_WIDTH*IMAGE_HEIGHT*IMAGE_CHANNELS];
int halfH = IMAGE_HEIGHT/2;
int halfW = IMAGE_WIDTH/2;
float MaxRad = sqrt(halfH*halfH+halfW*halfW);
int DistH,DistW,NewW,NewH,h,w;
float DistRad,NewRad,Angle,NewAngle,factor,factor2;
factor = 1;
IplImage* Temp = cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),
IPL_DEPTH_8U, IMAGE_CHANNELS );
int index=0;
for( h =0;h < IMAGE_HEIGHT; h++ )
{
//factor2 = MaxRad*PI;
//NewAngle = Angle + DistRad/factor2;
//NewAngle = DistRad*IMAGE_HEIGHT/MaxRad;
//NewRad = Angle*IMAGE_WIDTH/(2*PI);
factor = 0.5;
//NewRad = DistRad*DistRad/MaxRad;//Fisheye
// This we try:
NewRad = sqrt(DistRad*MaxRad);//Caricature
// This is the transformation
NewW = halfW + floor(factor * NewRad * cos(NewAngle));
NewH = halfH - floor(factor * NewRad * sin(NewAngle));
// End of transformation
if(NewW < 0 )
NewW = 0;
if(NewW > IMAGE_WIDTH-1)
NewW = IMAGE_WIDTH-1;
if(NewH < 0)
NewH = 0;
if(NewH > IMAGE_HEIGHT-1)
NewH = IMAGE_HEIGHT-1;
for(index = 0; index < IMAGE_CHANNELS;index++)
Matrix[(h*IMAGE_WIDTH+w)* IMAGE_CHANNELS+index] =
(NewH*IMAGE_WIDTH + NewW)* IMAGE_CHANNELS+index ;
}
}
}
- - - End cut'n paste - - -
InitMatrix();
- - - End cut'n paste - - -
int i,j;
assert (image);
for(int index = 0;index < image->imageSize; index++ )
Temp->imageData[ index ]= image1->imageData[ Matrix[index] ];
memcpy(image1->imageData, Temp->imageData, image1->imageSize );
cvReleaseImage(&Temp);
- - - End cut'n paste - - -
delete(Matrix);
- - - End cut'n paste - - -
Thats it! hit F5 to build and run your application, a pretty funny grab shows up, feel free
to experiment with other transformations.