Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从照相机捕获流时内存不足错误_C#_Out Of Memory_Emgucv - Fatal编程技术网

C# 从照相机捕获流时内存不足错误

C# 从照相机捕获流时内存不足错误,c#,out-of-memory,emgucv,C#,Out Of Memory,Emgucv,在过去的两周里,我已经被这个错误弄得筋疲力尽。我尝试了很多方法来找出答案,并尝试了不同的代码,但还没有成功。我认为主要的问题是位图,可能是我使用的方式不正确。我正在分享我的代码,以帮助理解我在做什么 首先,我告诉你这个场景。在这个应用程序中,我使用dslr摄像头进行实时查看。camera类的主要代码区域如下: internal void Run() { LVrunning = true; while (LVrunning) { Thread.Sleep(2

在过去的两周里,我已经被这个错误弄得筋疲力尽。我尝试了很多方法来找出答案,并尝试了不同的代码,但还没有成功。我认为主要的问题是位图,可能是我使用的方式不正确。我正在分享我的代码,以帮助理解我在做什么

首先,我告诉你这个场景。在这个应用程序中,我使用dslr摄像头进行实时查看。camera类的主要代码区域如下:

internal void Run()
{
    LVrunning = true;
    while (LVrunning)
    {
        Thread.Sleep(20);
        if (LVrunning)
            UpdatePicture();
    }
}

private void UpdatePicture()
{
    try
    {
        if (err == EDSDK.EDS_ERR_OK && LVrunning)
        {
            inSide = true;

            // Download live view image data
            err = EDSDK.EdsDownloadEvfImage(cameraDev, EvfImageRef);

            if (err != EDSDK.EDS_ERR_OK)
            {
                Debug.WriteLine(String.Format("Download of Evf Image: {0:X}", err));
                return;
            }
            IntPtr ipData;
            err = EDSDK.EdsGetPointer(MemStreamRef, out ipData);
            if (err != EDSDK.EDS_ERR_OK)
            {
                Debug.WriteLine(String.Format("EdsGetPointer failed: {0:X}", err));
                return;
            }

            uint len;
            err = EDSDK.EdsGetLength(MemStreamRef, out len);
            if (err != EDSDK.EDS_ERR_OK)
            {
                Debug.WriteLine(String.Format("EdsGetLength failed:{0:X}", err));
                EDSDK.EdsRelease(ipData);
                return;
            }

            Byte[] data = new byte[len];
            Marshal.Copy(ipData, data, 0, (int)len);
            System.IO.MemoryStream memStream = new System.IO.MemoryStream(data);

            // get the bitmap
            Bitmap bitmap = null;
            try
            {
                bitmap = new Bitmap(memStream);
            }
            catch (OutOfMemoryException ex)
            {
                GC.WaitForPendingFinalizers();
                bitmap = new Bitmap(memStream); // sometimes error occur
            }

            NewFrame(bitmap, null); // this is event call back to form area.

            memStream.Dispose();
            EDSDK.EdsRelease(ipData);
        }
    }
    catch (Exception ex)
    {

    }
}
private void getCapturedItem(IntPtr directoryItem)
{
    uint err = EDSDK.EDS_ERR_OK;
    IntPtr stream = IntPtr.Zero;

    EDSDK.EdsDirectoryItemInfo dirItemInfo;

    err = EDSDK.EdsGetDirectoryItemInfo(directoryItem, out dirItemInfo);

    if (err != EDSDK.EDS_ERR_OK)
    {
        throw new CameraException("Unable to get captured item info!", err);
    }

    //  Fill the stream with the resulting image
    if (err == EDSDK.EDS_ERR_OK)
    {
        err = EDSDK.EdsCreateMemoryStream((uint)dirItemInfo.Size, out stream);
    }

    //  Copy the stream to a byte[] and
    if (err == EDSDK.EDS_ERR_OK)
    {
        err = EDSDK.EdsDownload(directoryItem, (uint)dirItemInfo.Size, stream);
    }

    //  Create the returned item
    //CapturedItem item = new CapturedItem();
    if (dirItemInfo.szFileName.ToString().ToLower().Contains("jpg") || dirItemInfo.szFileName.ToString().ToLower().Contains("jpeg"))
    {
        if (err == EDSDK.EDS_ERR_OK)
        {
            IntPtr imageRef = IntPtr.Zero;

            err = EDSDK.EdsCreateImageRef(stream, out imageRef);

            if (err == EDSDK.EDS_ERR_OK)
            {
                EDSDK.EdsImageInfo info;
                err = EDSDK.EdsGetImageInfo(imageRef, EDSDK.EdsImageSource.FullView, out info);
            }
        }
    }

    if (err == EDSDK.EDS_ERR_OK)
    {
        try
        {
            byte[] buffer = new byte[(int)dirItemInfo.Size];
            GCHandle gcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            IntPtr address = gcHandle.AddrOfPinnedObject();
            IntPtr streamPtr = IntPtr.Zero;
            err = EDSDK.EdsGetPointer(stream, out streamPtr);
            if (err != EDSDK.EDS_ERR_OK)
            {
                throw new CameraDownloadException("Unable to get resultant image.", err);
            }

            try
            {
                Marshal.Copy(streamPtr, buffer, 0, (int)dirItemInfo.Size);//sometimes error comes here
                System.IO.MemoryStream memStream = new System.IO.MemoryStream(buffer);

                    Bitmap bitmap = null;
                    try
                    {
                        bitmap = new Bitmap(memStream);
                    }
                    catch (OutOfMemoryException ex)
                    {
                        GC.WaitForPendingFinalizers();
                        Bitmap b = new Bitmap(memStream);//sometimes error comes here
                    }

                    if (bitmap != null)
                    {


                            PhotoCaptured(bitmap, null);

                    }

            }
            catch (AccessViolationException ave)
            {
                throw new CameraDownloadException("Error copying unmanaged stream to managed byte[].", ave);
            }
            finally
            {
                gcHandle.Free();
                EDSDK.EdsRelease(stream);
                EDSDK.EdsRelease(streamPtr);
            }
        }
        catch (OutOfMemoryException ex)
        {
            GC.WaitForPendingFinalizers();
            IboothmeObject.minimizeMemory();
            getCapturedItem(directoryItem);
        }
    }
    else
    {
        throw new CameraDownloadException("Unable to get resultant image.", err);
    }
}
在表单方面,图像只是在图片框中更新

