将Python函数转换为Java,以将掩码应用于图像
我正在尝试将以下Python函数(将掩码应用于图像)转换为Java:将Python函数转换为Java,以将掩码应用于图像,java,opencv,mask,Java,Opencv,Mask,我正在尝试将以下Python函数(将掩码应用于图像)转换为Java: #应用图像遮罩。 def感兴趣区域(img、顶点): #定义要开始的空白掩码 掩码=np.类零(img) #根据输入图像定义3通道或1通道颜色以填充遮罩 如果长度(图像形状)>2: 通道计数=图像形状[2]#即3或4,取决于您的图像 忽略遮罩颜色=(255,)*通道计数 其他: 忽略遮罩颜色=255 #使用填充颜色填充由“顶点”定义的多边形内的像素 cv2.fillPoly(遮罩、顶点、忽略遮罩颜色) #仅在遮罩像素不为零的情
#应用图像遮罩。
def感兴趣区域(img、顶点):
#定义要开始的空白掩码
掩码=np.类零(img)
#根据输入图像定义3通道或1通道颜色以填充遮罩
如果长度(图像形状)>2:
通道计数=图像形状[2]#即3或4,取决于您的图像
忽略遮罩颜色=(255,)*通道计数
其他:
忽略遮罩颜色=255
#使用填充颜色填充由“顶点”定义的多边形内的像素
cv2.fillPoly(遮罩、顶点、忽略遮罩颜色)
#仅在遮罩像素不为零的情况下返回图像
蒙版图像=cv2.按位和(img,蒙版)
返回蒙版图像
到目前为止,我得到的是:
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)
我使用的OpenCV是由org.bytedeco.javacpp预置提供的:OpenCV平台:3.2.0-1.3
通过Maven Central
我必须承认,我在这里有些不知所措:与上面的Python函数做相同事情的惯用Java方式是什么?也许某个天才有完整的答案。以下是值得思考的问题:
std::bad_alloc
。()
- C++:,和
- C++:
Mat
转换到InputArray
,但是您可以(并且应该)只传递一个Mat
对象,其中请求了InputArray
()
好吧,我终于明白了。如果使用以下方法定义坐标:
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
是屏蔽结果
问题是原始的点列表没有正确定义。我想你要找的是与另一个stackoverflow帖子有关的。希望这能有所帮助。您如何初始化发送到applyMask的src变量?一个可疑的问题是,您显然是在为具有12个颜色分量的3通道图像定义颜色。这不可能是对的。@Daedalus我只是在调用
opencv\u core.Mat src=opencv\u imgcodecs.imread(文件名)
其中filename
是带有文件路径的字符串。@Dave用opencv_core.Scalar color=new opencv_core.Scalar(255,255,255,0)替换颜色代码>也不起作用,并给出相同的错误消息。感谢您对此进行调查,但这没有帮助。Java端公开的fillPoly
方法没有一个采用InputArray
。他们要么使用Mat
或UMat
。我认为我的问题更多的是没有正确定义点列表。例如,如果您能给我一个如何创建points参数的示例,例如,一个包含4个点的列表,每个点有2个坐标,那将非常有帮助。@zugaldia:谢谢您的反馈。您是否尝试过使用内存选项来增加堆大小,如在f.ex中<代码>-Xmx512m
?是。我认为他们的问题是我想使用方法publicstatic原生voidfillpoly(matblackimg,MatVector points,scalarwhitecolor)代码>但我没有正确定义拟向量点。我如何为这个用例创建一个新的MatVector
?