You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中为EmguCV的Mat逐像素赋值?

嘿,我之前也纠结过这个问题,现在给你分享几种用Emgu CV的Mat类逐像素赋值的实用方法,亲测有效:

方法1:使用Mat.At<T>()方法(最直观易读)

这是最常用的方式,Emgu CV为Mat提供了泛型的At<T>方法,你只需要根据Mat的像素类型传入对应的泛型参数就行:

示例1:8位单通道灰度图

// 创建一个200x200的8位单通道灰度Mat
Mat grayMat = new Mat(200, 200, DepthType.Cv8U, 1);

// 双层循环逐像素赋值
for (int y = 0; y < grayMat.Rows; y++)
{
    for (int x = 0; x < grayMat.Cols; x++)
    {
        // 这里可以根据x、y自定义像素值,比如生成渐变效果
        byte pixelValue = (byte)((x + y) % 256);
        // 注意坐标是(y, x):先行后列,别搞反!
        grayMat.At<byte>(y, x) = pixelValue;
    }
}

示例2:3通道彩色图(BGR格式)

Emgu CV默认用BGR顺序,所以可以直接用Bgr结构:

// 创建一个100x100的3通道彩色Mat
Mat colorMat = new Mat(100, 100, DepthType.Cv8U, 3);

for (int y = 0; y < colorMat.Rows; y++)
{
    for (int x = 0; x < colorMat.Cols; x++)
    {
        // 直接赋值BGR颜色,比如纯红色
        colorMat.At<Bgr>(y, x) = new Bgr(0, 0, 255);
        
        // 如果需要单独修改某一通道,也可以这样操作:
        // var currentColor = colorMat.At<Bgr>(y, x);
        // currentColor.Green = 255; // 改成绿色
        // colorMat.At<Bgr>(y, x) = currentColor;
    }
}
方法2:直接操作Data指针(性能最优,适合大数据量)

如果你的图像尺寸很大,At<T>方法的调用开销会累积,这时候直接操作内存指针会快很多。不过要注意开启项目的不安全代码支持:

Mat grayMat = new Mat(500, 500, DepthType.Cv8U, 1);

// 锁定Mat的内存并获取指针,用using确保内存正确释放
using (var dataPtr = grayMat.GetDataPointer())
{
    int stride = grayMat.Step; // 每行的字节数(步长)
    unsafe
    {
        byte* basePtr = (byte*)dataPtr;
        for (int y = 0; y < grayMat.Rows; y++)
        {
            // 获取当前行的起始指针
            byte* rowPtr = basePtr + y * stride;
            for (int x = 0; x < grayMat.Cols; x++)
            {
                rowPtr[x] = (byte)((x * y) % 256);
            }
        }
    }
}
方法3:通过数组+SetData批量赋值

如果可以先把所有像素值存入数组,再一次性写入Mat,这种方式也很方便:

int width = 300;
int height = 300;
Mat grayMat = new Mat(height, width, DepthType.Cv8U, 1);

// 创建对应大小的像素数组
byte[] pixelArray = new byte[width * height];

// 先给数组赋值
for (int i = 0; i < pixelArray.Length; i++)
{
    int y = i / width;
    int x = i % width;
    pixelArray[i] = (byte)((x - y) % 256);
}

// 把数组数据写入Mat
grayMat.SetData(pixelArray);
关键注意事项
  • 必须匹配像素类型:比如8位单通道用byte,16位单通道用ushort,32位浮点用float;彩色通道对应Bgr、Rgb等Emgu CV提供的颜色结构。
  • 坐标顺序是**(y, x)**:也就是先访问行,再访问列,搞反的话图像会出现奇怪的变形。
  • 指针操作需要开启不安全代码:右键项目→属性→生成→勾选"允许不安全代码"。

内容的提问来源于stack exchange,提问作者user9733371

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:55:51