How can I get and set pixel values of an EmguCV Mat image?

匿名 (未验证) 提交于 2019-12-03 01:23:02

问题:

I'm using the EmguCV 3.0.0 wrapper to the OpenCV 3.0 library. I'm using the Mat class in a few places. Here's an example of a single channel, 8x8 image made of double values:

Mat image = new Mat(8, 8, DepthType.Cv64F, 1);

The Image<> class provides reasonable means for getting and setting pixel values, and the method is identical for the Matrix<> class, but it doesn't seem as obvious for the Mat class. The only way I've figured out how to set individual pixel is using a mask:

// set two pixel values, (0,0) to 9.0, (2, 3) to 42.0  Matrix mask = new Matrix(8,8); mask.Data[0, 0] = 1; image.SetTo(new MCvScalar(9.0), mask);  mask = new Matrix(8,8); mask.Data[2, 3] = 1; image.SetTo(new MCvScalar(42.0), mask);

This is feels like it should be two lines, not six, so I feel like I'm missing something. Things get even more complicated when the Mat is more than one channel, because Matrix<> is only 2D, so the mask must be used to set the pixel on each channel.

I cannot afford the time or memory to set pixels this way. How can I set pixels with a single method call?

回答1:

You can get elements from Mat by copying unmanaged memory blocks using DataPointer and converting managed to unmanaged types. Setting values is marshaling in the opposite direction.

For an example you can use such an extension class

public static class MatExtension {     public static dynamic GetValue(this Mat mat, int row, int col)     {         var value = CreateElement(mat.Depth);         Marshal.Copy(mat.DataPointer + (row * mat.Cols + col) * mat.ElementSize, value, 0, 1);         return value[0];     }      public static void SetValue(this Mat mat, int row, int col, dynamic value)     {         var target = CreateElement(mat.Depth, value);         Marshal.Copy(target, 0, mat.DataPointer + (row * mat.Cols + col) * mat.ElementSize, 1);     }     private static dynamic CreateElement(DepthType depthType, dynamic value)     {         var element = CreateElement(depthType);         element[0] = value;         return element;     }      private static dynamic CreateElement(DepthType depthType)     {         if (depthType == DepthType.Cv8S)         {             return new sbyte[1];         }         if (depthType == DepthType.Cv8U)         {             return new byte[1];         }         if (depthType == DepthType.Cv16S)         {             return new short[1];         }         if (depthType == DepthType.Cv16U)         {             return new ushort[1];         
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!