【问题标题】:EmguCV Out of memory exception in x86 release mode only-Sharpening ImagesEmguCV Out of memory exception in x86 release mode only - 锐化图像
【发布时间】:2018-05-17 10:18:35
【问题描述】:

我正在尝试使用 EmguCV 提高图像的清晰度

 Image<Bgr, Byte> myImage = new Image<Bgr, Byte>(new Bitmap(pictureBox1.Image));
            float[,] matrixKernel = new float[3, 3] {
                { 0,-1, 0 },
                {-1, 5,-1 },
                { 0,-1, 0 }
};
            ConvolutionKernelF matrix = new ConvolutionKernelF(matrixKernel);
            Image<Bgr, float> result = myImage.Convolution(matrix);
            Image<Bgr, Byte> BGRResult = result.ConvertScale<byte>(1, 0);
            e.Result = BGRResult.ToBitmap();
            myImage.Dispose();
            result.Dispose();
            BGRResult.Dispose();

该代码适用于中等分辨率图像,但是当使用高分辨率图像时,例如:6000X4000 会引发以下异常

请注意,当项目设置为 AnyCPU -> 调试模式时,即使对于高分辨率图像,锐化也能正常工作 我正在使用 EmguCV 3.3

更新

根据 Rick 的参考答案,我做了以下修改,但问题仍然存在。请指教。

float[,] matrixKernel = new float[3, 3] {
{ 0,-1, 0 },
{-1, 5,-1 },
{ 0,-1, 0 }
};
ConvolutionKernelF matrix = new ConvolutionKernelF(matrixKernel);
var result2 = myImage.CopyBlank();
var handle = GCHandle.Alloc(result2); 
Image<Bgr, float> result = result2.Convolution(matrix);
Image<Bgr, Byte> BGRResult = result.ConvertScale<byte>(1, 0);

bm_dest = new Bitmap(BGRResult.ToBitmap());
handle.Free();
BGRResult.Dispose();
result.Dispose();
myImage.Dispose();
matrix.Dispose();

【问题讨论】:

  • 你可能想看看this answer
  • @RickM。感谢您的回复。如何调整该答案以在我的代码中处理掉句柄,请指教。
  • @RickM。请查看我的更新。

标签: c# .net opencv bitmap emgucv


【解决方案1】:

我认为这是与 cmets 中链接的访问冲突不同的问题。

Convolve 在底层 OpenCv API 中调用 Filter2D - 它适用于单通道浮动图像

您正在传递一个多通道字节图像

Emgu 3.3 将您的输入转换为浮动图像,每个通道调用一次Filter2D 并将图像重新拼接在一起。

对于 6000 x 4000,这需要在调用期间分配大约 576MB,如果您在 32 位进程中运行,这将是很多。

编辑

在每个通道上调用Filter2d 并随时进行处理会占用更少的内存,但会慢一些。

使用我比较熟悉的OpenCvSharp的例子,过滤的开销只有100mb:

    var inputMat = BitmapConverter.ToMat(myBitmap);
    var kernel = OpenCvSharp.InputArray.Create(
        new float[3, 3] { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } }
        );

    for (int i = 0; i < inputMat.Channels(); i++)
    {
        var c1 = inputMat.ExtractChannel(i);
        var c2 = c1.Filter2D(inputMat.Type(), kernel);
        c1.Dispose();
        c2.InsertChannel(inputMat, i);
        c2.Dispose();
    }

【讨论】:

  • 你说的好像是多通道图像造成的。分配了大约500mb的内存。我该如何解决这个问题。我只需要锐化图像。请指教。
  • 您可以首先将图像分配为浮点数,然后就地调用Filter2d(每个调用读取和写入一个图像通道,或者至少只使用一个单通道浮点临时图像) .切换到 64 位进程或减少在其余代码中分配的内存应该可以工作。
  • 感谢您的回复。我已从项目中删除 EmguCV,因为我需要 x86 版本。将在下一次更新中对其进行研究。
  • 是的,我认为 OpenCvSharp 可以在大图像的 8 位通道上调用 Filter2D,因此使用更少的内存。我的回答没有回答问题吗?
  • 我已经接受了这个答案。你能指点我一些相关的opencvsharp示例代码吗。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多