C# EmguCV PictureBox - 如何显示无符号的 16 位灰度图像?

问题描述 投票:0回答:1

我的项目中有一个单色相机,我可以读取 8 位/16 位深度的图像。 我正在使用 EmguCV 库从字节数组中创建一个 Mat 对象,我从相机读取该对象并希望在 EmguCV PictureBox 控件上显示图像。

当我在 8 位模式下工作时,一切看起来都很好,但当我尝试在 16 位模式下工作时,图片框显示会变黑。 如果我将 16 位图像的 mat 对象保存到文件中,图像看起来不错,所以我不确定问题可能是什么。

这是我正在使用的代码:

//This function run on a separate thread and continuously acquires frames from the camera. 
private int CatureVideoWorker()
{
    while(captureImages) 
    {
    //buffer address is pinned using GCMarshal to variable called pinnedImgBuffer.
    buffer = readFrameFromCamera(); 
    //acquire exclusive lock so GUI thread won't access mat object while it's being written to.
    lock (syncRoot)      {
        lastFrame.Dispose();
        if (8bitMode == true)
            lastFrame = new Mat(_height, _width, Emgu.CV.CvEnum.DepthType.Cv8U, 1, pinnedImgBuffer.AddrOfPinnedObject(), _width);
        else  
            lastFrame = new Mat(_height, _width, Emgu.CV.CvEnum.DepthType.Cv16U, 1, pinnedImgBuffer.AddrOfPinnedObject(), _width * 2);
    }
    }
    return 1;
}

//Timer event that run on the main GUI thread ~33ms to load the lastFrame to the Emgu PictureBox.
private void tmrCaptureFrame_Tick(object sender, EventArgs e)
{
    //make sure to get exclusive lock so the mat object won't get written/disposed while 
    //cloning it to the picture box. 
    lock (syncRoot)
    {
        pbx.Image = lastFrame.Clone();
    }
}

如前所述,在 8 位模式下,图片框显示相机的实时取景,但切换到 16 位时,图片框全黑。

在 8 位/16 位模式下将 Mat 对象保存到文件中效果很好,并且在 msPaint 中打开文件时 16 位图像看起来不错,所以不确定图片框有什么问题。

c# picturebox emgucv grayscale 16-bit
1个回答
0
投票

很少有软件可以很好地显示 16 位图像。大多数似乎只取高 8 位,并且只有当图像中的最大值为

ushort.MaxValue
时,这才有效。如果您将 16 位图像保存到文件中,并且它在 msPaint 中看起来不错,我会仔细检查它是否实际上是 16 位图像。许多软件倾向于默默地将高动态范围图像转换为 8 位。您需要小心确保处理链中的所有组件都可以处理 16 位图像。

无论如何,16位图像都需要转换为8位才能显示。一种相当简单的方法是在最小值和最大值之间进行线性缩放。 EmguCV 在 normalize 函数中

有这个

归一化(src,dst,NORM_MINMAX,0,255)

更高级的方法是在 0.01 和 0.99 百分位像素值之间进行缩放。或者做一些有限形式的直方图均衡。

© www.soinside.com 2019 - 2024. All rights reserved.