【问题标题】:Translate Python function to apply mask to image into Java翻译 Python 函数以将蒙版应用于图像到 Java
【发布时间】:2017-08-13 22:33:09
【问题描述】:

我正在尝试将以下用于将掩码应用于图像的 Python 函数转换为 Java:

# Applies an image mask.
def region_of_interest(img, vertices):
    #defining a blank mask to start with
    mask = np.zeros_like(img)   

    #defining a 3 channel or 1 channel color to fill the mask with depending on the input image
    if len(img.shape) > 2:
        channel_count = img.shape[2]  # i.e. 3 or 4 depending on your image
        ignore_mask_color = (255,) * channel_count
    else:
        ignore_mask_color = 255

    #filling pixels inside the polygon defined by "vertices" with the fill color    
    cv2.fillPoly(mask, vertices, ignore_mask_color)

    #returning the image only where mask pixels are nonzero
    masked_image = cv2.bitwise_and(img, mask)
    return masked_image

到目前为止,这就是我所拥有的:

public static opencv_core.Mat applyMask(opencv_core.Mat image, opencv_core.MatVector vertices) {
  opencv_core.Mat mask = opencv_core.Mat.zeros(image.size(), opencv_core.CV_8U).asMat();

  opencv_core.Scalar color = new opencv_core.Scalar(image.channels()); // 3
  double[] colors = new double[] {
    255.0, 255.0, 255.0, 255.0,
    255.0, 255.0, 255.0, 255.0,
    255.0, 255.0, 255.0, 255.0};
  color.put(colors, 0, colors.length);

  opencv_imgproc.fillPoly(mask, vertices, color);

  opencv_core.Mat dst = new opencv_core.Mat();
  opencv_core.bitwise_and(image, mask, dst);
  return dst;
}

但是,它不起作用。当我尝试调用此方法时,如下例所示:

opencv_core.MatVector points = new opencv_core.MatVector(
  new opencv_core.Mat(2, 3, opencv_core.CV_32F, new IntPointer(1, 2, 3, 4, 5, 6))
);

opencv_core.MatVector vertices = new opencv_core.MatVector(points);
opencv_core.Mat masked = LaneManager.applyMask(src, vertices);

(我假设这是构建一个由三个点组成的 2x3 矩阵的正确方法,每个点有两个坐标 (1,2)(3, 4)(5,6)

我得到一个例外:

java.lang.RuntimeException: std::bad_alloc
at org.bytedeco.javacpp.opencv_imgproc.fillPoly(Native Method)

我正在使用 org.bytedeco.javacpp-presets:opencv-platform:3.2.0-1.3 通过 Maven Central 提供的 OpenCV。

我必须承认我在这里不知所措:与上面的 Python 函数做同样事情的惯用 Java 方式是什么?

【问题讨论】:

  • 我认为您正在寻找的内容与其他 stackoverflow 帖子 stackoverflow.com/questions/221830/… 有关。希望这能有所帮助。
  • 如何初始化发送到 applyMask 的 src 变量?
  • 一个可疑的事情是,您显然是在为具有 12 个颜色分量的 3 通道图像定义颜色。这不可能。
  • @Daedalus 我只是在调用opencv_core.Mat src = opencv_imgcodecs.imread(filename);,其中filename 是带有文件路径的String
  • @Dave 用opencv_core.Scalar color = new opencv_core.Scalar(255, 255, 255, 0); 替换颜色也不起作用,并给出相同的错误消息。

标签: java opencv mask


【解决方案1】:

好吧,我终于想通了。如果你定义你的坐标:

int[] points = new int[] {x1, y1, x2, y2, ...};

然后您可以使用以下代码简单地应用掩码:

opencv_core.Mat mask = new opencv_core.Mat(image.size(), image.type());

// Array of polygons where each polygon is represented as an array of points
opencv_core.Point polygon = new opencv_core.Point();
polygon.put(points, 0, points.length);
opencv_imgproc.fillPoly(mask, polygon, new int[] {points.length / 2}, 1, new opencv_core.Scalar(255, 255, 255, 0));

opencv_core.Mat masked = new opencv_core.Mat(image.size(), image.type());
opencv_core.bitwise_and(image, mask, masked);

其中image 是原始图像,masked 是蒙版结果。

问题在于原始点列表没有正确定义。

【讨论】:

    【解决方案2】:

    也许一些高手有完整的答案。这里值得深思:

    1. Java API 是 CPP API 的直接副本:http://opencv.org/opencv-java-api.html
    2. 错误std::bad_alloc 发生在您未能分配所需的存储空间时。 (http://answers.opencv.org/question/28959/cascade-training-killed-and-bad_alloc/)

    3. 有两种 CPP 方法:
    4. 您不需要从Mat 转换为InputArray,但您可以(并且应该)只传递一个Mat 对象,其中请求InputArray (https://stackoverflow.com/a/32976883/1587329)

    【讨论】:

    • 感谢您对此进行调查,但这无济于事。在 Java 端公开的 fillPoly 方法中没有一个采用 InputArray。他们要么接受Mat 要么接受UMat。我认为我的问题更多在于没有正确定义点列表。例如,如果您能给我一个示例,说明如何使用包含 4 个点的列表(每个点有 2 个坐标)创建 points 参数,将会很有帮助。
    • @zugaldia:感谢您的反馈。您是否尝试过内存选项来增加堆大小,例如 f.ex。 -Xmx512m?
    • 是的。我认为他们的问题是我想使用方法public static native void fillPoly(Mat blackImg, MatVector points, Scalar whiteColor);,但我没有正确定义MatVector points。我如何为这个用例创建一个新的MatVector
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 2016-08-31
    • 2019-06-16
    • 1970-01-01
    • 2018-07-29
    相关资源
    最近更新 更多