> For the complete documentation index, see [llms.txt](https://portal-integracao.intelbras.com.br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://portal-integracao.intelbras.com.br/linha-android/algoritimos-e-funcionamento/reconhecimento-de-face.md).

# Reconhecimento de Face

Para detalhes, verifique o demo LamyAiServer

### 1 - Inicio do Algorítimo

```java
private void startAlgorithm() {
    // Create the parameter object
    Bundle requestBundle = new Bundle();
    // Set the maximum number of faces that can be detected at the same time,
    // generally 1, the default value is 1
    FaceParametersHelper.setMaxFaceDetectCount(requestBundle, 5);
    // Set the width and height of the preview screen.Otherwise, before drawing the
    // face frame in the preview interface, it is necessary to convert the
    // recognition coordinate value to preview coordinate
    FaceParametersHelper.setViewHeight(requestBundle, mSurfaceView.getHeight());
    FaceParametersHelper.setViewWidth(requestBundle, mSurfaceView.getWidth());
    // Generally, the detection area is larger than the output size of camera. If it
    // cannot be confirmed, the parameter of openCamera can not be set. The default
    // value is 1920x1920
    FaceParametersHelper.setMaxDetectWidth(requestBundle, 1920);
    FaceParametersHelper.setMaxDetectHeight(requestBundle, 1920);
    // Turn off the analysis logic of detection results (mainly for mask detection),
    // which can be determined by users according to their own needs. Generally, it
    // can be turned off, and the default is on
    // FaceParametersHelper.setFaceDetectResultAnalysisEnable(requestBundle, false);
    LamyAiServerClientProxy.getInstance().startArithmetic(getCameraId(), getCurrentArithmeticType(),
            requestBundle, mAiServerListener);
}

protected void setSceneMode() {
    // Set the scene mode to increase the recognition accuracy
    int resultCode = LamyAiServerClientProxy.getInstance().setLamySceneMode(getCameraId(),
            getCurrentArithmeticType());
    ModuleLog.i(TAG, "setSceneMode: resultCode " + resultCode);
}

private int getCurrentArithmeticType() {
    return ArithmeticType.ARITHMETIC_TYPE_FACE_DATABASE;
}
```

### 2 - Parse de recebimentos de dados do Algorítimo

```java
protected void onAlgorithmCompleted(Bundle replyBundle) {
    Parcelable[] results = replyBundle.getParcelableArray(IAiMessage.KEY_FACE);
    if (results != null) {
        ModuleLog.i(TAG, "onFaceDataCompleted: face size " + results.length);
        Rect[] detectRects = new Rect[results.length];
        for (int i = 0; i < results.length; i++) {
            Parcelable resultObject = results[i];
            if (resultObject == null) {
                continue;
            }
            IAIFaceObject aiObject = (IAIFaceObject) resultObject;
            dealFaceRecognitionObject(aiObject);
            Rect rect = new Rect(aiObject.mLeft, aiObject.mTop, aiObject.mRight,
                    aiObject.mBottom);
            detectRects[i] = rect;
        }
        drawDetectRect(detectRects);
    } else {
        setDefaultFaceRect();
    }
}

protected void dealFaceRecognitionObject(final IAIFaceObject face) {
    // Face algorithm a frame recognition will call back twice, once for the
    // detection result, once for the recognition result
    // The detection results are mainly used to display the face frame in advance,
    // and the recognition results can be used for subsequent logic
    // You can determine the type of the current callback result according to the
    // following code,
    // Can also use the judging mSimilarity, not for
    // FaceDetectSimilarityResult.DETECT_RESULT_IN_VALIDITY_PERIOD for face
    // recognition results, this method in the runOnUiThread code
    // If there is no special treatment, the similarity judgment method can be used
    // generally
    AiDetectExternalInfo externalInfo = null;
    if (face.mExtraInfo != null) {
        externalInfo = AiDetectExternalInfo.deserialize((Bundle) face.mExtraInfo);
        if (externalInfo.mFaceResultType == AiDetectExternalInfo.FACE_RESULT_TYPE_DETECT) {
            ModuleLog.i(TAG, "dealSingleFaceObject: FACE_RESULT_TYPE_DETECT");
        } else {
            ModuleLog.i(TAG, "dealSingleFaceObject: FACE_RESULT_TYPE_RECOGNITION");
        }
    }
    dealFaceCompareResult(face, externalInfo);
}

protected void dealFaceCompareResult(IAIFaceObject face, AiDetectExternalInfo detectExternalInfo) {
    // Similarity > 0 indicates successful recognition and face information
    // processing
    // Similarity <= 0 &&! . = FaceDetectSimilarityResult
    // DETECT_RESULT_IN_VALIDITY_PERIOD said recognition failure, need to face
    // information processing
    if (face.mSimilarity > 0) {
        // Process extraI identification frame information
        dealExtraInfoOfDetectFrame(detectExternalInfo);
    }
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            dealFaceInfo(face, detectExternalInfo);
        }
    });
}

protected void drawDetectRect(Rect[] detectRects) {
    // Subsequent logic is recommended to be handled in threads
    ThreadPoolManager.getCacheThreadPool().execute(new Runnable() {
        @Override
        public void run() {
            // Draw face coordinates
            mFaceCover.setRects(detectRects);
            // Detect the face, light up the screen
            acquireScreenOn();
        }
    });
}

protected void dealFaceInfo(IAIFaceObject face, AiDetectExternalInfo externalInfo) {
    // A similarity of > FaceDetectSimilarityResult.DETECT_RESULT_FAILED indicates
    // successful recognition
    if (face.mSimilarity > 0) {
        ModuleLog.w(TAG, face.toString());
        String tipSimilar = " similar " + face.mSimilarity + ", ";
        // Check the persistent database by ID to obtain user information
        FaceInfo faceInfo = mDataBaseHelperManager.queryFaceByFaceId(face.mId);
        if (faceInfo == null) {
            String tips = String.format(Locale.getDefault(),
                    getString(R.string.recognition_succeeded_with_face_id), face.mId) + tipSimilar;
            getMaskStateTip(face, tips);
            showTips(mTvResultData, tips);
            ModuleLog.i(TAG, "dealFaceInfo: can not query face info, face id " + face.mId);
            return;
        }
        int userId = faceInfo.mUserId;
        UserInfo userInfo = mDataBaseHelperManager.queryUser(userId);
        if (userInfo == null) {
            String tips = String.format(Locale.getDefault(),
                    getString(R.string.recognition_succeeded_with_user_id), face.mId, userId) + tipSimilar;
            getMaskStateTip(face, tips);
            showTips(mTvResultData, tips);
            ModuleLog.i(TAG, "dealFaceInfo: can not query user info, face id " + face.mId + ", userId " + userId);
            return;
        }
        // Handling mask logic: whether to wear a mask attribute, 0 no obstruction, 1
        // mask, 2 others greater than 0 is wearing a mask
        // Ask the access party to check this field face.mFaceMask according to the
        // business requirements
        String tips = String.format(Locale.getDefault(), getString(R.string.recognition_succeeded),
                face.mId, userInfo.mUserId, userInfo.mUserName) + tipSimilar;
        getMaskStateTip(face, tips);
        showTips(mTvResultData, tips);
    } else if (face.mSimilarity == FaceDetectSimilarityResult.DETECT_RESULT_IN_VALIDITY_PERIOD) {
        // There is no need to deal with the validity period of the identification,
        // success and failure have their own validity period,
        // note that the detection result can also be judged by this value.
        // do nothing
        // Convention: Anti-counterfeiting (biopsy) failure business This error type, -1
        // not detected (default), 0 is not alive, 1 is alive
        if (externalInfo != null && externalInfo.mFaceResultType == AiDetectExternalInfo.FACE_RESULT_TYPE_RECOGNITION
                && face.mLiveFlag == 0) {
            boolean isEnable = FaceAntifakeStrategyCfgHelper.getFaceAntiFakeEnable();
            if (isEnable) {
                showTips(mTvResultData, R.string.recognition_failure_anti);
                ModuleLog.i(TAG, "dealFaceInfo: failed. aini fake detect failed");
            }
        }
    } else if (face.mSimilarity == FaceDetectSimilarityResult.DETECT_RESULT_FAILED_LOW_THRESHOLD) {
        // This error type is common and is returned if the face is not present in the
        // memory cache.
        showTips(mTvResultData, R.string.recognition_failure_low);
    } else {
        ModuleLog.w(TAG, face.toString());
        showTips(mTvResultData, R.string.recognition_failure);
    }
}

protected void dealExtraInfoOfDetectFrame(AiDetectExternalInfo externalInfo) {
    if (externalInfo != null) {
        // Read out the recognition frame data, which is in YUV format.Note: The token
        // is reused, please get the data as fast as possible, if there are other
        // time-consuming operations, the token may be overwritten in the next frame,
        // resulting in inaccurate face image
        byte[] bigYuvData = ShareMemoryWrapperManager.getInstance().readShareBytes(externalInfo.mRgbFrameToken);
        // It is recommended to handle subsequent logic in threads
        ThreadPoolManager.getCacheThreadPool().execute(new Runnable() {
            @Override
            public void run() {
                if (bigYuvData != null) {
                    int width = externalInfo.mRgbFrameWidth;
                    int height = externalInfo.mRgbFrameHeight;

                    // Convert to jpg format
                    byte[] bigJpegData = ImageUtils.yuvCompressToJpeg(bigYuvData,
                            externalInfo.mDetectFrameWidth, externalInfo.mDetectFrameHeight, 90);
                    // Obtain the face image according to the recognition frame, and cut the matting
                    // image according to the face coordinates
                    // Note: The default coordinate is only extracted from the face, not the avatar,
                    // please enlarge appropriately according to the use scene, generally 1.4x1.5 is
                    // enough
                    // getValidFaceImageCoordinate(externalInfo, externalInfo.mDetectFrameWidth,
                    // externalInfo.mDetectFrameHeight);
                    byte[] smallJpegData = LamyImageUtilsProxy.getInstance().cropAndEncodeImageWithBuffer(
                            bigYuvData, width, height,
                            externalInfo.mOriLeft, externalInfo.mOriTop,
                            externalInfo.mOriRight, externalInfo.mOriBottom);
                    if (smallJpegData != null) {
                        // Convert to bitmap
                        Bitmap bitmap = Utils.bytesToBitmap(smallJpegData);
                    }
                }
            }
        });
    }
}

protected void setDefaultFaceRect() {
    mFaceCover.setRect(null);
}
```

### 4 - Encerramento do Algorítimo

```java
private void stopAlgorithm() {
    LamyAiServerClientProxy.getInstance().stopArithmetic(getCameraId(), getCurrentArithmeticType(),
    mAiServerListener);
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://portal-integracao.intelbras.com.br/linha-android/algoritimos-e-funcionamento/reconhecimento-de-face.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
