Giriş
Merhaba Dünya! eğiticisi MediaPipe Framework'ü kullanır ve böylece Android'de bir MediaPipe grafiği çalıştırıyor.
Ne oluşturacaksınız?
Canlı bir videoya gerçek zamanlı Sobel kenar algılaması için uygulanan basit bir kamera uygulaması canlı yayın yapabilirsiniz.
Kurulum
- Sisteminize MediaPipe Framework'ü yükleme için Çerçeve yüklemesi kurulumuna bakın rehberini inceleyin.
- Android Geliştirme SDK'sını ve Android NDK'yı yükleyin. Bunu nasıl yapacağınızı şuradan öğrenebilirsiniz: [Çerçeve kurulum kılavuzu].
- Android cihazınızda geliştirici seçeneklerini etkinleştirin.
- Android uygulamasını oluşturmak ve dağıtmak için sisteminizde Bazel'i kurun.
Kenar algılama grafiği
Şu grafiği kullanacağız: edge_detection_mobile_gpu.pbtxt
:
# MediaPipe graph that performs GPU Sobel edge detection on a live video stream.
# Used in the examples in
# mediapipe/examples/android/src/java/com/mediapipe/apps/basic and
# mediapipe/examples/ios/edgedetectiongpu.
# Images coming into and out of the graph.
input_stream: "input_video"
output_stream: "output_video"
# Converts RGB images into luminance images, still stored in RGB format.
node: {
calculator: "LuminanceCalculator"
input_stream: "input_video"
output_stream: "luma_video"
}
# Applies the Sobel filter to luminance images stored in RGB format.
node: {
calculator: "SobelEdgesCalculator"
input_stream: "luma_video"
output_stream: "output_video"
}
Grafik görselleştirmesi aşağıda gösterilmektedir:
Bu grafikte, tüm gelen kareler için input_video
adlı tek bir giriş akışı bulunuyor
bir veri feed'i seçin.
Grafikteki ilk düğüm olan LuminanceCalculator
, tek bir paket alır (görüntü
çerçeve) ve bir OpenGL gölgelendirici kullanarak parlaklık değişikliği uygular. Bunun sonucunda
resim çerçevesi, luma_video
çıkış akışına gönderilir.
İkinci düğüm olan SobelEdgesCalculator
, gelen içeriğe uç algılamayı uygular
luma_video
akışındaki paketler ve çıkışlar, output_video
çıkışıyla sonuçlanır
akış şeklinde gösterilir.
Android uygulamamız, tablodaki çıktıların resim çerçevelerini
output_video
akışı.
İlk minimum uygulama kurulumu
Öncelikle, "Hello World!" ifadesini görüntüleyen basit bir Android uygulamasıyla başlıyoruz.
ekranda görebilirsiniz. Android cihazlar hakkında bilginiz varsa bu adımı atlayabilirsiniz.
bazel
kullanan uygulamalar.
Android uygulamanızı oluşturacağınız yeni bir dizin oluşturun. Örneğin,
bu eğiticinin tam kodunu şu adreste bulabilirsiniz:
mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic
Bugün
codelab'de bu yoldan $APPLICATION_PATH
olarak bahsedin.
Uygulamaya giden yolda:
- Uygulamanın adı
helloworld
. - Başvuru
$PACKAGE_PATH
,com.google.mediapipe.apps.basic
. Bunlar, bu eğiticideki kod snippet'lerinde kullanıldığından lütfen kendi$PACKAGE_PATH
'iniz olur.
$APPLICATION_PATH/res/layout
adlı klasöre bir activity_main.xml
dosyası ekleyin. Bu sütunda
uygulamanın tam ekranında Hello
World!
dizesine sahip bir TextView
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
$APPLICATION_PATH
için, içeriği yükleyen basit bir MainActivity.java
ekleyin
activity_main.xml
düzeninin özelliklerini ayarlayın:
package com.google.mediapipe.apps.basic;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
/** Bare-bones main activity. */
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
$APPLICATION_PATH
hedefine AndroidManifest.xml
adlı bir manifest dosyasını ekleyin. Bu dosya
uygulama başlangıcında MainActivity
öğesini başlatır:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.mediapipe.apps.basic">
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:label="${appName}"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="${mainActivity}"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Uygulamamızda, uygulamada bir Theme.AppCompat
teması kullanıyoruz. Bu yüzden
uygun tema referansları hazırlayın. colors.xml
adlı kişiyi şuraya ekle:
$APPLICATION_PATH/res/values/
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
styles.xml
öğesini $APPLICATION_PATH/res/values/
öğesine ekleyin:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
Uygulamayı oluşturmak için $APPLICATION_PATH
uygulamasına bir BUILD
dosyası ekleyin ve
Manifest'teki ${appName}
ve ${mainActivity}
, dizelerle değiştirilecek
aşağıda gösterildiği gibi BUILD
içinde belirtilir.
android_library(
name = "basic_lib",
srcs = glob(["*.java"]),
manifest = "AndroidManifest.xml",
resource_files = glob(["res/**"]),
deps = [
"//third_party:android_constraint_layout",
"//third_party:androidx_appcompat",
],
)
android_binary(
name = "helloworld",
manifest = "AndroidManifest.xml",
manifest_values = {
"applicationId": "com.google.mediapipe.apps.basic",
"appName": "Hello World",
"mainActivity": ".MainActivity",
},
multidex = "native",
deps = [
":basic_lib",
],
)
android_library
kuralı, kaynak dosyalara MainActivity
için bağımlılık ekler.
ve AndroidManifest.xml
.
android_binary
kuralı, şu işlemler için oluşturulan basic_lib
Android kitaplığını kullanır:
Android cihazınıza yüklemek üzere bir ikili program APK'sı derleme
Uygulamayı derlemek için aşağıdaki komutu kullanın:
bazel build -c opt --config=android_arm64 $APPLICATION_PATH:helloworld
Oluşturulan APK dosyasını adb install
kullanarak yükleyin. Örneğin:
adb install bazel-bin/$APPLICATION_PATH/helloworld.apk
Cihazınızda uygulamayı açın. Metnin yer aldığı bir ekran görüntülenmelidir.
Hello World!
Kamera CameraX
üzerinden kullanılıyor
Kamera İzinleri
Kamerayı uygulamamızda kullanmak için kullanıcıdan
erişebilir. Kamera izni istemek için aşağıdakileri ekleyin:
AndroidManifest.xml
:
<!-- For using the camera -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
Şu öğede minimum SDK sürümünü 21
ve hedef SDK sürümünü 27
olarak değiştirin:
aynı dosya:
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="27" />
Bu işlem, kullanıcıdan kamera izni istemesini sağlar ve kamera erişimi için CameraX kitaplığını kullanmamız gerekiyor.
Kamera izni istemek için MediaPipe Framework tarafından sağlanan bir yardımcı programı kullanabiliriz
yani PermissionHelper
bileşenlerini kullanabilirsiniz. Kullanmak için bir bağımlılık ekleyin
"//mediapipe/java/com/google/mediapipe/components:android_components"
BUILD
içinde mediapipe_lib
kural.
PermissionHelper
öğesini MainActivity
içinde kullanmak için aşağıdaki satırı
onCreate
işlevi:
PermissionHelper.checkAndRequestCameraPermissions(this);
Bu işlemle, ekranda bir iletişim kutusuyla kullanıcıdan kamerayı bu uygulamada kullanabilirsiniz.
Kullanıcı yanıtını işlemek için aşağıdaki kodu ekleyin:
@Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
protected void onResume() {
super.onResume();
if (PermissionHelper.cameraPermissionsGranted(this)) {
startCamera();
}
}
public void startCamera() {}
startCamera()
yöntemini şimdilik boş bırakacağız. Kullanıcı yanıt verdiğinde
komut isteminde MainActivity
devam ettirilir ve onResume()
çağrılır.
Kod, kamerayı kullanma izinlerinin verildiğini ve
ve ardından kamerayı başlatır.
Uygulamayı yeniden derleyip yükleyin. Şimdi bir istem görebilirsiniz. uygulamanın kameraya erişmesine izin verir.
Kamera erişimi
Kamera izinlerini kullanarak kareleri şuradan başlatıp getirebiliriz: bulun.
Kareleri kameradan görüntülemek için bir SurfaceView
kullanacağız. Her bir kare
SurfaceTexture
bir nesne içinde depolanır. Bunları kullanmak için
öncelikle uygulamamızın düzenini değiştirmemiz gerekiyor.
TextView
kod bloğunun tamamını şuradan kaldırın:
$APPLICATION_PATH/res/layout/activity_main.xml
ve aşağıdaki kodu ekleyin
aşağıdaki adımları uygulayabilirsiniz:
<FrameLayout
android:id="@+id/preview_display_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:id="@+id/no_camera_access_view"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="center"
android:text="@string/no_camera_access" />
</FrameLayout>
Bu kod bloğunda preview_display_layout
adında yeni bir FrameLayout
ve
TextView
, no_camera_access_preview
adlı bunun içine yerleştirilmiş. Kamera olduğunda
olmadığı için, uygulamamız bu iznin başarılı bir şekilde
Dize mesajıyla birlikte, no_camera_access
değişkeninde depolanır. TextView
$APPLICATION_PATH/res/values/strings.xml
dosyasına aşağıdaki satırı ekleyin:
<string name="no_camera_access" translatable="false">Please grant camera permissions.</string>
Kullanıcı kamera izni vermediğinde ekran artık şu şekilde görünür: bu:
Şimdi SurfaceTexture
ve SurfaceView
nesnelerini şuraya ekleyeceğiz:
MainActivity
:
private SurfaceTexture previewFrameTexture;
private SurfaceView previewDisplayView;
onCreate(Bundle)
işlevinde, aşağıdaki iki satırı önce ekleyin
kamera izinleri isteniyor:
previewDisplayView = new SurfaceView(this);
setupPreviewDisplayView();
Şimdi de setupPreviewDisplayView()
öğesini tanımlayan kodu ekleyin:
private void setupPreviewDisplayView() {
previewDisplayView.setVisibility(View.GONE);
ViewGroup viewGroup = findViewById(R.id.preview_display_layout);
viewGroup.addView(previewDisplayView);
}
Yeni bir SurfaceView
nesnesi tanımlar ve bunu
Görüntülemek için kullanabileceğimiz preview_display_layout
FrameLayout
nesnesi
kamera karelerini previewFrameTexture
adlı bir SurfaceTexture
nesnesi kullanarak oluşturun.
Kamera çerçevelerini almak üzere previewFrameTexture
işlevini kullanmak için CameraX kullanılır.
Çerçeve, CameraX'i kullanmak için CameraXPreviewHelper
adlı bir yardımcı program sağlar.
Bu sınıf, kamera şunun üzerinden başlatıldığında bir dinleyiciyi günceller:
onCameraStarted(@Nullable SurfaceTexture)
Bu yardımcı programı kullanmak için BUILD
dosyasını değiştirerek
"//mediapipe/java/com/google/mediapipe/components:android_camerax_helper"
.
Şimdi CameraXPreviewHelper
dosyasını içe aktarın ve aşağıdaki satırı
MainActivity
:
private CameraXPreviewHelper cameraHelper;
Artık uygulamamızı startCamera()
öğesine ekleyebiliriz:
public void startCamera() {
cameraHelper = new CameraXPreviewHelper();
cameraHelper.setOnCameraStartedListener(
surfaceTexture -> {
previewFrameTexture = surfaceTexture;
// Make the display view visible to start showing the preview.
previewDisplayView.setVisibility(View.VISIBLE);
});
}
Bu işlem yeni bir CameraXPreviewHelper
nesnesi oluşturur ve anonim bir nesne ekler
bahsedeceğim. cameraHelper
, kameranın başladığını bildirdiğinde
ve kareleri tutmak için bir surfaceTexture
varsa,
previewFrameTexture
olarak surfaceTexture
ve previewDisplayView
turuna katılın
kadrajı previewFrameTexture
biçiminden görmeye başlayabilmemiz için görünür.
Ancak, kamerayı başlatmadan önce, hangi kamerayı başlatacağımıza
pek de iyi olmadığını unutmayın. CameraXPreviewHelper
, iki sağlayan CameraHelper
kaynağından devralır
seçenekler, FRONT
ve BACK
. Kararı BUILD
dosyasından iletebiliriz.
başka bir sürümünü oluşturmak için kod değişikliğinin gerekli olmadığı meta veriler
başka bir kamera kullanarak
uygulamayı başlatabilirsiniz.
Canlı bir sahnede kenar algılama işlemi yapmak için BACK
kamerayı kullanmak istediğimizi varsayarsak
meta verileri AndroidManifest.xml
dosyasına ekleyin:
...
<meta-data android:name="cameraFacingFront" android:value="${cameraFacingFront}"/>
</application>
</manifest>
ve helloworld
Android ikili kuralında BUILD
içinde seçimi belirtin
manifest_values
alanında yeni bir girişle:
manifest_values = {
"applicationId": "com.google.mediapipe.apps.basic",
"appName": "Hello World",
"mainActivity": ".MainActivity",
"cameraFacingFront": "False",
},
Şimdi, manifest_values
politikasında belirtilen meta verileri almak için MainActivity
ürününde,
ApplicationInfo
nesnesi ekleyin:
private ApplicationInfo applicationInfo;
onCreate()
işlevine şunu ekleyin:
try {
applicationInfo =
getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
} catch (NameNotFoundException e) {
Log.e(TAG, "Cannot find application info: " + e);
}
Şimdi startCamera()
işlevinin sonuna aşağıdaki satırı ekleyin:
CameraHelper.CameraFacing cameraFacing =
applicationInfo.metaData.getBoolean("cameraFacingFront", false)
? CameraHelper.CameraFacing.FRONT
: CameraHelper.CameraFacing.BACK;
cameraHelper.startCamera(this, cameraFacing, /*unusedSurfaceTexture=*/ null);
Bu noktada, uygulamanın başarıyla derlenmesi gerekir. Ancak,
üzerinde çalışırken, siyah bir ekran görürsünüz (kamerayı takiben
için izin verildi.) Çünkü her ne kadar
CameraXPreviewHelper
tarafından sağlanan surfaceTexture
değişkeni
previewSurfaceView
, çıkışını kullanmıyor ve henüz ekranda gösteriyor.
Çerçeveleri bir MediaPipe grafiğinde kullanmak istediğimiz için doğrudan bu eğiticide kamera çıkışını görüntüleyebilirsiniz. Bunun yerine, işlenmek üzere kamera çerçevelerini bir MediaPipe grafiğine gönderebilir ve grafiğin çıkışını inceleyin.
ExternalTextureConverter
kurulumu
SurfaceTexture
, bir akıştan görüntü karelerini OpenGL ES olarak yakalar
dokunun. Bir MediaPipe grafiğini kullanmak için, kameradan alınan kareler
normal bir Open GL doku nesnesinde saklanır. Çerçeve bir sınıf sağlar,
SurfaceTexture
klasöründe depolanan resmi dönüştürmek için ExternalTextureConverter
nesnesine dönüştürmenize gerek yoktur.
ExternalTextureConverter
aracını kullanmak için bir EGLContext
öğesine de ihtiyacımız var.
EglManager
nesnesi tarafından oluşturulur ve yönetilir. BUILD
öğesine bağımlılık ekleyin
EglManager
, "//mediapipe/java/com/google/mediapipe/glutil"
kullanılacak dosya.
MainActivity
içinde aşağıdaki beyanları ekleyin:
private EglManager eglManager;
private ExternalTextureConverter converter;
onCreate(Bundle)
işlevinde,
Kamera izinleri istenmeden önce eglManager
nesne:
eglManager = new EglManager(null);
Bu işlemi onaylamak için MainActivity
fonksiyonunda onResume()
işlevini tanımladığımızı unutmayın.
kamera izinleri verildi ve startCamera()
numaralı telefonu arayın. Bundan önce
kontrol, converter
işlemini başlatmak için onResume()
içine aşağıdaki satırı ekleyin
nesne:
converter = new ExternalTextureConverter(eglManager.getContext());
Bu converter
artık eglManager
tarafından yönetilen GLContext
kullanıyor.
Aynı zamanda, MainActivity
içinde onPause()
işlevini geçersiz kılmamız gerekir.
Uygulama duraklatılmış duruma geçerse converter
düzgün bir şekilde kapatılır:
@Override
protected void onPause() {
super.onPause();
converter.close();
}
previewFrameTexture
çıkışını converter
öğesine aktarmak için
setupPreviewDisplayView()
için takip eden kod bloğu:
previewDisplayView
.getHolder()
.addCallback(
new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// (Re-)Compute the ideal size of the camera-preview display (the area that the
// camera-preview frames get rendered onto, potentially with scaling and rotation)
// based on the size of the SurfaceView that contains the display.
Size viewSize = new Size(width, height);
Size displaySize = cameraHelper.computeDisplaySizeFromViewSize(viewSize);
// Connect the converter to the camera-preview frames as its input (via
// previewFrameTexture), and configure the output width and height as the computed
// display size.
converter.setSurfaceTextureAndAttachToGLContext(
previewFrameTexture, displaySize.getWidth(), displaySize.getHeight());
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {}
});
Bu kod bloğunda, şuraya özel bir SurfaceHolder.Callback
ekleriz:
Uygun bir görüntü boyutunu hesaplamak için previewDisplayView
ve surfaceChanged(SurfaceHolder holder, int
format, int width, int height)
işlevini uygulayın.
bağlamak ve previewFrameTexture
bağlamak için
nesnesini tanımlayın ve hesaplanan displaySize
öğesinin karelerini converter
öğesine gönderin.
Artık kamera çerçevelerini MediaPipe grafiğinde kullanmaya hazırız.
Android'de bir MediaPipe grafiği kullanma
İlgili bağımlılıkları ekleyin
MediaPipe grafiği kullanmak için son olarak MediaPipe çerçevesine bağımlılık eklememiz
elde etti. Önce JNI kodunu kullanarak cc_binary
oluşturmak için bir derleme kuralı ekleyeceğiz
bu ikili programı kullanmak için bir cc_library
kuralı derlemek
bir yöntem de var. BUILD
dosyanıza şu kod bloğunu ekleyin:
cc_binary(
name = "libmediapipe_jni.so",
linkshared = 1,
linkstatic = 1,
deps = [
"//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
],
)
cc_library(
name = "mediapipe_jni_lib",
srcs = [":libmediapipe_jni.so"],
alwayslink = 1,
)
":mediapipe_jni_lib"
bağımlılığını şurada mediapipe_lib
derleme kuralına ekleyin:
BUILD
dosyası.
Sonra, kullanmak istediğimiz MediaPipe grafiğine özel bağımlılıklar takip edebilirsiniz.
İlk olarak, libmediapipe_jni.so
uygulamasındaki tüm hesap makinesi koduna bağımlılıklar ekleyin
derleme kuralı:
"//mediapipe/graphs/edge_detection:mobile_calculators",
MediaPipe grafikleri .pbtxt
dosyalarıdır, ancak bunları uygulamada kullanmak için
.binarypb
dosyası oluşturmak için mediapipe_binary_graph
derleme kuralını kullanın.
helloworld
Android ikili program derleme kuralına mediapipe_binary_graph
ekleyin.
öğe olarak grafiğe özgü hedefi seçin:
assets = [
"//mediapipe/graphs/edge_detection:mobile_gpu_binary_graph",
],
assets_dir = "",
assets
derleme kuralında TensorFlowLite gibi başka öğeler de ekleyebilirsiniz
modellerden bahsetmek istiyorum.
Ayrıcamanifest_values
daha sonra MainActivity
içinde alınacak şekilde grafik:
manifest_values = {
"applicationId": "com.google.mediapipe.apps.basic",
"appName": "Hello World",
"mainActivity": ".MainActivity",
"cameraFacingFront": "False",
"binaryGraphName": "mobile_gpu.binarypb",
"inputVideoStreamName": "input_video",
"outputVideoStreamName": "output_video",
},
binaryGraphName
işlevinin ikili grafiğin dosya adını gösterdiğini unutmayın.
mediapipe_binary_graph
hedefindeki output_name
alanı tarafından belirlenir.
inputVideoStreamName
ve outputVideoStreamName
, giriş ve çıkıştır
sırasıyla grafikte belirtilen video akışı adı.
Şimdi MainActivity
öğesinin MediaPipe çerçevesini yüklemesi gerekiyor. Ayrıca,
çerçevesi OpenCV'yi kullandığından MainActvity
, OpenCV
öğesini de yüklemelidir. Şunu kullanın:
MainActivity
içinde aşağıdaki kodu (sınıfın içinde, herhangi bir işlevin içinde değil)
iki bağımlılığı da yükleyebilirsiniz:
static {
// Load all native libraries needed by the app.
System.loadLibrary("mediapipe_jni");
System.loadLibrary("opencv_java3");
}
MainActivity
uygulamasında grafiği kullanın
Öncelikle, şuradan derlenen .binarypb
öğesini içeren öğeyi yüklememiz gerekir:
grafiğin .pbtxt
dosyası. Bunun için bir MediaPipe yardımcı programı kullanabiliriz,
AndroidAssetUtil
.
Başlatmadan önce onCreate(Bundle)
içinde öğe yöneticisini başlatın
eglManager
:
// Initialize asset manager so that MediaPipe native libraries can access the app assets, e.g.,
// binary graphs.
AndroidAssetUtil.initializeNativeAssetManager(this);
Şimdi, kamera çerçeveleri gönderen bir FrameProcessor
nesnesi oluşturmamız gerekiyor.
converter
tarafından MediaPipe grafiğine hazırlanır ve grafiği çalıştırır.
ardından previewDisplayView
öğesini güncelleyerek çıkışı görüntüler. Ekle
FrameProcessor
öğesini tanımlamak için şu kodu kullanın:
private FrameProcessor processor;
ve eglManager
başlatıldıktan sonra onCreate(Bundle)
içinde başlat:
processor =
new FrameProcessor(
this,
eglManager.getNativeContext(),
applicationInfo.metaData.getString("binaryGraphName"),
applicationInfo.metaData.getString("inputVideoStreamName"),
applicationInfo.metaData.getString("outputVideoStreamName"));
processor
öğesinin, şunun için converter
üzerinden dönüştürülen kareleri kullanması gerekir:
bahsedeceğim. Başlattıktan sonra aşağıdaki satırı onResume()
öğesine ekleyin
converter
:
converter.setConsumer(processor);
processor
, çıkışı previewDisplayView
öğesine göndermelidir. Bunu yapmak için
özel SurfaceHolder.Callback
için aşağıdaki işlev tanımlarını içerir:
@Override
public void surfaceCreated(SurfaceHolder holder) {
processor.getVideoSurfaceOutput().setSurface(holder.getSurface());
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
processor.getVideoSurfaceOutput().setSurface(null);
}
SurfaceHolder
oluşturulduğunda, Surface
VideoSurfaceOutput
/ processor
. İmha edildikten sonra,
processor
öğesinin VideoSurfaceOutput
.
Hepsi bu kadar! Artık projeyi başarılı bir şekilde derleyip çalıştırabilmeniz gerekir sobel sınır algılama özelliğinin canlı kamerada çalıştığını görün feed! Tebrikler!
Herhangi bir sorunla karşılaşırsanız lütfen eğiticinin tam koduna göz atın. burada bulabilirsiniz.