使用C#来做界面以及图片的反复读取,为了利用C#的回收机制,不必担心内存泄漏问题
Image<Bgr, Byte> image = null;
Image<Bgr, Byte> outframe;
Bitmap bitmap;
MIplImage mlI;
foreach (var strImg in m_ImgList)
{
string strImgName = "图片路径/" + strImg ;
bitmap = new Bitmap(strImgName);
image = new Image<Bgr, Byte>(bitmap);
IntPtr ptrImg = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(image),
Emgu.CV.CvEnum.IplDepth.IplDepth_8U, image.Mat.NumberOfChannels);
CSharpAlg.ImgAlg(m_AlgPtr, image.Ptr, ptrImg);
//dll 接口定义: public static extern int ImgAlg(IntPtr pHandle, IntPtr pSrcImg, IntPtr pIplImg);
mlI = (MIplImage)Marshal.PtrToStructure(ptrImg, typeof(MIplImage));//托管与非托管的转换
outframe = new Image<Bgr, Byte>(mlI.Width, mlI.Height, mlI.WidthStep, mlI.ImageData);
// 在后台线程中进行C++ dll函数调用,使用代理进行界面图片显示
this.Invoke(new Action(() =>
{
pbPicShow.Image = outframe.ToBitmap();
}));
// 完成后进行内存释放;在后台线程执行完之前,不会进行回收,图片过多时会导致内存用完,new失败
CvInvoke.cvReleaseImage(ref ptrImg);
bitmap.Dispose();
image.Dispose();
}
// C++ dll的接口代码
ALG_DLL_EXP int __cdecl ImgAlg(ALG_HANDLE pHandle, IplImage* pSrc,
IplImage* pImg)
{
int nRet = -1;
AlgClass* pAlg = (AlgClass*)pHandle;
*pImg = *pSrc;
cv::Mat imgMat(pImg);
nRet = pAlg ->ImgAlg(imgMat);
*pImg = imgMat;
return nRet;
}