【问题标题】:How can I properly convert Bitmap RGB color to a 2d double array?如何正确地将位图 RGB 颜色转换为二维双数组?
【发布时间】:2018-07-22 06:42:31
【问题描述】:

我需要将Bitmap 图像转换为二维double 数组。
我想要一个代表 0-1 之间缩放的 RBG 颜色的每个像素的任意数字。 我想将位图图像转换为 2D 双精度数组,以便可以将卷积运算应用于该位图图像。 所以,我写了以下代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        Bitmap image = (Bitmap)Bitmap.FromFile("lena.jpg");

        pictureBox1.Image = image;
        dataGridView1.DataSource = ToDataTable(ToDouble2d(image));
    }        

    public static double[,] ToDouble2d(Bitmap input)
    {
        int width = input.Width;
        int height = input.Height;

        double[,] array2d = new double[width, height];

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                Color clr = input.GetPixel(x, y);

                double iClr = (double)clr.ToArgb();

                array2d[x, y] = iClr / 255.0;
            }
        }

        return array2d;
    }

    public static DataTable ToDataTable(double[,] numbers)
    {
        DataTable dt = new DataTable();
        for (int i = 0; i < numbers.GetLength(1); i++)
        {
            dt.Columns.Add("Column" + (i + 1));
        }

        for (var i = 0; i < numbers.GetLength(0); ++i)
        {
            DataRow row = dt.NewRow();
            for (var j = 0; j < numbers.GetLength(1); ++j)
            {
                row[j] = numbers[i, j];
            }
            dt.Rows.Add(row);
        }
        return dt;
    }
}

我注意到的第一个问题是:所有值都是负数。
因此,我尝试在 01 之间重新调整它们。

private static void Rescale(double[,] convolve)
{
    int imageWidth = convolve.GetLength(0);
    int imageHeight = convolve.GetLength(1);

    double maxAmp = 0.0;

    for (int j = 0; j < imageHeight; j++)
    {
        for (int i = 0; i < imageWidth; i++)
        {
            maxAmp = Math.Max(maxAmp, convolve[i, j]);
        }
    }

    double scale = 1 / maxAmp;

    for (int j = 0; j < imageHeight; j++)
    {
        for (int i = 0; i < imageWidth; i++)
        {
            double d = convolve[i, j] * scale;
            convolve[i, j] = d;
        }
    }
}  

现在,所有强度都变成了-Infinity

那么,处理这种情况的正确方法是什么?

注意。此时性能不是问题(例如位图锁定等)。我只是想知道为什么我的代码不能正常工作,以及如何正确地做到这一点。

【问题讨论】:

  • 那么您想获得颜色的色调饱和度 (HSL) 亮度值吗?
  • 只有 RGB 或 Alpha 通道
  • ToArgb()给出负值是正常的;它是以 alpha 值开头的UInt32,通常为 0xFF,但由于它表示为Int32,这意味着启用了第一位,因此,该数字被视为负数。要解决这个问题,只需先将其投射到UInt32

标签: c# image-processing bitmap


【解决方案1】:

我不确定您要做什么,或者为什么。但是,如果您只想要一个表示从 0 到 1 缩放的 RBG 值的任意数字。您也许可以这样做

public static Uint RGBtoUInt(int r, int g, int b)
{
    return (uint)(( r << 0 ) | ( g << 8 ) | ( b << 16 ));
}

...

var myArbitaryValue = RGBtoInt(r,g,b) / (double)16581375; // maximum 24bit color value 

注意:完全未经测试

【讨论】:

    【解决方案2】:

    好的,我已经解决了this link的问题。

        public static double[,] ToDouble2d(Bitmap input)
        {
            int width = input.Width;
            int height = input.Height;
    
            double[,] array2d = new double[width, height];
    
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Color cl = input.GetPixel(x, y);
    
                    // A 2d double data is always Grayscale.
                    // So, three elements are averaged.
                    double gray = ((cl.R * 0.3) + (cl.G * 0.59) + (cl.B * 0.11));
    
                    array2d[x, y] = gray/255.0;
                }
            }
    
            return array2d;
        }
    

    【讨论】:

    • 好吧,您的问题甚至没有提到您想将其视为灰度。您也可以只使用来自ColorGetBrightness() 值。
    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 2011-03-23
    • 2011-07-30
    • 2012-09-30
    相关资源
    最近更新 更多