图像上的伪像从16bpp到BMP

时间:2017-05-17 13:23:38

标签: c# image grayscale artifact

在我开发的显微镜上,我用CCD相机拍摄了那叠图像。

我正在使用Lumenera的CCD相机生成12bpp的图像,由

拉伸

<< 4(在LSB上移动4个零) 到16bpp。我附上原始图像 - 看起来很合理: jpg of raw image

这是另一个: enter image description here 还有许多蒙太奇,其中有垂直线:enter image description here

唯一的"处理"我在蒙太奇上 THINK I DO 正在缩放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 个答案:

答案 0 :(得分:1)

没有看到原始数据我只能使用您显示的图像。但我怀疑你的图像创建代码是错误的。

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

  1. 图像的整体亮度不一样。
  2. 图像的亮度有所偏差,右上方有点暗,如阴影或单面的小插图。
  3. 第一个问题很容易克服;第二个不是这样。

    这是一个简单的,实际上非常简单的方法,将相当均匀的图像带到一个共同的亮度级别

    1. 准备图像;因为它们相当粗糙,我们从每个版本创建一个较小的版本来进行统计。
    2. 调整整体亮度。我们不需要查看每个像素;一个相当大的数字将会做。我使用随机选择的1000像素。
    3. 调整图像以获得均匀的亮度。使用ColorMatrix
    4. ,这是最好和最快的完成
    5. 使用两种颜色矩阵将图像拼接在一起。
    6. 我为两个较大的那个做了这个。正如你所看到的那样,左边的部分几乎是水平的,但是在右边,顶部的阴影比底部的阴影更深,并且拼接瑕疵很强烈。

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

      结果如下:

      enter image description here

      ..这是代码:

      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 ?在这里不能帮助,但我建议先调查一下...... - 另外:有些模式似乎在重复,有些则不是...... - 像往常一样,最好尽可能早地在加工链中提高质量。