2013-02-19 26 views
6

Bazı canlı video işlemlerini yapmayı denemek için OpenCV kullanıyorum. İşleme oldukça ağır olduğundan, çıkış karelerini önemli ölçüde geciktirerek canlı akışı dalgalı gösteriyor.Android Canlı video karelerini işlemek için asynctask

Bazı işlemlerin bir AsyncTask'e boşaltılmasını istiyorum. Denedim ve aslında videoyu çok daha pürüzsüz hale getiriyor. Bununla birlikte, bir seferde büyük miktarda Görev başlatacak ve daha sonra yavaş yavaş bazı sonuçlarla dönmeye başlayacak.

Bunu yavaşlatmanın bir yolu var mıdır, bir sonucu da Senkronize ifadelerini veya başka bir yöntemi kullanarak mı bekleyebilirsiniz?

Her kamera çerçevesinde, bunlardan birini başlatırım. DoImgProcessing uzun işlem yapar ve bir dize sonucu döndürür.

private class LongOperation extends AsyncTask<Mat, Void, String> { 

    @Override 
    protected String doInBackground(Mat... params) { 
     Mat inputFrame = params[0]; 
     cropToCenter(inputFrame); 
     return doImgProcessing(inputFrame); 
    }  

    @Override 
    protected void onPostExecute(String result) { 
     Log.d(TAG, "on post execute: "+result); 

    } 

    @Override 
    protected void onPreExecute() { 
     Log.d(TAG, "on pre execute"); 
    } 
} 

public Mat onCameraFrame(Mat inputFrame) { 
    inputFrame.copyTo(mRgba);//this will be used for the live stream 
    LongOperation op = new LongOperation(); 
    op.execute(inputFrame); 
    return mRgba; 
} 
+0

Çerçeveleri içine yerleştirmek için bir blockingqueue ile tek bir iş parçacığı kullanırdım. – njzk2

+0

Bunlardan hiç birini yazmamıştım, aldığınız örnek kodu – Jameo

cevap

3

ben böyle bir şey yapmak istiyorum.

Bu, çerçevenin alınmasını ve işlenmesini dekode eder. Sıranın büyümesini frames.size() kullanarak izleyebilirsiniz.

Bu, tipik bir üretici-tüketici örneğidir.

+0

Harika bir örnek. İlk olarak, bu boolean koşulu değişkeni olmak üzere iki soru, teorik olarak tüm etkinlik boyunca koşmalı mı? Ayrıca, kareleri sıraya eklerken şunu söyleyebilirim: (frames.size() <4) {frames.put (inputFrame);} ?? – Jameo

+1

Genellikle, bir duruş durumuna karar vermeniz gerekir. 'running = false', hızlı ve basit bir şekilde ele almanın yoludur, ancak kuyrukta kalanını (beklenen davranış olabilir veya olmayabilir) bırakırsınız. – njzk2

+1

Kuyruk boyutuna gelince, sabit bir kapasite kuyruğu kullanabilir (kurucuya limit ekleyebilir) ve nesneyi yerleştirmeyi deneyecek olan "offer (inputFrame)" komutunu kullanabilir ve boş alan varsa yanlış döndürebilirsiniz. Bu, kareleri bırakabileceğiniz anlamına gelir, ancak gerçek zamanlı tedaviye yakın bir şeyiniz olur. – njzk2

1

Her bir karede bunu yapıyorsanız, bunun yerine bir iş parçacığına ihtiyacınız olduğu anlaşılıyor. Bir AsyncTask, başka bir iş parçacığında bir kerelik etkinlik yapmak istediğiniz zaman içindir. Burada tekrar tekrar yapmak istersiniz. Sadece bir iş parçacığı oluşturun ve bir kareyi tamamladığında, kullanıcı arabirimindeki gönderi adımını çalıştırmak için bir işleyiciye bir ileti gönderin. Bir sonraki çerçevenin hazır olması için kendi döngüsünün üstündeki bir semaforda bekleyebilir. onCameraFrame Kuyruğu, Sırasından işçi Konu sandık üzerinde çerçeve koyar

// Example value for a timeout. 
private static final long TIMEOUT = 1000L; 

private BlockingQueue<Mat> frames = new LinkedBlockingQueue<Mat>(); 

Thread worker = new Thread() { 
    @Override 
    public void run() { 
     while (running) { 
      Mat inputFrame = frames.poll(TIMEOUT, TimeUnit.MILLISECONDS); 
      if (inputFrame == null) { 
       // timeout. Also, with a try {} catch block poll can be interrupted via Thread.interrupt() so not to wait for the timeout. 
       continue; 
      } 
      cropToCenter(inputFrame); 
      String result = doImgProcessing(inputFrame); 
     } 
    } 
}; 
worker.start(); 

public Mat onCameraFrame(Mat inputFrame) { 
    inputFrame.copyTo(mRgba);//this will be used for the live stream 
    frames.put(inputFrame); 
    return mRgba; 
} 

:

+0

verebilirseniz cevabınızı kabul etmekten mutluluk duyarım. . Ama AsyncTask gerçekten sadece bir iş parçacığı değil mi? – Jameo

+0

Sistemin aynı anda birden fazla çerçeve işlemine başlamasına izin vermenin bir avantajı olduğunu düşünüyor musunuz? – Jameo

+0

Bir iş parçacığı üzerinde çalışır, ancak iş parçacığı çıkar. Eğer bir şeyleri kontrplak yapıyorsanız, aslında ne istediğinizi karşılıyorsunuz. 1'den fazla gerçekte bir seferde 1'den fazla asenkron görevi almak zor olduğu için, bazı android sürümlerinde özel kod gerektirir. Ve sadece işletim sisteminin farklı çekirdekler üzerinde çalıştırılması için akıllıca olması yararlı olacaktır, ki şüpheliyim. –