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 = [
"@maven//:androidx_appcompat_appcompat",
"@maven//:androidx_constraintlayout_constraintlayout",
],
)
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.