C与C#混合编程

本文介绍了如何在C#中调用封装了OpenCV人脸识别代码的DLL。首先创建一个Win32 DLL项目,导出函数,然后在C#中通过添加引用和unsafe代码块来调用DLL,实现从视频文件中检测人脸的功能。文章详细展示了C++中定义的DLL函数和C#中调用的示例代码。
摘要由CSDN通过智能技术生成
 


 一、将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);
					IplImage *Img_R=cvCreateImage(cvGetSize(small_img),8,1);
					IplIma
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值