无法克隆ArrayList<MatOfPoint>元素

3

我正在使用以下代码来克隆我的数组:

aproximatedContours = cloneList(contours);

方法主体:
public static ArrayList<MatOfPoint> cloneList(ArrayList<MatOfPoint> contours) {
    ArrayList<MatOfPoint> clone = new ArrayList<MatOfPoint>(contours.size());
    for(MatOfPoint item: contours) 
        clone.add((MatOfPoint) item.clone()); // Line 479
    return clone;
}

然而,尽管轮廓(contours)和克隆(clone)都是ArrayList的类型,显然它们的元素都是MatOfPoint的类型,但我仍然遇到以下错误:
08-16 16:34:16.015: W/System.err(21747): java.lang.ClassCastException: org.opencv.core.Mat cannot be cast to org.opencv.core.MatOfPoint
08-16 16:34:16.020: W/System.err(21747):    at com.example.objecttracker.ObjectTracker.cloneList(ObjectTracker.java:469)
08-16 16:34:16.020: W/System.err(21747):    at com.example.objecttracker.ObjectTracker.onCameraFrame(ObjectTracker.java:446)
08-16 16:34:16.020: W/System.err(21747):    at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:387)
08-16 16:34:16.020: W/System.err(21747):    at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:321)
08-16 16:34:16.025: W/System.err(21747):    at java.lang.Thread.run(Thread.java:856)

有人知道这里发生了什么吗?

根据您的请求已更新。 - Marek
3个回答

4
似乎在MatOfPoint中存在API漏洞:它继承了Matclone方法,因此当您调用它时,您会得到一个普通的Mat(假设只复制了超类的字段)。总体来说,MatOfPoint的语义似乎没有清晰地定义,也没有复制的机制。
编辑:如果原生对象句柄包含所有必要的数据,则可以使用new MatOfPoint(Mat m)作为复制构造函数。

2
可能复制构造函数是正确的方法,但您需要检查源代码以查看它是否与MatOfPoint实例正常工作。 - Duncan Jones
我在使用OpenCV进行android开发时遇到了很多问题。是否有其他好的CV库可供选择?您确定这是一个错误吗?您可以帮忙查看我的奖励问题吗:http://stackoverflow.com/questions/18073239/opencv-java-convexity-defects-computer-vision - Marek
@Marek 请不要使用注释来提出进一步的问题。 - Duncan Jones
这是一个 bug,因为一个类只有在它是 final 时才应该实现 clone(),而 Mat 也没有实现 Cloneable 接口。 - chrylis -cautiouslyoptimistic-
根据Duncan Jones的说法,新的MatOfPoint(Mat m)不会有所帮助。那么应该如何正确地拥有两个独立的列表?我想处理第二个列表,其中包含与第一个列表相同的元素,并且我不想更改第一个列表中的元素。如果ArrayList包含不同的元素,我的代码是否有效?例如Point? - Marek
1
@Marek 我并没有说这不会有帮助。我只是建议你查看源代码以确认 - 你做到了吗? - Duncan Jones

1

克隆是一个非常棘手的问题,也许在opencv中没有正确实现


0

看起来这是一个库的问题,因为MatOfPoint奇怪地依赖于Mat的克隆方法,该方法将克隆不是MatOfPoint的Mat对象。

作为一种解决方法,您可以尝试不依赖clone()方法,而是显式地自己构建副本(未经测试):

    // Use a copy ctor
    clone.add(new MatOfPoint(item));

无法正常工作 - MatOfPoint具有相同的引用,因此当我更改克隆元素列表元素时,列表元素也会发生变化... - Marek
你可以尝试深度克隆这些值。也许可以像这样:new clone.add(new MatOfPoint(item.toArray())); - cyberz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接