【问题标题】:How can I send the byte array for Bitmap to the main page in image processing?如何将位图的字节数组发送到图像处理的主页?
【发布时间】:2021-12-18 10:20:42
【问题描述】:

我正在尝试将字节发送到“alldata.AddRange()”,但我想将其作为行来执行。我的意思是,例如,我有一个 RGB 视图 640 * 360。视图的宽度是 640。我想取视图 640*3=1920(作为一条线)并将其设为灰色并将其发送回函数(alldata.AddRange)。如果我发送其中的第 360 行,我想拍摄图像。我该如何这样做?

编辑:我只是稍微更改了代码。可能可以认为它是通过数组在类之间发送数据,我需要将它们部分发送而不是考虑图像处理问题。

Form1 的代码如下:

using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace dnm2510img
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public FilterInfoCollection devices;
        public VideoCaptureDevice camera;
        private void Form1_Load(object sender, EventArgs e)
        {
            devices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            foreach (FilterInfo item in devices)
            {
                comboBox1.Items.Add(item.Name);

            }

            camera = new VideoCaptureDevice();
            comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
        }
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (camera.IsRunning == false)
                {
                    camera = new VideoCaptureDevice(devices[comboBox1.SelectedIndex].MonikerString);
                    camera.NewFrame += Camera_NewFrame;
                    camera.Start();
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message + "");
            }
        }
        public void Camera_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            List<byte> alldata = new List<byte>();
            //byte[] line = new byte[360];
            Bitmap image = (Bitmap)eventArgs.Frame.Clone();
            byte[] maindata = new byte[image.Height*image.Width*4];
            int count = 0;
            if(btnapplyWasClicked == true)
            {
                for (int i = 0; i < image.Height; i++)
                {
                    for (int j = 0; j < image.Width; j++)
                    {
                        Color color = image.GetPixel(j, i);
                        maindata[count] = color.R;
                        maindata[count + 1] = color.G;
                        maindata[count + 2] = color.B;
                        maindata[count + 3] = color.A;
                        count = count + 4;

                        for (int k = 1; k <= 360; k++)
                        {
                            if (maindata[(count + 4) * k] == maindata[2560 * k])
                            {
                                dnm2510img.Gray.GrayFilter(maindata, 2560 * k);
                            }
                        }
                    }
                }
                    //alldata.AddRange(maindata);
            }
            
        }
        
        private bool btnapplyWasClicked = false;
        //private bool button1WasClicked = false;
        //private bool GeriALWasClicked = false;

        private void btnapply_Click(object sender, EventArgs e)
        {
            btnapplyWasClicked = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //button1WasClicked = true;
        }
    }
}

这是灰度的代码:

using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace dnm2510img
{
    public class Gray
    {
        
        public static byte[] GrayFilter(byte[] data,int width)
        {
            List<byte> alldataa = new List<byte>();
            for (int i = 0; i < width; i++)
            {
                int temp =((data[i]+data[i+1]+data[i+2]+data[i+3]) / 4);
                data[i] = (byte)temp;
                data[i+1] = (byte)temp;
                data[i+2] = (byte)temp;
                data[i + 3] = (byte)temp;
            }
            //alldataa.AddRange(data);
            return data;
        }
        
        
    }
}

【问题讨论】:

  • 您已经在更改阵列。你真的需要退货吗?
  • 但是当我不返回时,我得到了错误。
  • ...错误是什么?您在这里没有使用结果:dnm2510img.Gray.GrayFilter(maindata, 1920 * k);,所以我看不出仅将方法更改为void 会出现错误。
  • 是的,当我添加 void 错误消失了,谢谢,但是您有什么建议可以解决我的问题。
  • 不只是alldata.AddRange(maindata);?

标签: c# image-processing


【解决方案1】:

这是将 24 bpp 位图转换为灰度并将其输出到线性数组的方法:

public static unsafe byte[] ToBgr24To8Mono(Bitmap source)
{
    var width = source.Width;
    var height = source.Height;
    var sourceData = source.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, source.PixelFormat);
    var sourceStride = sourceData.Stride;
    var sourcePtr = (byte*)sourceData.Scan0;
    var targetArray = new byte[width * height];
    try
    {
        Parallel.For(0, height, y =>
        {
            var sourceRow = sourcePtr + y * sourceStride;
            var targetRow =  y * width;
            for (int x = 0; x < width; x++)
            {
                var sourceIndex = (sourceRow + x * 3);
                var value = (byte) (sourceIndex[0] * 0.11f + sourceIndex[1] * 0.59f + sourceIndex[2] * 0.3f);
                targetArray[targetRow + x] = value;
            }
        });
    }
    finally
    {
        source.UnlockBits(sourceData);
    }

    return targetArray;
}

如果您想使用 32 位图像作为输入,请将 x * 3 更改为 x * 4。如果您愿意,可以将并行循环切换为常规循环。

【讨论】:

  • 谢谢你,我会尝试用这种方式做@JonasH,但如果有人能用我的方法解决它,我将不胜感激
猜你喜欢
  • 2016-01-05
  • 2012-07-28
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
相关资源
最近更新 更多