溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何實現(xiàn)物體檢測與跟蹤

發(fā)布時間:2021-10-13 14:29:01 來源:億速云 閱讀:193 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“如何實現(xiàn)物體檢測與跟蹤”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

效果示例

如何實現(xiàn)物體檢測與跟蹤

基本原理和實現(xiàn)步驟

實現(xiàn)步驟

圖片預(yù)處理:在圖像預(yù)處理環(huán)節(jié),通過編碼、閾值及濾波、改善模式、離散模式運算等基本運算方式,在盡可能保留圖像所有內(nèi)容信息的基礎(chǔ)上,整理突出圖像特征,以達到最佳圖像特征提取的狀態(tài)。

圖像特征提取:經(jīng)過預(yù)處理的圖像在特征提取環(huán)節(jié),提取出價值高的特征,使高維特征空間擁有更好的分離性,更便于進行算法識別。圖像特征提取一般細(xì)分成幾個模塊來進行:灰度值、亮度值、形狀、紋理等視覺上的基本特征提??;基于像素點顏色的顏色特征提??;物體紋理及結(jié)構(gòu)材質(zhì)的紋理特征提?。换谳喞突趨^(qū)域的形狀特征提??;以及圖像分割出的多個目標(biāo)之間空間位置關(guān)系信息的空間特征提取。

特征選擇:特征提取后,可根據(jù)具體物體識別情況進行特征選擇。比如在特征種類繁多、物體種類多的情況下,通過特征選擇找到各個特征適配的場合。

建模:特征選擇之后,在建模環(huán)節(jié)建立特征集合,分辨異同點,提取相同點,主要建模對象是特征與特征之間的空間結(jié)構(gòu)關(guān)系。

匹配:匹配環(huán)節(jié)是用模型去識別匹配新圖像,識別圖像屬于哪類物體,條件符合可將物體與圖像其他部分分離。

定位:物體識別后進行對目標(biāo)物體的定位,即將識別到的物體坐標(biāo)與實際物理空間坐標(biāo)結(jié)合起來,之后可以進行對應(yīng)的跟蹤和模型疊加處理。

AR Engine提供的三大能力

華為AR Engine提供的三大能力分別是運動跟蹤、環(huán)境跟蹤、人體和人臉跟蹤。

運動跟蹤主要通過終端設(shè)備攝像頭標(biāo)識特征點,并跟蹤這些特征點的移動變化,來不斷跟蹤終端設(shè)備位置和姿態(tài)。

環(huán)境跟蹤可以識別平面,如地面、墻壁等,也可估測平面周圍的光照強度。

人體和人臉跟蹤讓終端設(shè)備具備了對人的理解能力。通過定位人的手部位置和對特定手勢的識別,可將虛擬物體或內(nèi)容特效放置在人的手上;結(jié)合深度器件,還可精確還原手部的21個骨骼點的運動跟蹤,做更為精細(xì)化的交互控制和特效疊加;當(dāng)識別范圍擴展到人的全身時,可利用識別到的23個人體關(guān)鍵位置,實時的檢測人體的姿態(tài),為體感和運動健康類的應(yīng)用開發(fā)提供能力支撐。

開發(fā)準(zhǔn)備

在AndroidManifest.xml中添加權(quán)限

打開main中的AndroidManifest.xml文件,在<application 前添加對相機的權(quán)限聲明,需要注意的是代碼中還需要動態(tài)進行權(quán)限申請,否則會有Permission Denied報錯

<uses-permission android:name="android.permission.CAMERA" />

開發(fā)步驟

配置MainActivity的顯示效果

首先通過 MainActivity extends Activity implements GLSurfaceView.Renderer創(chuàng)建MainActivity,在MainActivity的layout文件中新建一個GLSurfaceView,用于顯示攝像頭拍攝的實時畫面,提供給AREngine進行識別:

<android.opengl.GLSurfaceView
    android:id="@+id/surfaceview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="top" />

在MainActivity的onCreate階段進行SurfaceView的配置:

