JavaCV 采集攝像頭及桌面視頻數據


javacv 封裝了javacpp-presets庫很多native API,簡化了開發,對java程序員來說比較友好。

之前使用JavaCV庫都是使用ffmpeg native API開發,這種方式使用起來太多坑了,還是使用JavaCV封裝好的庫開發方便。

其他關於JavaCV的文章,可以通過下面的鏈接查看:
JavaCV-開發系列文章匯總篇(https://www.cnblogs.com/itqn/p/14696221.html)

引入依賴

前幾天剛剛發布了1.5.5,這里使用最新的javacv依賴:

<properties>
  <javacpp.version>1.5.5</javacpp.version>
</properties>
<dependencies>
  <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>${javacpp.version}</version>
  </dependency>
  <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>${javacpp.version}</version>
  </dependency>
</dependencies>

OpenCVFrameGrabber采集攝像頭數據

javacv的demo中有攝像頭及麥克風采集音視頻數據的例子(WebcamAndMicrophoneCapture),例子采集攝像頭數據使用的就是OpenCVFrameGrabber,視頻畫面回顯采用的是CanvasFrame

public class Sample01_Camera {

  @SuppressWarnings("resource")
  public static void main(String[] args) throws Exception {
    OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
    grabber.setImageWidth(1280);
    grabber.setImageHeight(720);
    grabber.start();
    CanvasFrame canvas = new CanvasFrame("攝像頭");
    canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    canvas.setAlwaysOnTop(true);

    while (canvas.isDisplayable()) {
      canvas.showImage(grabber.grab());
      TimeUnit.MILLISECONDS.sleep(40);
    }
    
    grabber.stop();
  }
}

畫面預覽效果圖:

FFmpegFrameGrabber采集攝像頭數據

FFmpegFrameGrabber采集攝像頭數據需要指定輸入,如:video=Integrated Camera,這里Integrated Camera是攝像頭的設備名。

可以通過以下方式獲取攝像頭設備名:

  1. 打開“計算機管理”->“設備管理器”->“照相機”
  2. 使用ffmpeg命令,具體查看之前我的文章 JavaCV FFmpeg采集攝像頭YUV視頻數據

采用FFmpeg查看本機設備的命令:

ffmpeg.exe -list_devices true -f dshow -i dummy  

FFmpegFrameGrabber的使用方式跟OpenCVFrameGrabber的方式是一樣的,只不過OpenCVFrameGrabber指定的是設備索引,而FFmpegFrameGrabber指定設備輸入。

public class Sample02_Camera {
  @SuppressWarnings("resource")
  public static void main(String[] args) throws Exception {
    FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("video=Integrated Camera");
    grabber.setImageWidth(1280);
    grabber.setImageHeight(720);
    grabber.setFormat("dshow");
    grabber.start();
    CanvasFrame canvas = new CanvasFrame("攝像頭");
    canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    canvas.setAlwaysOnTop(true);

    while (canvas.isDisplayable()) {
      canvas.showImage(grabber.grab());
      TimeUnit.MILLISECONDS.sleep(40);
    }

    grabber.stop();
  }
}

FFmpegFrameGrabber采集桌面數據

FFmpegFrameGrabber采集桌面采用gdigrab,參考雷神的博客 FFmpeg源代碼簡單分析:libavdevice的gdigrab

public class Sample03_Desktop {

  // https://blog.csdn.net/leixiaohua1020/article/details/44597955
  @SuppressWarnings("resource")
  public static void main(String[] args) throws Exception {
    FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("desktop");
    grabber.setFormat("gdigrab");
    grabber.setOption("offset_x", "0");
    grabber.setOption("offset_y", "0");
    grabber.setOption("framerate", "25");
    grabber.setOption("draw_mouse", "0");
    grabber.setOption("video_size", "1920x1080");
    // 這種形式,雙屏有問題
    // grabber.setImageWidth(1920);
    // grabber.setImageWidth(1080);
    grabber.start();
    CanvasFrame canvas = new CanvasFrame("攝像頭");
    canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    canvas.setAlwaysOnTop(true);

    while (canvas.isDisplayable()) {
      canvas.showImage(grabber.grab());
      TimeUnit.MILLISECONDS.sleep(40);
    }

    grabber.stop();
  }
}

畫面預覽效果圖:

這里由於我的電腦是2K屏,這里1920x1080只是截圖了屏幕的一部分。

=========================================================
HiIT青年
關注公眾號,閱讀更多關於JavaCV的文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM