一、将C代码生成DLL
首先新建一个项目,选择 win32项目,如下图所示:
点击确定,下一步后,选择 DLL,导出符号,如下图所示:
点击完成,就可以将自己添加想要封装成DLL的代码。
如:我想要将利用opencv查找人脸的代码,封装成DLL,在C#下调用
首先,我在DllTest.h文件中添加函数:
extern "C" DLL_FACE_API HBITMAP FindFaceForCSharp(int EnableCamera,char str[50],int *CooIndex,int* width, int* height,
double scale_factor,int min_neighbors,int min_size);
然后在.cpp中实现函数:
//@PARAM:EnableCamera:if true open the camera;
//@PARAM:*CoorIndex:coordination array, a[0] index total number of faces;then x point, y point width, height and loop
//@PARAM:*width :return picture width
//@PARAM:*height: return picture height
HBITMAP FindFaceForCSharp(int EnableCamera,char Videoname[50],int *CooIndex,int* width, int* height,double scale_factor,int min_neighbors,int min_size)
{
if (EnableCamera)
{
static int active=0;
active++;
int i=0;
int j=0;
if(active==1)
{
if(EnableCamera==1)
m_Video=cvCaptureFromCAM(0);
else
m_Video=cvCaptureFromFile(Videoname);
cascade1=(CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt2.xml");
cascade2=(CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml");
cascade3=(CvHaarClassifierCascade*)cvLoad("haarcascade_profileface.xml"); // detect face datafile
}
if (!m_Video)
{
fprintf(stderr,"can not open camera\n");
return NULL;
}
if(Frame=cvQueryFrame(m_Video))
{
*width=Frame->width;
*height=Frame->height;
CvRect FaceRect[100];// the temp face rect
CvPoint pt[100];// the before face center point
for (int i=0;i<100;i++)
{
FaceRect[i].x=0;FaceRect[i].y=0;
FaceRect[i].width=0;FaceRect[i].height=0;
pt[i].x=0;pt[i].y=0;
}
//Ç°Ò»Ö¡ÈËÁ³µÄÖÐÐÄ
int TotalBef=0;
if (CooIndex[0]>0)
{
TotalBef=CooIndex[0];
for (i=1,j=0;jorigin==1)
cvFlip(image,NULL,0); //////////////////////////////////////////
int facetotal=0;// face count
//find skin
IplImage *Skin=cvCreateImage(cvGetSize(Frame),8,1);
{
int x,y;
int b,g,r;
float Y,Cr,Cb;
cvZero(Skin);
for (x=0;xheight;x++)
for (y=0;ywidth;y++)
{
b=((uchar*)(Frame->imageData+Frame->widthStep*x))[y*3];
g=((uchar*)(Frame->imageData+Frame->widthStep*x))[y*3+1];
r=((uchar*)(Frame->imageData+Frame->widthStep*x))[y*3+2];
Y=(float)(0.299*r+0.587*g+0.114*b);
Cr=(float)(0.5*r-0.419*g-0.081*b+128.0);
Cb=(float)(-0.169*r-0.331*g+0.5*b+128.0);
if (Cr/Cb>1.05)
{
if ((Cr>132&& Cr<178)&&(Cb>87 &&Cb<126))
{
((uchar*)(Skin->imageData+Skin->widthStep*x))[y]=255;
}
}
}
cvSmooth(Skin,Skin,CV_BLUR,3,3);
cvErode(Skin,Skin,0,1);
cvDilate(Skin,Skin,0,1);
}
if(Skin->origin==0)
cvFlip(Skin,NULL,0);//////////////////////////////////////////////////////////////////////
// cvNamedWindow("skin",1);
// cvShowImage("skin",Skin);
//detect face
{
CvRect bndRect = cvRect(0,0,0,0);
IplImage* binal_copy=cvCloneImage(Skin);
double scale = 1.3;
double bndArea=0;
int i=0;
int flags=8;
int maxradius=0;
CvMemStorage* storage_face=cvCreateMemStorage(0);
CvSeq* contour;
cvFindContours( binal_copy, storage_face, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
for( ; contour != 0; contour = contour->h_next )
{
bndRect=cvBoundingRect(contour,0);
bndArea=fabs(cvContourArea(contour,CV_WHOLE_SEQ));
if (bndRect.width<10||bndRect.height<10/*||bndArea<100||(double)bndRect.width/bndRect.height>2.5||(double)bndRect.width/bndRect.height<0.4*/)
{
continue;
}
if (bndRect.heightheight/5&&bndRect.widthwidth/5)
{
bndRect = cvRect(bndRect.x - bndRect.width/4, bndRect.y - bndRect.height/4
, bndRect.width*1.5, bndRect.height*1.5);
}
if (bndRect.x<0||bndRect.y<0||bndRect.width<0||bndRect.height<0)
{
bndRect=cvBoundingRect(contour,0);
}
cvSetImageROI(image, bndRect);
cvSetImageROI(Skin,bndRect);
IplImage* small_img = cvCreateImage( cvSize( cvRound (image->roi->width/scale),cvRound (image->roi->height/scale)),8, 3 );
cvResize( image, small_img, CV_INTER_LINEAR );
//cvEqualizeHist( small_img, small_img );
IplImage *Img_B=cvCreateImage(cvGetSize(small_img),8,1);
IplImage *Img_R=cvCreateImage(cvGetSize(small_img),8,1);
IplImage *Img_G=cvCreateImage(cvGetSize(small_img),8,1);
cvSplit(small_img,Img_B,Img_R,Img_G,NULL);
cvResetImageROI( image );
if( cascade1&&cascade2)
{
CvSeq* faces = cvHaarDetectObjects( Img_R, cascade1, storage_face,
scale_factor,min_neighbors, 0/*CV_HAAR_DO_CANNY_PRUNING*/,cvSize(min_size, min_size) );
if (!faces->total)
{
faces=cvHaarDetectObjects(small_img,cascade2,storage_face,1.1,2,0,cvSize(50,50));
}
if (!faces->total)
{
faces=cvHaarDetectObjects(small_img,cascade3,storage_face,1.2,3,0,cvSize(50,50));
}
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect *r = (CvRect*)cvGetSeqElem( faces, i);
CvRect realR=cvRect(0,0,0,0);
realR.x=r->x*scale+bndRect.x;
realR.y=image->height-(r->y*scale+bndRect.y);
realR.width=r->width*scale;
realR.height=r->height*scale;
realR.y=realR.y-realR.height;
//½«Öظ´Ñ¡ÔñÔÚÒ»¸öÈËÁ³ÇøÓòµÄ¾ØÐÎÈ¥µô
bool exist=false;
for (int j=0;j0)
{
for ( i=0;ibmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = Frame->width;
bmi->bmiHeader.biHeight = Frame->height;
bmi->bmiHeader.biPlanes = 1/*Size*/;
bmi->bmiHeader.biBitCount = Frame->nChannels * Frame->depth;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biSizeImage = Frame->width*Frame->height*1;
bmi->bmiHeader.biClrImportant =0 ;
switch(Frame->nChannels * Frame->depth)
{
case 8 :
for(i=0 ; i < 256 ; i++)
{
bmi->bmiColors[i].rgbBlue = i;
bmi->bmiColors[i].rgbGreen= i;
bmi->bmiColors[i].rgbRed= i;
}
break;
case 32:
case 24:
((DWORD*) bmi->bmiColors)[0] = 0x00FF0000; /* red mask */
((DWORD*) bmi->bmiColors)[1] = 0x0000FF00; /* green mask */
((DWORD*) bmi->bmiColors)[2] = 0x000000FF; /* blue mask */
break;
}
hBmp = ::CreateDIBSection(hDC,bmi,DIB_RGB_COLORS,NULL,0,0);
SetDIBits(hDC,hBmp,0,Frame->height,Frame->imageData,bmi,DIB_RGB_COLORS);
::DeleteDC(hDC);
return hBmp;
}
}
}
else
{
cvReleaseCapture(&m_Video);
m_Video=NULL;
}
return NULL;
}
编译后就可以在Debug或release下找到DLL了
二、在C#中调用DLL
将DLL拷贝到工程目录下,并添加导入代码:
[DllImport("DLL_face120203.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "FindFaceForCSharp")]
unsafe public static extern IntPtr FindFaceForCSharp(int EnableCamera, char []Videoname, int* CooIndex, ref int width,
ref int height, double scale_factor, int min_neighbors, int min_size,ref int count,bool validity);
完成上述操作后,就可以在C#下调用DLL封装的函数了。
如:
private void ProcessFrame(object sender, EventArgs arg)
{
#region unsafe module
unsafe
{
int EnableCamera =2; //为1时开启摄像头,屏蔽读视频文件; 为2时关闭摄像头,开始读视频文件
string file = Application.StartupPath + "\\PicNew\\test1.avi";
char[] videoName = file.ToCharArray();
int ImgWidth = 0;
int ImgHeight = 0;
int* Coordination = stackalloc int[500];
double min_factor = 1.05;
int min_neighbor = 3;
int size = 37;
/*************************************************************************************************/
/* EnableCamera: 摄像头的状态 1:打开摄像头,2:打开视频 */
/* Videoname:视频文件 */
/* Coordination: Coordination[0]表示有多少个人脸;Coordination[1]第一个人脸的X坐标, */
/* Coordination[2],第一个人脸Y坐标;Coordination[3],第一个人脸宽度;Coordination[4]; */
/* 第一个人脸高度;Coordination[5]第五个是跟踪事件为1为跟踪,为0为不跟踪。 */
/* Coordination[1+5*i]第(i-1)个人脸的X坐标; Coordination[2+5*i]第(i-1)个人脸Y坐标; */
/* Coordination[3+5*i],第(i-1)个人脸宽度; Coordination[4+i],第(i-1)个人脸高度; */
/* ImgWidth:图像宽度 */
/* ImgHeight:图像高度 */
/* min_factor:DLL中cvHaarDetectObjects的搜索窗口的比例系数 */
/* min_neighbor:DLL中cvHaarDetectObjects构成检测目标的相邻矩形的最小个数 */
/* size:DLL中cvHaarDetectObjects检测窗口的最小尺寸 */
/*************************************************************************************************/
if (EnableCamera == 2)
{
if (number
IntPtr hBitmap = FindFaceForCSharp(EnableCamera, videoName, Coordination, ref ImgWidth,
ref ImgHeight, min_factor, min_neighbor, size, ref count, validity);
#region switch (Coordination[0])
switch (Coordination[0])
{
case 0:
{
for (int i = 0; i < 3; i++)
{
faceintX[i] = 0;
faceintY[i] = -130;
}
break;
}
case 1:
{
faceintX[0] = Coordination[1];
faceintY[0] = 480 -Coordination[2];
faceintX1 = faceintX[0];
faceintY1 = faceintY[0];
faceintX2 = 0;
faceintY2 = 0;
faceintX3 = 0;
faceintY3 = 0;
faceintW[0] = Coordination[3];
faceintH[0] = Coordination[4];
faceintX[1] = 0;
faceintY[1] = 0;
faceintX[2] = 0;
faceintY[2] = 0;
label1.Text = Coordination[5].ToString();
Flag1 = Coordination[5];
break;
}
case 2:
{
faceintX[2] = 0;
faceintY[2] = -130;
faceintX[0] = Coordination[1];
faceintY[0] = 480 - Coordination[2];
faceintX1 = faceintX[0];
faceintY1 = faceintY[0];
faceintW[0] = Coordination[3];
faceintH[0] = Coordination[4];
faceintX[1] = Coordination[6];
faceintY[1] = 480 - Coordination[7];
faceintX2 = faceintX[0];
faceintY2 = faceintY[0];
faceintX3 = 0;
faceintY3 = 0;
faceintW[1] = Coordination[8];
faceintH[1] = Coordination[9];
faceintX[2] = 0;
faceintY[2] = 0;
label2.Text = Coordination[10].ToString();
Flag2 = Coordination[10];
break;
}
case 3:
{
faceintX[0] = Coordination[1];
faceintY[0] = 480 - Coordination[2];
faceintX1 = faceintX[0];
faceintY1 = faceintY[0];
faceintW[0] = Coordination[3];
faceintH[0] = Coordination[4];
faceintX[1] = Coordination[6];
faceintY[1] = 480 - Coordination[7];
faceintX2 = faceintX[0];
faceintY2 = faceintY[0];
faceintW[1] = Coordination[8];
faceintH[1] = Coordination[9];
faceintX[2] = Coordination[11];
faceintY[2] = 480 - Coordination[12];
faceintW[2] = Coordination[13];
faceintH[2] = Coordination[14];
faceintX3 = faceintX[0];
faceintY3 = faceintY[0];
label3.Text = Coordination[15].ToString();
Flag3 = Coordination[15];
break;
}
}
#endregion
Bitmap bitmap = Bitmap.FromHbitmap(hBitmap);
captureImageBox.Image = bitmap;
DeleteObject(hBitmap);
GC.Collect();
number++;
}
}
else
if(EnableCamera==1)
{
IntPtr hBitmap = FindFaceForCSharp(EnableCamera, videoName, Coordination, ref ImgWidth, ref ImgHeight,
min_factor, min_neighbor, size, ref count, validity);
#region switch (Coordination[0])
switch (Coordination[0])
{
#region
//case 0:
// {
// for (int i = 0; i < 3; i++)
// {
// faceintX[i] = 0;
// faceintY[i] = -130;
// }
// break;
// }
//case 1:
// {
// for (int i = 0; i < 3; i++)
// {
// faceintX[i] = 0;
// faceintY[i] = -130;
// }
// faceintX[0] = Coordination[1];
// faceintY[0] = 480 - Coordination[2];
// faceintW[0]=Coordination[3];
// faceintH[0]=Coordination[4];
// break;
// }
//case 2:
// {
// faceintX[2] = 0;
// faceintY[2] = -130;
// faceintX[0] = Coordination[1];
// faceintY[0] = 480 - Coordination[2];
// faceintW[0] = Coordination[3];
// faceintH[0] = Coordination[4];
// faceintX[1] = Coordination[6];
// faceintY[1] = 480 - Coordination[7];
// faceintW[1] = Coordination[8];
// faceintH[1] = Coordination[9];
// break;
// }
//case 3:
// {
// faceintX[0] = Coordination[1];
// faceintY[0] = 480 - Coordination[2];
// faceintW[0] = Coordination[3];
// faceintH[0] = Coordination[4];
// faceintX[1] = Coordination[6];
// faceintY[1] = 480 - Coordination[7];
// faceintW[1] = Coordination[8];
// faceintH[1] = Coordination[9];
// faceintX[2] = Coordination[11];
// faceintY[2] = 480 - Coordination[12];
// faceintW[2] = Coordination[13];
// faceintH[2] = Coordination[14];
// break;
#endregion
case 0:
{
for (int i = 0; i < 3; i++)
{
faceintX[i] = 0;
faceintY[i] = -130;
}
break;
}
case 1:
{
faceintX[0] = Coordination[1];
faceintY[0] = 480 -Coordination[2];
faceintX1 = faceintX[0];
faceintY1 = faceintY[0];
faceintX2 = 0;
faceintY2 = 0;
faceintX3 = 0;
faceintY3 = 0;
faceintW[0] = Coordination[3];
faceintH[0] = Coordination[4];
faceintX[1] = 0;
faceintY[1] = 0;
faceintX[2] = 0;
faceintY[2] = 0;
label1.Text = Coordination[5].ToString();
Flag1 = Coordination[5];
break;
}
case 2:
{
faceintX[2] = 0;
faceintY[2] = -130;
faceintX[0] = Coordination[1];
faceintY[0] = 480 - Coordination[2];
faceintX1 = faceintX[0];
faceintY1 = faceintY[0];
faceintW[0] = Coordination[3];
faceintH[0] = Coordination[4];
faceintX[1] = Coordination[6];
faceintY[1] = 480 - Coordination[7];
faceintX2 = faceintX[0];
faceintY2 = faceintY[0];
faceintX3 = 0;
faceintY3 = 0;
faceintW[1] = Coordination[8];
faceintH[1] = Coordination[9];
faceintX[2] = 0;
faceintY[2] = 0;
label2.Text = Coordination[10].ToString();
Flag2 = Coordination[10];
break;
}
case 3:
{
faceintX[0] = Coordination[1];
faceintY[0] = 480 - Coordination[2];
faceintX1 = faceintX[0];
faceintY1 = faceintY[0];
faceintW[0] = Coordination[3];
faceintH[0] = Coordination[4];
faceintX[1] = Coordination[6];
faceintY[1] = 480 - Coordination[7];
faceintX2 = faceintX[0];
faceintY2 = faceintY[0];
faceintW[1] = Coordination[8];
faceintH[1] = Coordination[9];
faceintX[2] = Coordination[11];
faceintY[2] = 480 - Coordination[12];
faceintW[2] = Coordination[13];
faceintH[2] = Coordination[14];
faceintX3 = faceintX[0];
faceintY3 = faceintY[0];
label3.Text = Coordination[15].ToString();
Flag3 = Coordination[15];
break;
}
}
#endregion
Bitmap bitmap = Bitmap.FromHbitmap(hBitmap);
captureImageBox.Image = bitmap;
DeleteObject(hBitmap);
GC.Collect();
}
}
#endregion
}
例子下载处:
http://download.csdn.net/my