private void StartLiveView()
    {
        if (this.liveView.Connected)
        {
            this.liveView.PhotoCaptured += new EventHandler(liveView_PhotoCaptured);
            this.liveView.NewFrame += new EventHandler(liveView_NewFrame);
            this.liveView.StartLiveView();

        }
    }

    void liveView_NewFrame(object sender, EventArgs e)
    {
        this.picMain.Image = sender as Image;
    }
    void liveView_PhotoCaptured(object sender, EventArgs e)
    {
        Image img = sender as Image;
        // this image is big in size like 5000x3000.
        Bitmap tempbitmap = new Bitmap(img.Width, img.Height);// now mostly error comes here
        tempbitmap.SetResolution(img.HorizontalResolution, img.VerticalResolution);
            using (Graphics g = Graphics.FromImage(tempbitmap))
            {
                g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
                g.Save();
            }
        picMain.Image = tempbitmap;
        tempbitmap.Save(path,ImageFormat.Jpeg);
    }
另一个使用位图和摄像机实时视图的代码区域。此代码从摄像机获取帧并在帧上写入一些对象。在我的例子中,我正在帧上写入一些气球

void liveView_NewFrame(object sender, EventArgs e)
    {
        using (Image<Bgr, byte> Frame = new Image<Bgr, byte>(new Bitmap(sender as Image)))
        {
            Frame._SmoothGaussian(3);
            IntPtr hsvImage = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(Frame), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
            CvInvoke.cvCvtColor(Frame, hsvImage, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_BGR2HSV);

            Image<Gray, byte> imgThresh = new Image<Gray, byte>(Frame.Size);
            imgThresh.Ptr = GetThresholdedImage(hsvImage);
            //CvInvoke.cvSmooth(imgThresh, imgThresh, Emgu.CV.CvEnum.SMOOTH_TYPE.CV_GAUSSIAN, 3, 3, 3, 3);

            #region Draw the contours of difference
            //this is tasken from the ShapeDetection Example
            Rectangle largest = new Rectangle();
            try
            {
                using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation
                    //detect the contours and loop through each of them
                    for (Contour<Point> contours = imgThresh.Convert<Gray, Byte>().FindContours(
                          Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                          Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL,
                          storage);
                       contours != null;
                       contours = contours.HNext)
                    {
                        //Create a contour for the current variable for us to work with
                        Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage);

                        //Draw the detected contour on the image
                        if (currentContour.Area > ContourThresh) //only consider contours with area greater than 100 as default then take from form control
                        {
                            if (currentContour.BoundingRectangle.Width > largest.Width && currentContour.BoundingRectangle.Height > largest.Height)
                            {
                                largest = currentContour.BoundingRectangle;
                            }
                        }
                        //storage.Dispose();
                    }

            }
            catch (Exception)
            {

            }

            #endregion

            #region Draw Object
            Random r = new Random();
            //Bitmap bb = Frame.Bitmap;
            foreach (var item in objectList)
            {
                using (Graphics g = Graphics.FromImage(Frame.Bitmap))
                {
                    if (DrawAble(item, largest))
                    {
                        if (item.Y < 0)
                        {
                            if (item.X < picMain.Width)
                            {
                                g.DrawImage(item.image, new Rectangle(item.X, 0, item.image.Width, item.image.Height + item.Y),
                                    new Rectangle(), GraphicsUnit.Pixel);
                                item.X += r.Next(-5, 5);
                                item.Y += 15;
                            }
                        }
                        else
                        {
                            if (item.X < picMain.Width && item.Y < picMain.Height)
                            {
                                g.DrawImage(item.image, new Rectangle(item.X, item.Y, item.image.Width, item.image.Height));
                                item.X += r.Next(-5, 5);
                                item.Y += 15;
                            }
                            else
                            {
                                item.X = r.Next(0, picMain.Width - 5);
                                item.Y = r.Next(-item.image.Height, -5);
                            }

                        }
                    }
                    else
                    {
                        item.X = r.Next(0, picMain.Width - 5);
                        item.Y = r.Next(-item.image.Height, -5);
                    }

                }
            }

            #endregion

            picMain.Image = Frame.ToBitmap();

        }

        minimizeMemory();
    }
