EmguCV仅在x86发布模式下出现内存不足 - 锐化图像

时间:2018-05-17 10:18:36

标签: c# .net opencv bitmap emgucv

我试图使用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抛出以下异常

enter image description here

请注意,当项目设置为AnyCPU时,即使对于高分辨率图像,锐化也能正常工作 - &gt;调试模式 我正在使用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();

1 个答案:

答案 0 :(得分:1)

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

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();
    }