繁体   English   中英

从16bpp到BMP的图像伪像

[英]Artifacts on Image from 16bpp to BMP

我在显影的显微镜上有一堆用CCD相机拍摄的图像。

我正在使用Lumenera的CCD相机,该相机会产生12bpp的图像,

<< 4(将LSB上的4个零移位)到16bpp。 我附上原始图片-看起来很明智: 原始图片jpg

这是另一个: 在此处输入图片说明 和其中许多的蒙太奇,其中有垂直线: 在此处输入图片说明

认为我在蒙太奇上所做的唯一“处理”是在minValue和maxValue之间缩放值,并将该值压缩为一个字节,以便在8bpp位图中使用它,使用以下行:

public static void ParseImage(ushort[]image,ushort minVal,ushort maxVal, int nx,int ny)
{
  ...........
  byte val = (byte)((image[i]-minval)/(maxVal-minVal)*byte.maxValue);

我知道:处理过的图像中的伪影通常使我将手指放在相机上,但是相机制造商表示这可能与12位到16位之间的转换有关……任何人都可以理解,以及所以-如何解决? 还是我可以通过这些工件识别出一些错误

任何帮助(提示,更多家庭作业对我来说..)将不胜感激! 谢谢

没有看到原始数据,我只能根据您显示的图像进行操作。 但是我怀疑您的图像创建代码根本是错误的。

据我所知,您有两个问题,这两个问题均源于原始数据。

  1. 图像的整体亮度不一样。
  2. 图像上的亮度有偏差,右上角较暗,如阴影或单面装饰图案。

第一个问题很容易克服。 第二不是。

这是一种简单但实际上非常简单的方法,可以将相当均匀的图像带到一个普通的亮度级别

  1. 准备图像; 因为它们相当粗糙,所以我们为每个统计数据创建一个较小的版本。
  2. 计算整体亮度。 我们不需要研究每个像素。 一个相当大的数目就可以了。 我使用1000随机选择的像素。
  3. 使图像适应均匀的亮度。 这是使用ColorMatrix最好最快的方法。
  4. 使用两种颜色矩阵将图像拼接在一起。

我是为两个较大的服务器这样做的。 如您所见,左侧部分几乎是水平的,但右侧的顶部阴影比底部的阴影暗,并且拼接效果明显。

如果您无法在相机级别解决此问题,或者可能无法通过更细心的闪电解决问题,那么最好的解决方案imo是创建用于校正的标准图像; 它会是完全空白的,即除了阴影之外没有动机。 然后,您可以以某种方式从每个真实图像中减去此值,例如,在计算允许伽玛差异的因素之后。

结果如下:

在此处输入图片说明

..这是代码:

private void button1_Click(object sender, EventArgs e)
{
    Bitmap bmp1 = (Bitmap) Image.FromFile(path1); 
    Bitmap bmp2 = (Bitmap) Image.FromFile(path2);
    int factor = 8;   // size reduction for smooth measurement data
    Size sz = bmp1.Size;
    Size szs = new Size(sz.Width / factor, sz.Height / factor);
    Bitmap bmp1s = new Bitmap(bmp1, szs);
    Bitmap bmp2s = new Bitmap(bmp2, szs);

    float avgBrightnes1 = getAvgBrightness(bmp1, 1000);
    float avgBrightnes2 = getAvgBrightness(bmp2, 1000);

    float avgB12 = (avgBrightnes1 + avgBrightnes2) / 2f;
    float deltaB1 = avgB12 - avgBrightnes1;
    float deltaB2 = avgB12 - avgBrightnes2;

    Console.WriteLine("  B1 = " + avgBrightnes1.ToString("0.000") 
                    +   "B2 = " + avgBrightnes2.ToString("0.000"));

    pictureBox1.Image = (Bitmap)bmp1;
    pictureBox2.Image = (Bitmap)bmp2;

    Rectangle r1 = new Rectangle(0, 0, sz.Width, sz.Height);
    Rectangle r2 = new Rectangle(0, sz.Height, sz.Width, sz.Height);

    Bitmap bmp12 = new Bitmap(sz.Width, sz.Height * 2);

    ColorMatrix M1 = new ColorMatrix();
    M1.Matrix40 =  M1.Matrix41 = M1.Matrix42 = deltaB1;
    ColorMatrix M2 = new ColorMatrix();
    M2.Matrix40 =  M2.Matrix41 = M2.Matrix42 = deltaB2;
    ImageAttributes iAtt = new ImageAttributes();

    using (Graphics g = Graphics.FromImage(bmp12))
    {
        iAtt.SetColorMatrix(M1, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
        g.DrawImage(bmp1,r1, 0, 0, sz.Width, sz.Height, GraphicsUnit.Pixel, iAtt);

        iAtt.ClearColorMatrix();
        iAtt.SetColorMatrix(M2, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
        g.DrawImage(bmp2,r2, 0, 0 ,sz.Width, sz.Height, GraphicsUnit.Pixel, iAtt);
    }
    pictureBox3.Image = (Bitmap)bmp12;
}

float getAvgBrightness(Bitmap bmp, int count)
{
    Random rnd = new Random(0);
    float b = 0f;
    for (int i = 0; i < count; i++)
    {
        b += bmp.GetPixel(rnd.Next(bmp.Width), rnd.Next(bmp.Height)).GetBrightness();
    }
    return b/count;
}

getAvgBrightness非常简单。 可以使用更高级的统计信息来权衡最常见或最中间的亮度水平。 我认为MSChart控件具有可以使用的内置统计功能。 但是从我看来,真正的问题在于相机图像中的伽玛和小插图阴影。

请注意:即使图像很简单,拼接也不是一件容易的事。 那里的全景拼接软件非常专业! 在您的图像中,伪影非常容易检测,因为我们的眼睛看不到其他东西。

PS:看着第3图像一个不禁想知道为什么图像越来越progressivley暗? 在这里无济于事,但我建议您先对此进行调查。-另外:某些模式似乎正在重复,而其他模式则没有。-与往常一样,最好尽早在加工链中提高质量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM