C与C#混合编程

 
  
 

 
  
 一、将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

 
 

你可能感兴趣的:(C/C++)