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.
Click on the thumbnail to view the actual FileNew dialog box.
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.
Click on the thumbnail to view the wizard step 3 of 4 dialog box.
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.
Click on the thumbnail to view the Project Dependencies settings dialog.
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
Click on the thumbnail to view the Work space browser.
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.
Now let start working with the library:
Double click on MyApplication.h and add the lines:
- - - Start cut'n paste - - -
#include "cv.h"
#include "HighGUI.h"
#define IMAGE_WIDTH 128
#define IMAGE_HEIGHT 128
#define IMAGE_CHANNELS 3
- - - End cut'n paste - - -
just below the "#include resource.h" line.
In the CVB right click on the CMyApplicationDlg class and add a member variable of type "IplImage*" and variable name "TheImage" let it be public.
Double click on the created variable in the CVB window and add the following lines below it but let them be protected:
- - - Start 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 - - -
// Create the IPL image
CvSize ImgSize;
ImgSize.width = IMAGE_WIDTH;
ImgSize.height = IMAGE_HEIGHT;
TheImage = cvCreateImage( ImgSize, IPL_DEPTH_8U, IMAGE_CHANNELS );
// Initialize the IPL image -actually not necessary
//Grayscale
if (TheImage->nChannels == 1)
{
float dx = (TheImage->width / 256.0f);
for ( int w = 0; w < TheImage->width; w++ )
for (int h = 0; h < TheImage->height; h++)
{
TheImage->imageData[ TheImage->height * w + h] = (char)(w / dx ); // Copy data to ipl
}
}
else if(TheImage->nChannels == 3) //The image is RGB
{
IplImage* Temp = cvCreateImage( ImgSize, IPL_DEPTH_8U, 1 );
int h,w;
float dx = (Temp->width / 256.0f) ;
for ( w = 0; w < Temp->width; w++ )
for (h = 0; h < Temp->height; h++)
Temp->imageData[ Temp->height * w + h] = (char)(w / dx ); // Copy data to ipl
cvSetImageCOI( TheImage, 1); //Choose the blue channel of interest
cvCopy(Temp,TheImage);
for ( w = 0; w < Temp->width; w++ )
for (h = 0; h < Temp->height; h++)
Temp->imageData[ Temp->height * w + h] = (char)(255 - w / dx ); // Copy green data to ipl
cvSetImageCOI( TheImage, 2); //Choose the green channel of interest
cvCopy(Temp,TheImage);
for ( w = 0; w < Temp->width; w++ )
for (h = 0; h < Temp->height; h++)
Temp->imageData[ Temp->height * w + h] = (char)(w / dx ); // Copy red data to ipl
cvSetImageCOI( TheImage, 3); //Choose the red channel of interest
cvCopy(Temp,TheImage);
cvReleaseImage(&Temp);
}
- - - End 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:
- - - Start cut'n paste - - -
//Initialize the BMP display buffer
bmi = (BITMAPINFO*)buffer;
bmih = &(bmi->bmiHeader);
memset( bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = IMAGE_WIDTH;
bmih->biHeight = -IMAGE_HEIGHT;
bmih->biPlanes = 1;
bmih->biCompression = BI_RGB;
bmih->biBitCount = 8 * TheImage->nChannels;
palette = bmi->bmiColors;
if (TheImage->nChannels == 1)
{
for( int i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
- - - End cut'n paste - - -
This creates a display buffer for drawing our IPL image
Click again on the CMyApplicationDlg class and add a member function of type void and called DisplayMyData, double click on it to get to the function and add the lines:
- - - Start cut'n paste - - -
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
SRCCOPY); // raster operation code
// Update Window, force View to redraw.
RedrawWindow(
NULL, // handle to window
NULL, // update rectangle
RDW_INVALIDATE // handle to update region
);
- - - End cut'n paste - - -
Couble click on the function OnPaint() and add the line:
- - - Start cut'n paste - - -
DisplayMyData();
- - - End cut'n paste - - -
in the else bracket part, before the line "CDialog::OnPaint();"
Click on InitInstance() in the CVB and add the following line after the two "// TODO:" to clean up the memory:
- - - Start cut'n paste - - -
cvReleaseImage(&dlg.TheImage);
- - - End cut'n paste - - -
Thats it! hit F5 to build and run your application!
Click Here to customize the project by loading a bmp file into the ipl structure.