private GLSurfaceView mSurfaceView;

private static final int CONFIG_CHOOSER_RED_SIZE = 8;
private static final int CONFIG_CHOOSER_GREEN_SIZE = 8;
private static final int CONFIG_CHOOSER_BLUE_SIZE = 8;
private static final int CONFIG_CHOOSER_ALPHA_SIZE = 8;
private static final int CONFIG_CHOOSER_DEPTH_SIZE = 16;
private static final int CONFIG_CHOOSER_STENCIL_SIZE = 0;
private static final int OPENGLES_VERSION = 2;

mSurfaceView = findViewById(R.id.surfaceview);
mSurfaceView.setPreserveEGLContextOnPause(true);
mSurfaceView.setEGLContextClientVersion(OPENGLES_VERSION);
mSurfaceView.setEGLConfigChooser(CONFIG_CHOOSER_RED_SIZE, // Alpha used for plane blending.
        CONFIG_CHOOSER_GREEN_SIZE,
        CONFIG_CHOOSER_BLUE_SIZE,
        CONFIG_CHOOSER_ALPHA_SIZE,
        CONFIG_CHOOSER_DEPTH_SIZE,
        CONFIG_CHOOSER_STENCIL_SIZE); // Alpha used for plane blending.
mSurfaceView.setRenderer(this);
mSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

加載一張框圖文件,用于標(biāo)記識別的位置,引導(dǎo)用戶進行物體識別:

fitToScanView = findViewById(R.id.image_view_fit_to_scan);
InputStream bitmapstream;
try {
    bitmapstream = getAssets().open("fit_to_scan.png");
} catch (IllegalArgumentException | IOException e) {
    Log.d(TAG, "open bitmap failed!");
    return;
}
Bitmap bitmap = BitmapFactory.decodeStream(bitmapstream);
fitToScanView.setImageBitmap(bitmap);

AREngine檢測和配置權(quán)限申請

物體識別功能的使用需要設(shè)備支持AREngine,并且已經(jīng)安裝了AREngine的APK包,所以要對運行的設(shè)備進行判斷,是否支持該功能

rivate boolean arEngineAbilityCheck() {
    boolean isInstallArEngineApk = AREnginesApk.isAREngineApkReady(this);
    if (!isInstallArEngineApk && isRemindInstall) {
        Toast.makeText(this, "Please agree to install.", Toast.LENGTH_LONG).show();
        finish();
    }
    Log.d(TAG, "Is Install AR Engine Apk: " + isInstallArEngineApk);
    if (!isInstallArEngineApk) {
        //Code of jumping to AppGallery to download the APK
        isRemindInstall = true;
    }
    return AREnginesApk.isAREngineApkReady(this);
}

AREngine檢測完成之后,再進行相機權(quán)限的動態(tài)申請

private static final String[] PERMISSIONS_ARRAYS = new String[]{Manifest.permission.CAMERA};
public static void requestPermission(final Activity activity) {
    Log.d(TAG, "requestPermission >>");
    for (String permission : PERMISSIONS_ARRAYS) {
        if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission);
        }
    }
    ActivityCompat.requestPermissions(activity,
            permissionsList.toArray(new String[permissionsList.size()]),
            REQUEST_CODE_ASK_PERMISSIONS);
    Log.d(TAG, "requestPermission <<");
}

以上步驟完成之后,說明設(shè)備支持AREngine的物體識別功能,并且已經(jīng)獲得了相機的使用權(quán)限,接下來就可以創(chuàng)建ARSession,并進行識別數(shù)據(jù)庫的配置

配置物體識別數(shù)據(jù)庫

在進行物體識別之前,要將想識別的對象的圖片添加到數(shù)據(jù)庫中,使用的是ARAugmentedImageDatabase,創(chuàng)建一個boolean函數(shù),進行數(shù)據(jù)庫的圖片添加,并給后續(xù)是否進行識別作判斷:

private boolean setupAugmentedImageDatabase(ARWorldTrackingConfig config) {

    ARAugmentedImageDatabase augmentedImageDatabase;
    Optional<Bitmap> augmentedImageBitmapOptional = loadAugmentedImageBitmap();
    Bitmap augmentedImageBitmap = null;
    if (augmentedImageBitmapOptional.isPresent()) {
        augmentedImageBitmap = loadAugmentedImageBitmap().get();
    } else {
        return false;
    }

    if (augmentedImageBitmap == null) {
        return false;
    }

    augmentedImageDatabase = new ARAugmentedImageDatabase(mSession);
    augmentedImageDatabase.addImage("image_name", augmentedImageBitmap);
    config.setAugmentedImageDatabase(augmentedImageDatabase);
    String text = String.format(Locale.ROOT, "has set ImageNum: %d", augmentedImageDatabase.getNumImages());

    messageSnackbarHelper.showMessage(this, text);

    return true;

}

所添加的識別圖片源可以放置在Assets文件夾內(nèi),通過InputStream打開為Bitmap的格式

private Optional<Bitmap> loadAugmentedImageBitmap() {
    try (InputStream is = getAssets().open("cup.jpg")) {
        return Optional.of(BitmapFactory.decodeStream(is));
    } catch (IOException e) {
        Log.e(TAG, "IO exception loading augmented image bitmap.", e);
    }
    return Optional.empty();
}

配置識別后顯示效果

在MainActivity的onDrawFrame中配置識別到物體之后的顯示效果,在檢測到要識別的物體后,用一個方框?qū)⒆R別的物體標(biāo)識出來。

public void onDrawFrame(GL10 unused) {
    Log.d(TAG, "onDrawFrame >>");
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    if (mSession == null) {
        Log.d(TAG, "onDrawFrame mSession is null");
        return;
    }
    try {
        ARFrame frame = mSession.update();
        ARCamera camera = frame.getCamera();
        if (camera.getTrackingState() == ARTrackable.TrackingState.PAUSED) {
            return;
        }
        Log.d(TAG, "ARTrackable.TrackingState" + camera.getTrackingState());
        drawAugmentedImages(frame, projmtx, viewmtxs, colorCorrectionRgbas);
    } catch (Throwable t) {
        Log.e(TAG, "Exception on the OpenGL thread", t);
    }
    Log.d(TAG, "onDrawFrame <<");
}

判斷是否識別到物體時,調(diào)用ARAugmentedImage的getTrackingStatus方法,如果是TRACKING的話,則為識別到了

switch (augmentedImage.getTrackingState()) {
    case TRACKING:
        augmentedImageRenderer.draw(viewmtxs, projmtx, augmentedImage, centerAnchor, colorCorrectionRgbas);
        break;
    default:
        break;
}

之后通過getCenterPose獲取物體的中心位置信息,將邊框添加到顯示中

anchorPose = augmentedImage.getCenterPose();
float scaleFactor = 1.0f;
float[] modelMatrixs = new float[MODEL_MATRIX_SIZE];
float[] tintColors = convertHexToColor(TINT_COLORS_HEXS[augmentedImage.getIndex() % TINT_COLORS_HEXS.length]);
worldBoundaryPoses[0].toMatrix(modelMatrixs, 0);
imageFrameUpperLeft.updateModelMatrix(modelMatrixs, scaleFactor);
imageFrameUpperLeft.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColors);
worldBoundaryPoses[1].toMatrix(modelMatrixs, 0);
imageFrameUpperRight.updateModelMatrix(modelMatrixs, scaleFactor);
imageFrameUpperRight.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColors);
worldBoundaryPoses[2].toMatrix(modelMatrixs, 0);
imageFrameLowerRight.updateModelMatrix(modelMatrixs, scaleFactor);
imageFrameLowerRight.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColors);
worldBoundaryPoses[3].toMatrix(modelMatrixs, 0);
imageFrameLowerLeft.updateModelMatrix(modelMatrixs, scaleFactor);
imageFrameLowerLeft.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColors);

“如何實現(xiàn)物體檢測與跟蹤”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI