在处理IDEP3D(OpenGL)渲染器中将PImage转换为Mat-JavaOpenCV
我编写了一个代码,在OpenCV Mat到PImage(ARGB)和返回之间进行转换。我使用网络摄像机作为输入,通过处理视频库捕获。它适用于Java2D渲染器,但不适用于P2D或P3D渲染器。可能是什么问题 它尝试使用在处理IDEP3D(OpenGL)渲染器中将PImage转换为Mat-JavaOpenCV,java,image,opencv,processing,Java,Image,Opencv,Processing,我编写了一个代码,在OpenCV Mat到PImage(ARGB)和返回之间进行转换。我使用网络摄像机作为输入,通过处理视频库捕获。它适用于Java2D渲染器,但不适用于P2D或P3D渲染器。可能是什么问题 它尝试使用loadPixels()和updatePixels()语句-它不起作用。另外,P3D渲染器中的相机图像无法通过PImage=cam.copy()复制到PImage或pimage=cam.get()但必须像pimage=cam那样分配;我不明白这是为什么 我使用的是原生Opencv
loadPixels()
和updatePixels()
语句-它不起作用。另外,P3D渲染器中的相机图像无法通过PImage=cam.copy()复制到PImage代码>或pimage=cam.get()代码>但必须像pimage=cam那样分配;我不明白这是为什么
我使用的是原生Opencv Java 3.4
import processing.video.*;
Capture cam;
import java.nio.*; //to convert Mat PImage
byte [] bArray;
int [] iArray;
int pixCnt1, pixCnt2;
PImage camStream;// camera frame
//----------------------
void setup() {
size(640, 480); //PImage to mat does not work with P2D for some reason?
//size(640,480,P3D);// this does NOT WORK
String[] cameras = Capture.list();
if (cameras == null) {
println("Failed to retrieve the list of available cameras, will try the default...");
cam = new Capture(this, 640, 480);
}
if (cameras.length == 0) {
println("There are no cameras available for capture.");
exit();
} else {
println("Available cameras:");
//printArray(cameras);
cam = new Capture(this, cameras[0]);
//cam = new Capture(this, 1280, 720, "c922 Pro Stream Webcam", 5);
cam.start();
}
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
println(Core.VERSION);
pixCnt1 = width*height*4;// number of bytes in the pixel buffer.
pixCnt2 = width*height;//number of integers in the PImage pixels buffer.
bArray = new byte[pixCnt1]; //temporary byte array buffer for OpenCV cv::Mat.
iArray = new int[pixCnt2];//temporary integer array buffer for PImage pixels.
camStream = createImage(640, 480, ARGB);
}
void draw() {
background(0);
if (cam.available() == true) {
cam.read();
camStream = cam;
Mat frame = toMat(camStream ); //CvType=CV_8UC4
//Mat undistorted = frame.clone();
camStream = toPImage(frame);
}
image(camStream, 0, 0, 640, 480);
}
//--------------------------------------------------------------------------
// Convert PImage (ARGB) to Mat (CvType = CV_8UC4)
Mat toMat(PImage image) {
//image.loadPixels(); //???
int w = image.width;
int h = image.height;
Mat mat = new Mat(h, w, CvType.CV_8UC4);
byte[] data8 = new byte[w*h*4];
int[] data32 = new int[w*h];
arrayCopy(image.pixels, data32);
ByteBuffer bBuf = ByteBuffer.allocate(w*h*4);
IntBuffer iBuf = bBuf.asIntBuffer();
iBuf.put(data32);
bBuf.get(data8);
mat.put(0, 0, data8);
//image.updatePixels();
return mat;
}
//---------------------------------------------------------------------------
// Convert Mat (CvType=CV_8UC4) to PImage (ARGB)
PImage toPImage(Mat mat) {
int w = mat.width();
int h = mat.height();
PImage image = createImage(w, h, ARGB);
//image.loadPixels(); //???
byte[] data8 = new byte[w*h*4];
int[] data32 = new int[w*h];
mat.get(0, 0, data8);
ByteBuffer.wrap(data8).asIntBuffer().get(data32);
arrayCopy(data32, image.pixels);
//image.updatePixels(); //???
return image;
}
有趣的问题。它可能与定时和像素数据访问有关(2D渲染器可能会隐藏这些数据)
您可以通过使用以下方法显式复制数据来解决此问题:
非常感谢你!它就像一个符咒。在用简单的“=”重新说明PVectors变量时,我也发现了一些问题,有时需要使用.copy()或提到.get(),但我没有想到在这个场景中使用它。我仍然不明白背后的逻辑…你对背后的逻辑有什么见解吗?@doku关于PVector.copy()
这听起来像是一个场景,当你需要独立复制数据时,你会操纵对PVector的引用。想象一下,由于不同的原因(渲染/模拟管线的阶段等),对同一数据段有两个或多个引用:如果在一个位置更改该引用,将影响其他位置。在这种情况下,您可以拆分管道,其中最多有一个点的数据是相同的,然后复制数据,以便两个独立的功能可以运行而不会相互影响。HTH@doku我想我会给你指出:可能很方便。(例如,opencv.loadImage(camStream);
然后opencv.getGray()
或opencv.getColor()
以获取Mat
和opencv.getOutput()
以获取PImage
。在这两者之间,您可以进行筛选/等操作。然后直接使用Matopencv.setColor()
/opencv.setGray();`orOpenCV.toProcessing
void draw() {
Mat frame = toMat(camStream ); //CvType=CV_8UC4
camStream = toPImage(frame);
image(camStream, 0, 0, 640, 480);
}
void captureEvent(Capture cam){
cam.read();
// make copy of the data
camStream = cam.get();
}