一、将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;j<TotalBef;i=i+5,j++)
{
pt[j].x=CooIndex[i]+CooIndex[i+2]/2;
pt[j].y=CooIndex[i+1]+CooIndex[i+3]/2;
}
}
IplImage *image=cvCloneImage(Frame);
if(image->origin==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;x<Frame->height;x++)
for (y=0;y<Frame->width;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.height<binal_copy->height/5&&bndRect.width<binal_copy->width/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);