但不工作的错误仍然是一样的

UpdatePicture()方法中有时显示错误,liveView_NewFrame方法中有时出现错误。 表示问题与位图、位图大小或内存损坏有关。
所以请帮帮我。我很担心,两周过去了,但我无法解决这个问题。

您正在调用
CvInvoke.cvCreateImage
创建的数据位于本机堆上
因此,GC不会收集这些数据。
您必须调用
cvReleaseImage(IntPtr)
来释放数据

有很多内存分析器可以帮助理解这个问题


试着使用

这是很多需要我们调试的代码。当抛出
OutOfMemoryException
时,考虑GC已经太迟了——它已经尽了最大努力,但失败了。每当您编写调用
GC
类(除了
KeepAlive
)的代码时,您都可能做错了什么。您需要在OOM异常发生时捕获进程转储,而不是期望我们调试此代码,然后搜索.NET内存泄漏,以获取探索转储和查找问题的提示和提示。Tess Ferrandez过去曾就此写过一些很好的博客文章。处理完位图后,尝试调用dispose on bitmaps,可能会有所帮助。好的,我会尝试找出答案。谢谢你,makc,我删除了此区域的错误。如果不处理指针,内存会不断增加。但在此之后,我解决了这个问题。但我在应用程序的其他方面仍然存在错误。现在我正在尝试正确检查位图对象。@t4taurus我很高兴我能提供帮助:),尝试使用任何内存分析器,它将有助于解决问题。
// get the bitmap
        Bitmap bitmap = null;
        try
        {
            bitmap = new Bitmap(memStream);
        }
        catch (OutOfMemoryException ex)
        {
            GC.WaitForPendingFinalizers();
            bitmap = new Bitmap(memStream);
        }