簡體   English   中英

適用於Android中的opencv的網絡攝像頭捕獲,使用ffmpeg構建並針對android進行編譯

[英]Webcam capture for opencv in Android ,built with ffmpeg and compiled for android

我剛購買了一個在線ip攝像機,主要目的是使用Android平板電腦進行圖像處理和監視。雖然是本地編碼,並且在使用FFMPEG對java,python和C ++進行交叉編譯時可以使用。Videocapture類與ip camera url完美配合。 它顯示了使用rtsp協議進行流傳輸的ipcamera幀。 例如在C ++中

       Mat frame
        Videocapture cap;
         cap.open(rtsp:// the url);
           while(true)
           {
               cap.read(frame);
               waitkey(1);
            } 

代碼完美無瑕地工作,它幾乎沒有延遲地為我提供了LAN上攝像機流的幀。對於python和針對Java進行編譯是相同的。

但是問題來了,因為Android的opencv sdk本身不支持ffmpeg。起初,我不想再用ffmpeg進行編譯,而是換成JavaCV,它帶有預建的ffmpegframegrabber類,並且保留了本地源代碼opencv的代碼。但是當我嘗試在位圖上顯示幀時framegrabber使我失敗了,並且丟包和幀都出現了巨大的渲染問題,幀全亂碼了,也嘗試了FrameRecorder類並在后台記錄了文件,但是結果。 后來我嘗試使用Android的Mediaplayer進行嘗試。

    package com.example.rob.androidipcamera4;

   import android.app.Activity;
   import android.content.Context;
   import android.media.MediaPlayer;
   import android.net.Uri;
   import android.support.v7.app.AppCompatActivity;
   import android.os.Bundle;
   import android.util.Base64;
   import android.view.SurfaceHolder;
   import android.view.SurfaceView;
   import android.view.Window;
   import android.view.WindowManager;


  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Map;

  public class MainActivity extends Activity implements        MediaPlayer.OnPreparedListener,SurfaceHolder.Callback {
final static String RTSP_URL="rtsp://192.168.1.7:554/onvif1";
private static String USERNAME="";
private static String PASSWORD="";
private MediaPlayer mediaplayer;
private  SurfaceHolder surfaceholder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    Window window=getWindow();
    window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
    window.setBackgroundDrawableResource(android.R.color.black);
    setContentView(R.layout.activity_main);
    //Configuring the surfaceview
    SurfaceView surfaceView=(SurfaceView)findViewById(R.id.surfaceView);
    surfaceholder = surfaceView.getHolder();
    surfaceholder.addCallback(this);
    surfaceholder.setFixedSize(320,320);
}

@Override
public void onPrepared(MediaPlayer mp) {
    mediaplayer.start();

}

@Override
public void surfaceCreated(SurfaceHolder sh)  {
    mediaplayer=new MediaPlayer();
    mediaplayer.setDisplay(surfaceholder);
    Context context=getApplicationContext();
    Map<String,String>headers=getRTSPHeaders();
    Uri source=Uri.parse(RTSP_URL);
    try{
        mediaplayer.setDataSource(context,source,headers);
        mediaplayer.setOnPreparedListener(this);
        mediaplayer.prepareAsync();
    }
    catch (Exception e){
        System.out.println("Sorry no media ");
    };
   }

@Override
public void surfaceChanged(SurfaceHolder sh, int f, int w, int h) {}

@Override
public void surfaceDestroyed(SurfaceHolder sh) {
    mediaplayer.release();

}
private  Map<String,String>getRTSPHeaders() {
    Map<String,String>headers=new HashMap<String, String>();
    String basicAuthValue=getBasicAuthValue(USERNAME,PASSWORD);
    headers.put("Authorisation",basicAuthValue);
    return headers;
}
private String getBasicAuthValue(String usr,String pwd){
    String credientials=usr+":"+pwd;
    int flags= Base64.URL_SAFE|Base64.NO_WRAP;
    byte[]bytes=credientials.getBytes();
    return "Basic" + Base64.encodeToString(bytes,flags) ;

}
}

盡管這些幀的分辨率很高,但也給了我一個選擇,即可以拍攝每個幀並進行一些運動檢測,但是實況流中大約有7秒的延遲,這在監視中是完全不可接受的。

所以我想我回到為android編譯ffmpeg的話題了。我只是有點懷疑,因為用opencv編譯的ffmpeg在C ++和Python(在linux上)上都可以完美工作,給了我0.2秒的延遲,是否用android編譯ffmpeg會給我相同的結果,是否可以不使用NDK而以與C ++相同的方式在android中使用Videocapture類? 如果有人曾經使用官方sdk在帶有ipcam的Android平板電腦和手機上嘗試過此操作,那將非常有幫助;或者使用mediaplayer或JavaCV是否還有其他方法可以讓我輕松一點,也不會出現任何亂碼而沒有延遲

配置ffmpeg所需的所有內容將花費一些時間,盡管我有一段時間沒有觸摸它了,也許有些改變了。 最好從尋找一個已經集成了它的github項目開始,然后從那里開始,應該有很多這樣的項目(找到更新的項目)。 大約3年前,當我進行視頻通話時,沒有合適的Android媒體API,目前存在底層回調,因此您應該成功實現所需的任何東西。

我實際上已經通過從源代碼編譯android(armhf)的opencv庫以及包括libav,libswsscale等的ffmpeg庫來解決了這個問題。在最終通過JNI從主程序調用主函數之前,先應用了所有圖像處理算法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM