I've read online中,当您在OpenCV中创建子垫时,它共享父垫的图像缓冲区:

java - OpenCV(Java)子垫似乎没有与父垫共享缓冲区?-LMLPHP

但是,这似乎不是我在Android上从Java使用OpenCV时遇到的问题。

这是一个片段,它构成了子垫,然后用纯蓝色填充。但是,呈现在屏幕上时,原始垫保持不变:

//Create submat
submat1 = input.submat(new Rect(sub1pointA, sub1pointB));

//Fill submat with solid color
Imgproc.rectangle(
    submat1 ,
    new Point(0,0),
    new Point(submat1.width(), submat1.height()),
    new Scalar(0, 0, 255), -1);

但是,如果我将对rectangle()的调用更改为可以在input垫上进行操作,则确实可以在屏幕上看到一个纯蓝色矩形。是什么赋予了?我是否缺少明显的东西,还是在使用OpenCV for Java时子垫未与其父共享缓冲区?

最佳答案

我发现了问题。代码在循环中运行(因为从相机接收到每一帧),而不仅仅是一次。子垫只在循环中第一次创建,因为它应该共享父对象的缓冲区,所以当父对象使用相机的下一帧进行更新时,应该会对其进行更新。问题是我将相机的帧传递到原位之前将其旋转,然后将其传递给我的处理函数:

Core.rotate(frame, frame, Core.ROTATE_90_COUNTERCLOCKWISE);
processFrame(frame);

看起来,当旋转90度时,将重新分配支持数组(我想这是有道理的,因为行和列的数量将被反转),并且这种重新分配会断开与先前创建的子垫的链接。

如果我不就地旋转,而是旋转到单独的Mat 上,然后将该Mat传递给我的处理函数,那么一切都会按预期进行(我在屏幕上看到一个蓝色矩形)。
Core.rotate(frame, rotatedFrame, Core.ROTATE_90_COUNTERCLOCKWISE);
processFrame(rotatedFrame);

10-06 04:56