Конвертировать PImage в Mat - Java OpenCV в обработчике IDE P3D (OpenGL) - PullRequest
0 голосов
/ 09 марта 2020

Я написал код для преобразования между OpenCV Mat в PImage (ARGB) и обратно. Я использую веб-камеру в качестве входных данных с захваченной библиотекой обработки видео. Он работает в рендерере Java2D, но не в рендерере P2D или P3D. В чем может быть проблема?

Попытка использовать операторы loadPixels() и updatePixels() - не работает. Также примечательно то, что изображение с камеры в P3D-рендере нельзя скопировать в PImage с помощью pimage = cam.copy(); или 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;
    }


1 Ответ

1 голос
/ 14 апреля 2020

Интересная тема. Это может быть как-то связано с синхронизацией и доступом к пиксельным данным (которые может скрыть 2D-рендеринг).

Вы можете обойти это, явно скопировав данные с помощью get () :

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();
}
...