【问题标题】:OpenCV for Android - Access elements of MatOpenCV for Android - 访问 Mat 的元素
【发布时间】:2016-01-12 23:35:32
【问题描述】:

在 OpenCV4Android 中访问和修改 Mat 的各个元素的标准方法是什么?另外,BGR(我认为这是默认的)和灰度的数据格式是什么?
编辑:让我们更具体一点。 mat.get(row, col) 返回一个双精度数组。这个数组中有什么?

【问题讨论】:

  • 你读过documentation吗?
  • 当然。在我最初的问题中甚至没有必要提及它,因为它仅指使用指针的 C++ API,并且还因为它主要将 Mat 作为容器结构而不是您可以放入其中的东西。
  • 好吧,我只知道 C++ API,所以如果您对此不感兴趣,我无法帮助您。如果您需要其他人的帮助,您应该尝试使您的问题更具体。就像你说的,Mat 是一个容器。 mat.get(row,col) 返回的内容完全取决于您在该垫子中放入的内容。 BGR 可能是 opencv 中某些函数的默认格式,但 Mat 与类型无关。通常虽然图像存储为 uchars。

标签: android opencv


【解决方案1】:

如果您只想访问一些像素,请使用 double[] get(int row, int col) 并使用 put(int row, int col, double.. . 数据)。如果您正在考虑访问整个图像或在循环中迭代图像的数据,那么您应该做的最好的事情是将 Mat 数据复制到 Java 原始数据类型中。完成数据操作后,只需将数据复制回 Mat 结构即可。

图像使用 CV_8U,如果您有灰度图像,它将使用 CV_8UC1 如果您有 RGB 图像,它将使用 CV_8UC3 的 Mat >(CV_8U 的 3 个通道)。 CV_8U 相当于java中的字节。 :)

我可以给你和我在 Java(Android 平台)中使用的方法示例来二值化灰度图像:

private Mat featuresVectorBinarization(Mat fv){

    int size = (int) fv.total() * fv.channels();
    double[] buff = new double[size];
    fv.get(0, 0, buff);

    for(int i = 0; i < size; i++)
    {
        buff[i] = (buff[i] >= 0) ? 1 : 0;
    }

    Mat bv = new Mat(fv.size(), CvType.CV_8U);
    bv.put(0, 0, buff);
    return bv;
}  

希望对您有所帮助。

【讨论】:

  • 你能检查一下这个几乎与这个问题相似的问题吗stackoverflow.com/questions/29204124/…
  • @AshokVarma 抱歉,但从未将 OpenCV 与 C++ 接口一起使用,所以我什至不知道 MatIterator 是什么。但是,如果 Iterator 是一种循环 Image Mat 的方法,那么您可以使用我上面的代码实现相同的目的。使用 Mat 的 get 方法将您的 Mat 序列化为 Buffer(上面代码中的 buff),然后循环执行您想要的操作。最后创建一个目标 Mat(结果)并使用 put 反序列化。我不知道这是否有帮助,但这基本上是上面的代码正在做的事情,在这种情况下,我将图像转换为黑白。
  • Mat.get() 的第三个参数是什么?这个方法在documentation中没有描述。 :s
  • @Solace Mat.get() 的第三个参数是您要将值存储到的数组,您会看到这样的函数不会返回任何像素值,而函数 get() 使用只有 2 个参数返回此答案中提到的双精度数组。我同意,文档很糟糕。
【解决方案2】:

在 OpenCV4Android 中访问和修改 Mat 的各个元素的标准方法是什么?

Mat 是我们在数学中称为“矩阵”的东西——由行和列组成的矩形数组。在图像 Mat 的情况下,这些“数量”表示像素(例如,矩阵的每个元素都可以是图像 Mat 中每个像素的 color)。来自this教程:

在上图中你可以看到汽车的镜子什么都不是 不仅仅是一个包含像素所有强度值的矩阵 点。

那么你将如何遍历一个矩阵呢?这个怎么样:

for (int row=0; row<mat.rows(); row++) {
  for (int col=0; col<mat.cols(); col++ ) {
    //...do what you want.. 
    //e.g. get the value of the 3rd element of 2nd row 
    //by mat.get(2,3);
  }
}

在 OpenCV4Android 中访问和修改 Mat 的各个元素的标准方法是什么?

您可以使用Mat 的函数get(x)(y) 获取元素的值,其中x 是该元素的第一个坐标(行号),y 是该元素的第二个坐标(列号)。例如,要获取名为bgrImageMatBGR 图像Mat 的第7 行的第4 个元素,请使用Matget 方法获取double 类型的数组,该数组将具有大小3 中的每个数组元素代表 BGR 图像格式的 BlueGreenRed 通道中的每一个。

double [] bgrColor = bgrImageMat.get();

另外,BGR(我认为这是默认的)和灰度的数据格式是什么?编辑:让我们更具体一点。 mat.get(row, col) 返回一个双精度数组。这个数组里有什么?

您可以从网上了解 BGR 颜色格式和灰度。例如BGRGrayscale

简而言之,BGR 颜色格式有 3 个通道:BlueGreenRed。所以mat.get(row, col)返回的double数组,当matBGR图像时,是一个大小为3的数组,它的每个元素都包含Bluegreenred 频道。

同样,灰度格式是 1 通道颜色格式,因此返回的 double 的大小为 1。

【讨论】:

    【解决方案3】:

    通过学习 OpenCV Mat 对象我可以理解的是,Mat 是可以表示任何 W x H 像素图像的对象。

    现在假设您要访问图像的中心像素,然后

    X = W/2 Y = H/2

    然后你可以访问像素数据如下 double[] 数据 = matObject.get(x,y);

    现在数据代表什么,数据数组的大小是多少。这取决于图像类型。 如果图像是灰度图像,则 data.length = 1 ,因为只有一个通道,并且 data[0] 表示该像素的颜色值,即。 0(黑色)- 255(白色)

    如果图像是彩色图像,则 data.length = 4(rgba) ,因为有四个通道,并且 data[0-n] 表示该像素的颜色值

    【讨论】:

      猜你喜欢
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 2011-11-03
      • 1970-01-01
      相关资源
      最近更新 更多