{"id":968,"date":"2026-08-14T14:22:41","date_gmt":"2026-08-14T14:22:41","guid":{"rendered":"https:\/\/boochlin.com\/?p=968"},"modified":"2026-08-14T16:15:56","modified_gmt":"2026-08-14T16:15:56","slug":"android-%e7%88%9b%e8%a3%9d%e7%bd%ae%e6%83%b3%e8%b7%91%e4%ba%ba%e8%87%89%e8%be%a8%e8%ad%9819-%e9%9b%99%e9%8f%a1%e9%a0%ad%e7%9a%84%e6%99%82%e7%a9%ba%e4%bf%ae%e7%be%85%e5%a0%b4%ef%bc%9argb-%e8%88%87-to","status":"publish","type":"post","link":"https:\/\/boochlin.com\/?p=968","title":{"rendered":"Android \u721b\u88dd\u7f6e\u60f3\u8dd1\u4eba\u81c9\u8fa8\u8b5810 &#8211; \u96d9\u93e1\u982d\u7684\u6642\u7a7a\u4fee\u7f85\u5834\uff1aRGB \u8207 ToF"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p>\u5728\u9580\u7981\u6a5f\u4e0a\uff0c\u55ae\u9760\u4e00\u9846\u666e\u901a RGB \u93e1\u982d\u505a\u4eba\u81c9\u8fa8\u8b58\uff0c\u57fa\u672c\u4e0a\u5c31\u662f\u628a\u5927\u9580\u655e\u958b\u7d66\u5f69\u8272\u5217\u5370\u7167\u7247\u3001iPad \u87a2\u5e55\u548c 3D \u9762\u5177\u96a8\u4fbf\u9032\u3002\u70ba\u4e86\u904e <strong>BCTC\uff08\u9280\u884c\u5361\u6aa2\u6e2c\u4e2d\u5fc3\uff09\u91d1\u878d\u7d1a\u652f\u4ed8\u8a8d\u8b49<\/strong>\uff0c\u6211\u5011\u5728 MSM8937 \u9019\u584a\u7834\u677f\u5b50\u4e0a\uff0c\u540c\u6642\u639b\u4e86 RGB \u76f8\u6a5f\u8207 3D ToF \u6df1\u5ea6\u611f\u6e2c\u5668\uff08\u5410\u51fa IR \u7070\u968e\u5716\u8207 16-bit \u9ede\u96f2\uff09\u3002<\/p>\n\n\n\n<p>\u93e1\u982d\u639b\u4e0a\u53bb\u5f88\u7c21\u55ae\uff0c\u4f46\u8edf\u9ad4\u7684\u707d\u96e3\u624d\u525b\u958b\u59cb\uff1a\u4f60\u600e\u9ebc\u4fdd\u8b49\u9001\u9032 AI \u6a21\u578b\u7684\u5f69\u8272\u4eba\u81c9\u8ddf\u6df1\u5ea6\u4eba\u81c9\uff0c\u662f\u540c\u4e00\u77ac\u9593\u7684\u540c\u4e00\u500b\u4eba\uff1f<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<ul>\n<li><strong>RGB \u76f8\u6a5f<\/strong>\uff1a\u6bcf\u79d2 30 \u5e40\uff0c\u8dd1\u5f97\u9806\u66a2\uff0c\u8ca0\u8cac\u7d66\u4eba\u770b\u9810\u89bd\u756b\u9762\u548c\u6293\u4eba\u81c9\u4f4d\u7f6e\u3002<\/li>\n\n\n\n<li><strong>ToF \u6df1\u5ea6\u76f8\u6a5f<\/strong>\uff1a\u8981\u89e3\u7b97 16-bit \u539f\u59cb\u9ede\u96f2\uff0c\u5e40\u7387\u8f03\u4f4e\u4e14\u8ca0\u64d4\u91cd\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u9019\u6703\u9020\u6210\u81f4\u547d\u7684 <strong>\u6642\u7a7a\u932f\u4f4d<\/strong><\/p>\n\n\n\n<p>\u7576\u6709\u4eba\u908a\u8d70\u908a\u5237\u81c9\u6642\uff0cRGB \u93e1\u982d\u6293\u5230\u4ed6\u5728\u5de6\u908a\uff08\u7b2c 10 \u6beb\u79d2\uff09\uff0cToF \u6df1\u5ea6\u93e1\u982d\u6293\u5230\u7684\u6df1\u5ea6\u5716\u537b\u9084\u505c\u5728\u53f3\u908a\uff08\u7b2c 25 \u6beb\u79d2\uff09\u3002\u5169\u5f35\u5716\u4e00\u758a\u5408\uff0cRGB \u4eba\u81c9\u8ddf 3D \u6df1\u5ea6\u8f2a\u5ed3\u76f4\u63a5\u5c0d\u4e0d\u4e0a\u2014\u2014AI \u6d3b\u9ad4\u6a21\u578b\u4e00\u770b\u6df1\u5ea6\u8cc7\u6599\u51f9\u51f8\u4e0d\u5e73\u4e14\u4f4d\u7f6e\u932f\u4e82\uff0c\u76f4\u63a5\u5224\u65b7\u6210\u653b\u64ca\uff0c\u5237\u81c9\u7576\u5834\u5931\u6557\u3002<\/p>\n\n\n\n<p>\u6211\u5011\u5fc5\u9808\u5728\u8edf\u9ad4\u5c64\u628a\u9019\u5169\u8def\u5f71\u50cf<strong>\u5f37\u884c\u9396\u5728\u540c\u4e00\u500b\u6642\u9593\u9ede<\/strong>\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u8edf\u9ad4\u89e3\u6cd5\uff1aRGB \u7576\u706b\u8eca\u982d\uff0cToF \u96a8\u53eb\u96a8\u5230<\/h2>\n\n\n\n<p>\u6211\u5011\u6c92\u6709\u8b93\u5169\u9846\u93e1\u982d\u5404\u81ea\u4e82\u8df3 Callback\uff0c\u800c\u662f\u8a2d\u8a08\u4e86\u4e00\u5957\u4ee5 RGB \u70ba\u57fa\u6e96\u7684\u300c\u975e\u963b\u585e\u62bd\u5e40\uff080ms\uff09\u300d\u8207\u300c\u4e1f\u820a\u4fdd\u65b0\uff08Drop-Oldest\uff09\u300d\u6a5f\u5236\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. RGB \u7576 Master \u6642\u9418\uff0c\u975e\u963b\u585e\u62c9\u53d6 ToF<\/h3>\n\n\n\n<p>\u5728 <code>CameraInstanceMK1.java<\/code> \u4e2d\uff0c\u6211\u5011\u8b93\u5e40\u7387\u7a69\u5b9a\u7684 RGB \u93e1\u982d\u7576\u706b\u8eca\u982d\u3002<\/p>\n\n\n\n<p>\u6bcf\u7576 RGB \u5410\u51fa\u4e00\u5e40\u756b\u9762\uff0c\u6211\u5011<strong>\u4e0d\u662f\u50bb\u50bb\u7b49\u5f85<\/strong> ToF \u6162\u6162\u7b97\u5b8c\uff0c\u800c\u662f\u76f4\u63a5\u4ee5 0ms \u903e\u6642\u53bb ToF \u7684\u7de9\u885d\u5340\u6293\u300c\u7576\u524d\u6700\u65b0\u300d\u7684\u4e00\u5f35\u6df1\u5ea6\u5e40\uff1a<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ CameraInstanceMK1.java\nmRgbCamera.setFrameCallback(\n    yuv -&gt; {\n        if (yuv != null) {\n            System.arraycopy(yuv, 0, mYuvBuffer, 0, yuv.length);\n\n            \/\/ \u95dc\u9375\u9ede\uff1aRGB \u5230\u9054\u77ac\u9593\uff0c\u7acb\u523b\u53bb ToF \u968a\u5217\u62c9\u53d6\u6700\u65b0\u6df1\u5ea6\u8cc7\u6599\uff080ms \u903e\u6642\u975e\u963b\u585e\uff09\n            if (tofRaw == null || tofRaw.length != getTofRawFrameSize()) {\n                tofRaw = new byte&#x5B;getTofRawFrameSize()];\n            }\n            mTof.getData(0, tofRaw);\n\n            \/\/ \u5c07\u5c0d\u9f4a\u597d\u7684 RGB (mYuvBuffer) \u8207 ToF (tofRaw) \u6253\u5305\u4e1f\u9032 Pipeline\n            mCameraFrameCallback.onFrameAvailable(mYuvBuffer, tofRaw, null);\n        }\n    }\n);\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">2. ToF \u7684\u56fa\u5b9a\u4f47\u5217\u8207 Drop-Oldest \u7b56\u7565<\/h3>\n\n\n\n<p>ToF \u7684\u8cc7\u6599\u7522\u751f\u5728\u80cc\u666f\u57f7\u884c\u7dd2\u8dd1\u3002\u5728 <code>CameraTofHelpler.java<\/code> \u88e1\uff0c\u6211\u5011\u7dad\u8b77\u4e86\u4e00\u500b\u56fa\u5b9a\u9577\u5ea6\u7684 <code>ArrayBlockingQueue<\/code>\u3002<\/p>\n\n\n\n<p>\u5982\u679c ToF \u7522\u751f\u7684\u901f\u5ea6\u6bd4 RGB \u62ff\u53d6\u7684\u901f\u5ea6\u5feb\uff0c\u6216\u8005\u968a\u5217\u585e\u6eff\u4e86\uff0c\u6211\u5011\u6703<strong>\u4e3b\u52d5\u4e1f\u68c4\u6700\u820a\u7684\u90a3\u4e00\u5e40<\/strong>\uff0c\u78ba\u4fdd\u968a\u5217\u6700\u524d\u7aef\u6c38\u9060\u662f\u300c\u8ddd\u96e2\u73fe\u5728\u6700\u8fd1\u300d\u7684\u8cc7\u6599\uff1a<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ CameraTofHelpler.java\nprivate ArrayBlockingQueue&amp;lt;byte&#x5B;]&gt; mRawQueue = new ArrayBlockingQueue&amp;lt;&gt;(RAW_QUEUE_MAX_SIZE);\nprivate ArrayBlockingQueue&amp;lt;byte&#x5B;]&gt; mFreeRawQueue = ...;\n\n\/\/ \u7576 ToF \u5e95\u5c64\u5410\u8cc7\u6599\u6642\nsynchronized (CameraTofHelpler.this) {\n    if (mRawQueueSize &gt;= RAW_QUEUE_MAX_SIZE) {\n        \/\/ \u968a\u5217\u6eff\u4e86\u4ee3\u8868 RGB \u9084\u6c92\u4f86\u62ff\uff0c\u4e3b\u52d5\u4e1f\u68c4\u6700\u820a\u7684\u4e00\u5e40\uff08Drop-Oldest\uff09\n        buffer = mRawQueue.poll(0, TimeUnit.MILLISECONDS);\n    }\n    mRawQueue.offer(buffer);\n}\n\n\/\/ \u4f9b RGB \u706b\u8eca\u982d\u8abf\u7528\u7684\u975e\u963b\u585e\u63d0\u53d6\u51fd\u6578\npublic void getData(int timeoutMS, byte&#x5B;] buffer) {\n    synchronized (CameraTofHelpler.this) {\n        byte&#x5B;] tmp = mRawQueue.poll(timeoutMS, TimeUnit.MILLISECONDS);\n        if (tmp != null) {\n            System.arraycopy(tmp, 0, buffer, 0, buffer.length);\n            offerData(tmp); \/\/ \u8a18\u61b6\u9ad4\u6c60\u56de\u6536\u91cd\u7528 (0-GC)\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p>\u900f\u904e\u9019\u5957\u6a5f\u5236\uff0c\u9001\u9032\u5f8c\u9762 Pipeline \u7684\u6bcf\u4e00\u5305 <code>CameraData<\/code>\uff0cRGB \u8207 ToF \u90fd\u662f\u5728\u6beb\u79d2\u7d1a\u8aa4\u5dee\u5167\u7d44\u88dd\u5b8c\u6210\u7684\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u9032 Pipeline\uff1aToF \u9ede\u96f2\u8f49 IR\/Depth \u5716\u50cf<\/h2>\n\n\n\n<p>\u62ff\u5230\u6e4a\u597d\u5305\u7684 <code>CameraData<\/code> \u4e4b\u5f8c\uff0c\u7b2c\u4e00\u6b65\u662f\u5728 <code>TofRawToIrDepth<\/code> \u4e2d\u5c07 ToF \u5410\u51fa\u4f86\u7684 Raw \u8cc7\u6599\u8f49\u6210 OpenCV <code>Mat<\/code>\uff1a<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\npackage com.iam3d.sdk.service.detect.steps;\n\npublic class TofRawToIrDepth implements Step&amp;lt;CameraData, DetectInfo&gt; {\n    @Override\n    public boolean process(PipelineContext&amp;lt;CameraData, DetectInfo&gt; context) {\n        CameraData imageData = context.getInput();\n        DetectInfo detectInfo = context.getOutput();\n\n        if (imageData.getIrFrame() != null) {\n            \/\/ \u7528 OpenCV Mat \u5305\u88dd IR Raw Frame\uff08\u55ae\u901a\u9053 8-bit\uff09\n            Mat depMat = new Mat(\n                CameraProxy.getInstance().getIrFrameHeight(), \n                CameraProxy.getInstance().getIrFrameWidth(), \n                CvType.CV_8U\n            );\n            depMat.put(0, 0, imageData.getIrFrame());\n\n            \/\/ Debug \u6a21\u5f0f\u4e0b\u53ef\u843d\u76e4\u9a57\u8b49 IR \u5716\u7247\n            if (DebugFlags.saveIrCameraImages) {\n                MatOfByte imagetBytes = new MatOfByte();\n                Imgcodecs.imencode(&quot;.png&quot;, depMat, imagetBytes);\n                String path = Environment.getExternalStorageDirectory().getAbsolutePath() \n                    + &quot;\/rawir&quot; + imageData.id() + &quot;.png&quot;;\n                FileUtils.write(new File(path), imagetBytes.toArray());\n            }\n        }\n        return true;\n    }\n}\n<\/pre><\/div>\n\n\n<p>\u539f\u672c\u5728 Java \u88e1\u89e3\u6790 4 \u901a\u9053\u9ede\u96f2\uff08640\u00d7480\u00d74 = 122 \u842c\u6b21\u8fed\u4ee3\uff09\u9700\u8981 18 \u6beb\u79d2\uff0c\u6211\u5011\u628a\u9019\u6bb5\u5ea7\u6a19\u8f49\u63db\u4e0b\u6c89\u5230 C++ \u7528 NEON \u6307\u4ee4\u96c6\u4e00\u6b21\u62bd 4 \u500b float\uff0c\u8017\u6642\u76f4\u63a5\u7e2e\u77ed\u5230 2 \u6beb\u79d2\u4ee5\u4e0b\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3D \u7a7a\u9593\u4eba\u81c9\u5c0d\u9f4a\uff1a\u6293\u9f3b\u5c16\u6df1\u5ea6\u8207\u63d0\u65e9\u77ed\u8def<\/h2>\n\n\n\n<p>\u6709\u4e86\u6df1\u5ea6\u77e9\u9663\uff0c\u63a5\u4e0b\u4f86\u8981\u5f9e 3D \u7a7a\u9593\u4e2d\u628a\u4eba\u81c9\u300c\u6316\u300d\u51fa\u4f86\u3002<\/p>\n\n\n\n<p>\u5728 <code>AlignDepthFace<\/code> \u6b65\u9a5f\u4e2d\uff0c\u6211\u5011\u900f\u904e <code>getNoseDepth<\/code> \u8a08\u7b97\u4eba\u81c9\u96e2\u93e1\u982d\u6700\u8fd1\u7684\u5e7e\u4f55\u7279\u5fb5\u9ede\u2014\u2014<strong>\u9f3b\u5c16\u6df1\u5ea6<\/strong>\uff1a<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\npackage com.iam3d.sdk.service.detect.steps;\n\npublic class AlignDepthFace implements Step&amp;lt;CameraData, DetectInfo&gt; {\n    @Override\n    public boolean process(PipelineContext&amp;lt;CameraData, DetectInfo&gt; context) {\n        CameraData cameraData = context.getInput();\n        DetectInfo detectInfo = context.getOutput();\n\n        int mDepthFrameWidth = CameraProxy.getInstance().getDepthFrameWidth();\n        int mDepthFrameHeight = CameraProxy.getInstance().getDepthFrameHeight();\n        int xDepthCropSize = CameraProxy.getInstance().getWidthSizeToCropDepth();\n        int yDepthCropSize = CameraProxy.getInstance().getHeightSizeToCropDepth();\n\n        \/\/ 1. \u6aa2\u67e5\u81c9\u90e8 BBox \u662f\u5426\u5728\u756b\u9762\u908a\u754c\u5167\n        if (!isBBoxInRange(detectInfo.faceDepthPos, mDepthFrameWidth, mDepthFrameHeight, xDepthCropSize, yDepthCropSize)) {\n            return false;\n        }\n\n        \/\/ 2. \u8a08\u7b97\u9f3b\u5c16\u6df1\u5ea6\u503c\uff08\u6beb\u7c73\uff09\n        int noseDepth = getNoseDepth(\n            cameraData.getShortDepthData(), mDepthFrameWidth, mDepthFrameHeight,\n            detectInfo.faceDepthPos, xDepthCropSize, yDepthCropSize\n        );\n\n        \/\/ \u95dc\u9375\u512a\u5316\uff1a\u8ddd\u96e2\u4e0d\u5408\u6cd5\u76f4\u63a5\u77ed\u8def\u4e2d\u65b7\uff0c\u7d55\u4e0d\u6d6a\u8cbb CPU \u8dd1\u5f8c\u7e8c\u6a21\u578b\n        if (noseDepth &amp;lt; 0) {\n            return false;\n        }\n        detectInfo.setDepthFaceDistance(noseDepth);\n\n        \/\/ 3. \u6df1\u5ea6\u6b78\u4e00\u5316\u4e26\u88c1\u5207\u51fa 3D \u4eba\u81c9\u9001\u9032 Align \u6a21\u578b\n        Bitmap normalizedDepth = normalizeTofDepth(\n            cameraData.getShortDepthData(), mDepthFrameWidth, mDepthFrameHeight,\n            30, 90, noseDepth, xDepthCropSize, yDepthCropSize\n        );\n\n        alignInput.setBitmap(normalizedDepth);\n        alignInput.setFacePos(detectInfo.faceDepthPos);\n        inference.setInput(alignInput);\n        inference.setOutput(alignOutput);\n        Face3DAIModel.start().use(Model.FACE_ALIGN_MODEL).infer(inference);\n\n        detectInfo.alignDepthSuccess = alignOutput.isSuccess();\n        detectInfo.alignedDepthFace = alignOutput.getAlignedBitmap();\n        return detectInfo.alignDepthSuccess;\n    }\n}\n<\/pre><\/div>\n\n\n<p>\u5982\u679c\u4eba\u5728\u6709\u6548\u8fa8\u8b58\u7bc4\u570d\u5916\uff08\u4f8b\u5982\u592a\u9060\u6216\u592a\u8fd1\uff09\uff0c<code>noseDepth<\/code> \u56de\u50b3\u8ca0\u503c\uff0c\u6574\u689d Pipeline \u5728\u9019\u88e1\u76f4\u63a5\u77ed\u8def\u4e2d\u65b7\uff0c\u628a\u73cd\u8cb4\u7684\u7b97\u529b\u7559\u7d66\u4e0b\u4e00\u5e40\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u96d9\u6a21\u614b IR + Depth \u96d9\u6d41\u6d3b\u9ad4\u9632\u507d<\/h2>\n\n\n\n<p>\u5230\u4e86\u6700\u5f8c\u4e00\u6b65\uff0c\u6211\u5011\u624b\u4e0a\u6709\u4e86\u5169\u5f35\u5c0d\u9f4a\u597d\u7684\u4eba\u81c9\uff1a<\/p>\n\n\n\n<ul>\n<li><strong>IR \u4eba\u81c9\u5716<\/strong>\uff1a\u770b\u76ae\u819a\u7d05\u5916\u53cd\u5c04\u7279\u5fb5\uff08\u8fa8\u8b58\u7d19\u5f35\u3001\u87a2\u5e55\u7ffb\u62cd\uff09\u3002<\/li>\n\n\n\n<li><strong>Depth \u4eba\u81c9\u5716<\/strong>\uff1a\u770b\u4e94\u5b98 3D \u51f9\u51f8\u5e7e\u4f55\u7279\u5fb5\uff08\u8fa8\u8b58\u5e73\u9762\u7167\u7247\u3001\u77fd\u81a0\u9762\u5177\uff09\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u5728 <code>CheckAlignedDepthLiveness<\/code> \u88e1\uff0c\u6211\u5011\u767c\u52d5\u96d9 TFLite \u6a21\u578b\u4e26\u884c\u63a8\u7406\uff0c\u6700\u5f8c\u63a1\u7528\u56b4\u683c\u7684 <strong>AND \u5224\u5b9a<\/strong>\uff1a<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\npackage com.iam3d.sdk.service.detect.steps;\n\npublic class CheckAlignedDepthLiveness implements Step&amp;lt;CameraData, DetectInfo&gt; {\n    private LivenssOutput irOutput = new LivenssOutput();\n    private Inference&amp;lt;Bitmap, LivenssOutput&gt; irInference = new Inference&amp;lt;&gt;();\n    private LivenssOutput depthOutput = new LivenssOutput();\n    private Inference&amp;lt;Bitmap, LivenssOutput&gt; depthInference = new Inference&amp;lt;&gt;();\n\n    @Override\n    public boolean process(PipelineContext&amp;lt;CameraData, DetectInfo&gt; context) {\n        DetectInfo detectInfo = context.getOutput();\n        if (!detectInfo.alignDepthSuccess) return false;\n\n        \/\/ 1. IR \u7d05\u5916\u6d3b\u9ad4\u63a8\u7406\n        irInference.setInput(detectInfo.alignedIRFace);\n        irInference.setOutput(irOutput);\n        Face3DAIModel.start().use(Model.IR_LIVENESS_MODEL).infer(irInference);\n\n        \/\/ 2. 3D Depth \u6df1\u5ea6\u6d3b\u9ad4\u63a8\u7406\n        depthInference.setInput(detectInfo.alignedDepthFace);\n        depthInference.setOutput(depthOutput);\n        Face3DAIModel.start().use(Model.DEPTH_LIVENESS_MODEL).infer(depthInference);\n\n        \/\/ 3. \u96d9\u9632\u7dda AND \u5224\u5b9a\uff1a\u5169\u8005\u90fd\u904e\u624d\u7b97\u771f\u6d3b\u4eba\n        detectInfo.liveness = (irInference.getOutput().isPass() &amp;amp;&amp;amp; depthInference.getOutput().isPass());\n\n        \/\/ 4. \u91cd\u7f6e\u8f38\u51fa\u5bb9\u5668\u4f9b\u4e0b\u4e00\u5e40\u91cd\u7528 (0-GC)\n        irOutput.reset();\n        depthOutput.reset();\n\n        return detectInfo.liveness;\n    }\n}\n<\/pre><\/div>\n\n\n<p>\u9019\u5169\u9053\u9632\u7dda\u662f\u4e92\u88dc\u7684\uff1a<\/p>\n\n\n\n<ul>\n<li>\u62ff\u4e00\u5f35\u9ad8\u89e3\u6790\u5ea6\u5f69\u8272\u5217\u5370\u7167\u7247\uff1aIR \u6d3b\u9ad4\u6a21\u578b\u53ef\u80fd\u88ab\u7279\u6b8a\u6cb9\u58a8\u9a19\u904e\uff0c\u4f46 3D \u6df1\u5ea6\u6a21\u578b\u4e00\u6e2c\u767c\u73fe\u6574\u5f35\u81c9\u5728\u540c\u4e00\u500b\u5e73\u9762\u4e0a\uff0c\u76f4\u63a5\u88ab Depth \u6514\u622a\u3002<\/li>\n\n\n\n<li>\u62ff\u4e00\u500b 3D \u5217\u5370\u7684\u7acb\u9ad4\u5047\u9762\u5177\uff1aDepth \u6a21\u578b\u770b\u5230\u4e86\u51f9\u51f8\u9f3b\u6a11\uff0c\u4f46 IR \u6a21\u578b\u4e00\u6e2c\u767c\u73fe\u6750\u8cea\u53cd\u5c04\u5149\u8b5c\u6839\u672c\u4e0d\u662f\u6d3b\u9ad4\u76ae\u819a\uff0c\u76f4\u63a5\u88ab IR \u6514\u622a\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u9019\u5c31\u662f MK1 \u80fd\u901a\u904e BCTC \u91d1\u878d\u7d1a\u9632\u507d\u8a8d\u8b49\u7684\u6838\u5fc3\u908f\u8f2f\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<p>\u5728 2GB RAM \u7684\u7834\u88dd\u7f6e\u4e0a\u641e\u96d9\u93e1\u982d\uff0c\u6700\u96e3\u7684\u5f80\u5f80\u4e0d\u662f\u6a21\u578b\u672c\u8eab\uff0c\u800c\u662f<strong>\u600e\u9ebc\u5728\u8edf\u9ad4\u5c64\u9762\u628a\u5169\u8def\u4e0d\u540c\u5e40\u7387\u3001\u4e0d\u540c\u683c\u5f0f\u7684\u76f8\u6a5f\u6d41\u4f3a\u5019\u597d<\/strong>\uff1a<\/p>\n\n\n\n<ol>\n<li><strong>RGB \u706b\u8eca\u982d + 0ms \u975e\u963b\u585e\u62c9\u53d6<\/strong>\uff1a\u7528\u7a69\u5b9a\u5e40\u7387\u5e36\u52d5\u6162\u901f\u5e40\uff0c\u907f\u514d UI \u5361\u9813\u3002<\/li>\n\n\n\n<li><strong>\u56fa\u5b9a\u9577\u5ea6\u968a\u5217 + Drop-Oldest<\/strong>\uff1a\u5be7\u53ef\u4e1f\u6389\u904e\u671f\u5f71\u683c\uff0c\u4e5f\u7d55\u4e0d\u8b93\u6642\u9593\u932f\u4f4d\u7684\u9ad2\u8cc7\u6599\u9032 AI\u3002<\/li>\n\n\n\n<li><strong>\u53ca\u65e9\u77ed\u8def\u8207 0-GC<\/strong>\uff1a\u7121\u6548\u8ddd\u96e2\u76f4\u63a5\u4e2d\u65b7\uff0c\u5bb9\u5668\u91cd\u8907\u5229\u7528\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u628a\u9019\u5957\u8cc7\u6599\u6d41\u6253\u901a\uff0c\u591a\u93e1\u982d\u624d\u80fd\u771f\u6b63\u6210\u70ba\u9632\u507d\u7684\u6b66\u5668\uff0c\u800c\u4e0d\u662f\u62d6\u57ae\u7cfb\u7d71\u7684\u5305\u88b1\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u53c3\u8003\u8cc7\u6599 (References)<\/h2>\n\n\n\n<ol>\n<li><strong>BCTC \u91d1\u878d\u4eba\u81c9\u8b58\u5225\u6280\u8853\u898f\u7bc4<\/strong>: \u4e2d\u570b\u91d1\u878d\u79fb\u52d5\u652f\u4ed8\u4eba\u81c9\u8b58\u5225\u6280\u8853\u5b89\u5168\u898f\u7bc4 (<code>JR\/T 0166-2018<\/code>).<\/li>\n\n\n\n<li><strong>Android Camera2 API Reference<\/strong>: Multi-Camera synchronization &amp; ImageReader buffer management.<br><a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/package-summary\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/package-summary<\/a><\/li>\n\n\n\n<li><strong>OpenCV Mat &amp; Color Space Specifications<\/strong>: OpenCV Matrix manipulation and memory layout.<br><a href=\"https:\/\/docs.opencv.org\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/docs.opencv.org<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>\u5728\u9580\u7981\u6a5f\u4e0a\uff0c\u55ae\u9760\u4e00\u9846\u666e\u901a RGB \u93e1\u982d\u505a\u4eba\u81c9\u8fa8\u8b58\uff0c\u57fa\u672c\u4e0a\u5c31\u662f\u628a\u5927\u9580\u655e\u958b\u7d66\u5f69\u8272\u5217\u5370\u7167\u7247\u3001iPad \u87a2\u5e55\u548c 3D \u9762\u5177\u96a8\u4fbf\u9032\u3002\u70ba\u4e86\u904e BCTC\uff08\u9280\u884c\u5361\u6aa2\u6e2c\u4e2d\u5fc3\uff09\u91d1\u878d\u7d1a\u652f\u4ed8\u8a8d\u8b49\uff0c\u6211\u5011\u5728 MSM8937 \u9019\u584a\u7834\u677f\u5b50\u4e0a\uff0c\u540c\u6642\u639b\u4e86 RGB \u76f8\u6a5f\u8207 3D ToF \u6df1\u5ea6\u611f\u6e2c\u5668\uff08\u5410\u51fa IR \u7070\u968e\u5716\u8207 16-bit \u9ede\u96f2\uff09\u3002<\/p>\n","protected":false},"author":1,"featured_media":971,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[50,3,80],"tags":[],"_links":{"self":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts\/968"}],"collection":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=968"}],"version-history":[{"count":6,"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts\/968\/revisions"}],"predecessor-version":[{"id":981,"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts\/968\/revisions\/981"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/media\/971"}],"wp:attachment":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=968"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=968"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=968"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}