如何从System.Drawing.Bitmap转换为灰度,然后转换为双精度数组(Double [,]),然后再转换为灰度位图? [英] How to convert from System.Drawing.Bitmap to grayscale, then to array of doubles (Double[,]), then back to grayscale Bitmap?

查看:342
本文介绍了如何从System.Drawing.Bitmap转换为灰度,然后转换为双精度数组(Double [,]),然后再转换为灰度位图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在照片中执行一些数学运算,为此我需要图像的浮点灰度版本(可能来自JPG,PNG或具有各种颜色深度的BMP文件)。

I need to perform some mathematical operations in photographs, and for that I need the floating point grayscale version of an image (which might come from JPG, PNG or BMP files with various colordepths).

我以前在Python中使用 PIL scipy.ndimage 来做到这一点,它是非常简单地用 PIL 转换为灰度,然后转换为带有 numpy 的浮点数数组,但现在我需要在C#中做类似的事情,我很困惑如何这样做。

I used to do that in Python using PIL and scipy.ndimage, and it was very straightforward to convert to grayscale with PIL and then to an array of floating-point numbers with numpy, but now I need to do something similar in C#, and I'm confused how to do so.

我读过这个非常好的教程,这似乎是一个反复出现的参考,但只涵盖了转换为灰度部分,我不知道如何从Bitmap获取双打数组,然后(在某个时刻)将其转换回System.Drawing.Bitmap以供查看。

I have read this very nice tutorial, that seems to be a recurring reference, but that only covers the "convert to grayscale" part, I am not sure how to get an array of doubles from a Bitmap, and then (at some moment) to convert it back to System.Drawing.Bitmap for viewing.

推荐答案

决赛代码,主要基于从评论中提取的提示,特别是 LockBits 部分(这里的博客文章)以及R,G和B值之间的感知平衡(这里不是最重要的,但需要了解的事情):

The final code, based mostly in tips taken from the comments, specifically the LockBits part (blog post here) and the perceptual balancing between R, G and B values (not paramount here, but something to know about):

    private double[,] TransformaImagemEmArray(System.Drawing.Bitmap imagem) {
        // Transforma a imagem de entrada em um array de doubles
        // com os valores grayscale da imagem

        BitmapData bitmap_data = imagem.LockBits(new System.Drawing.Rectangle(0,0,_foto_franjas_original.Width,_foto_franjas_original.Height),
                                            ImageLockMode.ReadOnly, _foto_franjas_original.PixelFormat);

        int pixelsize = System.Drawing.Image.GetPixelFormatSize(bitmap_data.PixelFormat)/8;

        IntPtr pointer = bitmap_data.Scan0;
        int nbytes = bitmap_data.Height * bitmap_data.Stride;
        byte[] imagebytes = new byte[nbytes];
        System.Runtime.InteropServices.Marshal.Copy(pointer, imagebytes, 0, nbytes);

        double red;
        double green;
        double blue;
        double gray;

        var _grayscale_array = new Double[bitmap_data.Height, bitmap_data.Width];

        if (pixelsize >= 3 ) {
            for (int I = 0; I < bitmap_data.Height; I++) {
                for (int J = 0; J < bitmap_data.Width; J++ ) {
                    int position = (I * bitmap_data.Stride) + (J * pixelsize);
                    blue = imagebytes[position];
                    green = imagebytes[position + 1];
                    red = imagebytes[position + 2];
                    gray = 0.299 * red + 0.587 * green + 0.114 * blue;
                    _grayscale_array[I,J] = gray;
                }
            }
        }

        _foto_franjas_original.UnlockBits(bitmap_data);

        return _grayscale_array;
    }

这篇关于如何从System.Drawing.Bitmap转换为灰度,然后转换为双精度数组(Double [,]),然后再转换为灰度位图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