如何在C#的EmguCV中获取Mat类型图像的像素值?
在EmguCV中直接操作Mat获取像素值的方法
EmguCV的Mat类本身提供了无需转换为Image<>类型的像素访问方式,下面分场景说明具体实现:
1. 单通道灰度图(如8位无符号格式 CV_8UC1)
单个像素访问(简单直观)
使用At方法直接按坐标获取,注意坐标顺序是行(y)在前,列(x)在后:
// 获取(x,y)位置的灰度值 byte pixelValue = image.At<byte>(y, x);
批量像素遍历(高效处理大量像素)
通过指针直接访问内存,搭配GetDataPointer()确保内存锁定安全:
using (var dataPtr = image.GetDataPointer()) { byte* ptr = (byte*)dataPtr.Pointer; int rowStride = image.Cols; // 单通道每行字节数等于列数 for (int y = 0; y < image.Rows; y++) { for (int x = 0; x < image.Cols; x++) { byte value = ptr[y * rowStride + x]; // 处理像素值逻辑 } } }
2. 多通道图像(如BGR三通道格式 CV_8UC3)
单个像素的通道值获取
用At<MCvScalar>获取所有通道值,EmguCV默认是BGR顺序:
MCvScalar pixel = image.At<MCvScalar>(y, x); byte blue = pixel.V0; // 蓝色通道 byte green = pixel.V1; // 绿色通道 byte red = pixel.V2; // 红色通道
批量遍历多通道像素
通过指针按通道偏移访问,效率更高:
using (var dataPtr = image.GetDataPointer()) { byte* ptr = (byte*)dataPtr.Pointer; int rowStride = image.Cols * 3; // 三通道每行字节数=列数×3 for (int y = 0; y < image.Rows; y++) { for (int x = 0; x < image.Cols; x++) { int baseIndex = y * rowStride + x * 3; byte blue = ptr[baseIndex]; byte green = ptr[baseIndex + 1]; byte red = ptr[baseIndex + 2]; // 处理像素逻辑 } } }
3. 其他数据类型的图像
只需替换At方法的泛型类型或指针类型即可:
- 16位无符号单通道:
image.At<ushort>(y, x) - 32位浮点单通道:
image.At<float>(y, x) - 多通道浮点类型:通过
MCvScalar的V0/V1/V2获取对应浮点值
优化技巧
如果Mat是连续存储的(image.IsContinuous返回true),可以把整个图像当作一维数组处理,跳过行偏移计算进一步提升效率:
if (image.IsContinuous) { int totalPixels = image.Rows * image.Cols; byte* ptr = (byte*)image.GetDataPointer().Pointer; // 单通道示例 for (int i = 0; i < totalPixels; i++) { byte value = ptr[i]; } }
内容的提问来源于stack exchange,提问作者JavadMH13
相关产品推荐
相关产品推荐

