循环并更改Mat OpenCV Android

时间:2015-12-28 09:00:20

标签: java android opencv image-processing pixel

我现在正在基于样本颜色blob跟踪方法构建项目。我在轮廓周围使用了边界矩形来指示斑点。现在我想通过使用纠错方法来改进该算法。我现在所做的只是使用elemsum方法对rect区域中的像素进行求和,并计算平均强度并将其设置为每帧中的新斑点检测参数。然而,问题在于它不准确,因为轮廓外但在边界矩形内的那些像素也将被计数。结果很糟糕。

为了解决这个问题,我用另一个简单的方法循环遍历矩形区域(这是一个submat)中的每个像素,并将所有像素值设置在所需的(或之前的)hsv标量之外。然后再次总结所有像素并计算平均强度。这将更准确,更容易解决问题。问题是程序在手机上运行得太慢(每秒大约1帧),但结果是准确的。

我在网上找到了一些关于如何使用mat.forEach在c ++中完成的资料。我不想做ndk的事情,我想知道是否有更有效的方法在Java(Android)中做到这一点。

更新: 事实证明,我可以通过简单地降低采样率来解决问题。不是计算所有像素的平均强度,而是只有少数几个像素可以完成这项工作。我的代码:

for (int i=0; i< bounding_rect_hsv.rows();i+=10){
                for (int j=0; j<bounding_rect_hsv.cols();j+=10){
                    double[] data = bounding_rect_hsv.get(i, j);
                    for (int k = 0; k < 3; k++){
                        if (data[k] > new_hsvColor.val[k] + 30 || data[k] < new_hsvColor.val[k] - 30) {
                            data[k] = new_hsvColor.val[k];
                        }
                    }
                    bounding_rect_hsv.put(i, j, data); //Puts element back into matrix
                }
            }

我的源代码:

Rect rect = Imgproc.boundingRect(points);

// draw enclosing rectangle (all same color, but you could use variable i to make them unique)
Imgproc.rectangle(original_frame, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 0, 0, 255), 3);

//Todo: use the bounding rectangular to calculate average intensity (turn the pixels out of the contour to new_hsvColor)
//Just change the boundary values would be enough
bounding_rect_rgb = original_frame.submat(rect);
Imgproc.cvtColor(bounding_rect_rgb, bounding_rect_hsv, Imgproc.COLOR_RGB2HSV_FULL);

//Todo: change the logic so that pixels outside the contour will be changed to new_hsvColor

for (int i=0; i< bounding_rect_hsv.rows();i++){
    for (int j=0; j<bounding_rect_hsv.cols();j++){
        double[] data = bounding_rect_hsv.get(i, j);
        for (int k = 0; k < 3; k++){
        if (data[k] > new_hsvColor.val[k] + 30 || data[k] < new_hsvColor.val[k] - 30)
        data[k] = new_hsvColor.val[k];
        }
        bounding_rect_hsv.put(i, j, data); //Puts element back into matrix
    }
}

1 个答案:

答案 0 :(得分:0)

如果你想计算轮廓内像素的 mean 值,你可以简单地说:

  1. 在黑色(CV_FILLED)初始化Scalar(255)图片上使用drawContours参数Scalar(0)和颜色CV_8UC1创建一个模板,其大小与原始图片相同图像。
  2. 使用mean计算蒙版下的像素平均值。
  3. 您也不需要在每个区域(Rect)转换为HSV,但您可以将整个图像转换一次,然后直接在HSV图像上访问所需区域。

    在一般情况下,您想要对许多矩形区域的像素值求和,您可能更喜欢计算integral图像并计算总和作为右下角和左上角的值的差值矩形位置。