【實戰教程】React Native項目集成Google ML Kit實現離線水表OCR識別

前言

在這里插入圖片描述

在移動應用開發中,OCR(光學字符識別)技術廣泛應用于各類場景。本文將詳細介紹如何在React Native項目中集成Google ML Kit,實現離線水表數字識別功能。全程使用TypeScript,并針對React Native 0.74版本進行適配,解決版本兼容性問題。

技術棧

  • React Native: v0.74
  • TypeScript/TSX
  • Google ML Kit
  • React Native Image Picker
  • Native Base UI組件庫

1. 安裝必要依賴

首先,需要安裝相關依賴包:

# 安裝ML Kit文本識別包
yarn add @react-native-ml-kit/text-recognition# 安裝文件處理包(用于圖像處理)
yarn add react-native-fs

2. Android項目配置

2.1 修改build.gradle

打開android/app/build.gradle,添加以下配置:

android {defaultConfig {// 其他配置...// ML Kit配置missingDimensionStrategy 'react-native-camera', 'general'}packagingOptions {pickFirst '**/*.so'}
}dependencies {// 其他依賴...// 添加離線文本識別模型implementation 'com.google.mlkit:text-recognition:16.0.0'
}

2.2 配置AndroidManifest.xml

確保在AndroidManifest.xml中添加相機權限:

<manifest ... ><uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera" android:required="false" /><uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /><!-- 其他配置... -->
</manifest>

3. 核心代碼實現

3.1 導入相關模塊

// OcrDemo.tsx
import React, { useState, useEffect } from 'react';
import {VStack, Button, Image, Text, Box, Spinner, HStack, Icon, useToast
} from 'native-base';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { Platform, PermissionsAndroid } from 'react-native';
// 關鍵導入:ML Kit文本識別
import TextRecognition from '@react-native-ml-kit/text-recognition';

3.2 相機權限請求函數

// 請求相機權限
const requestCameraPermission = async () => {if (Platform.OS === 'android') {try {const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA,{title: "需要相機權限",message: "應用需要使用您的相機以拍攝水表照片",buttonNeutral: "稍后詢問",buttonNegative: "取消",buttonPositive: "確定"});return granted === PermissionsAndroid.RESULTS.GRANTED;} catch (err) {console.warn(err);return false;}}return true;
};

3.3 OCR識別核心函數

// 使用ML Kit進行OCR識別
const performOcrRecognition = async (imagePath: string) => {try {console.log('開始OCR識別,圖像路徑:', imagePath);// 處理圖像路徑,確保使用file:// URI格式let correctPath = imagePath;if (Platform.OS === 'android' && !imagePath.startsWith('file://')) {correctPath = `file://${imagePath}`;}console.log('使用的圖像路徑:', correctPath);// 調用TextRecognition,使用離線模式const result = await TextRecognition.recognize(correctPath);console.log('OCR結果:', result);// 處理OCR結果,提取數字let meterReading = extractMeterReading(result);return meterReading;} catch (error) {console.error('OCR處理錯誤:', error);throw error;}
};

3.4 提取水表讀數函數

// 提取水表讀數
const extractMeterReading = (ocrResult: any) => {// 從OCR結果中提取所有數字序列let allDigitSequences: string[] = [];// 檢查結果是否有效if (!ocrResult || !ocrResult.blocks || !Array.isArray(ocrResult.blocks)) {console.log('OCR結果無效或沒有文本塊');return '';}// 遍歷識別到的所有文本塊ocrResult.blocks.forEach((block: any) => {if (block.lines && Array.isArray(block.lines)) {// 遍歷每個塊中的每一行block.lines.forEach((line: any) => {if (line && line.text) {// 獲取這一行的完整文本const lineText = line.text;// 使用正則表達式提取連續的數字序列(可能包含小數點)const digitRegex = /\d+(\.\d+)?/g;const matches = lineText.match(digitRegex);if (matches) {allDigitSequences = [...allDigitSequences, ...matches];}}});}});console.log('提取的數字序列:', allDigitSequences);// 如果找到了數字序列,嘗試確定哪一個是水表讀數if (allDigitSequences.length > 0) {// 篩選策略:選擇符合水表讀數特征的數字// 水表讀數通常是5-8位數字,可能帶小數點const potentialReadings = allDigitSequences.filter(seq => {// 檢查是否符合水表讀數的格式(例如:5-8位數字,可能有1位小數)return /^\d{5,8}(\.\d{1})?$/.test(seq);});// 如果有符合條件的讀數,返回第一個if (potentialReadings.length > 0) {return potentialReadings[0];}// 如果沒有符合特定條件的,就返回最長的數字序列return allDigitSequences.sort((a, b) => b.length - a.length)[0];}// 如果沒有找到任何數字序列,返回空字符串return '';
};

3.5 處理識別結果

當識別出多個可能結果時,讓用戶選擇正確讀數:

// 添加狀態存儲多個可能的讀數
const [potentialReadings, setPotentialReadings] = useState<string[]>([]);
const [selectedReadingIndex, setSelectedReadingIndex] = useState<number>(-1);// 處理識別結果
const handleRecognizeResult = async (result: any) => {// 提取所有可能的水表讀數const allDigits = extractAllDigitSequences(result);// 根據特征篩選可能的水表讀數(5-8位數字等)const candidates = filterPotentialReadings(allDigits);if (candidates.length === 0) {// 沒有找到符合條件的讀數toast.show({title: "未識別到讀數",description: "請嘗試重新拍攝清晰的水表照片",status: "warning"});return;} else if (candidates.length === 1) {// 只有一個結果,直接使用setRecognizedText(candidates[0]);} else {// 多個可能結果,展示給用戶選擇setPotentialReadings(candidates);}
};

3.6 用戶選擇UI組件

// 用戶選擇UI
{potentialReadings.length > 0 && (<VStack space={3} width="90%" mt={4}><Text fontSize="md" fontWeight="medium">檢測到多個可能的讀數,請選擇正確的:</Text>{potentialReadings.map((reading, index) => (<Buttonkey={index}variant={selectedReadingIndex === index ? "solid" : "outline"}colorScheme="orange"onPress={() => {setSelectedReadingIndex(index);setRecognizedText(reading);}}>{reading}</Button>))}</VStack>
)}

4. 關鍵問題與解決方案

4.1 ML Kit模塊無法識別問題

問題:導入后TextRecognition報undefined錯誤

解決方案

// 正確的導入方式
import TextRecognition from '@react-native-ml-kit/text-recognition';
// 錯誤的導入方式
// import { TextRecognition } from '@react-native-ml-kit/text-recognition';

4.2 圖片路徑格式問題

問題:Android中圖片路徑需要以"file://"開頭

解決方案

// 處理圖像路徑,確保使用file:// URI格式
let correctPath = imagePath;
if (Platform.OS === 'android' && !imagePath.startsWith('file://')) {correctPath = `file://${imagePath}`;
}

4.3 多結果處理

問題:水表上存在多個數字區域導致識別混亂

解決方案

// 篩選策略:選擇符合水表讀數特征的數字
const potentialReadings = allDigitSequences.filter(seq => {// 水表讀數通常是5-8位數字,可能有1位小數return /^\d{5,8}(\.\d{1})?$/.test(seq);
});

5. 完整集成效果

通過以上步驟,我們成功實現了:

  1. Google ML Kit的離線OCR識別功能集成
  2. 相機拍照和相冊選擇功能
  3. 水表讀數的智能提取與篩選
  4. 多結果的用戶選擇機制

此解決方案完全支持離線使用,無需網絡連接即可工作。

在這里插入圖片描述

總結

本文詳細介紹了在React Native項目中集成Google ML Kit實現水表OCR識別的完整流程,包括環境配置、核心代碼實現和關鍵問題解決方案。希望對大家有所幫助!

如有任何問題或建議,歡迎在評論區留言交流!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904249.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

全球化電商平臺AWS云架構設計

業務需求&#xff1a; 支撐全球三大區域&#xff08;北美/歐洲/亞洲&#xff09;用戶訪問&#xff0c;延遲<100ms處理每秒50,000訂單的峰值流量混合云架構整合本地ERP系統全年可用性99.99%滿足GDPR和PCI DSS合規要求 以下是一個體現AWS專家能力的全球化電商平臺架構設計方…

jupyter notebook運行簡單程序

一. 使用 cmd 創建虛擬環境 1.創建虛擬環境 &#xff08;1&#xff09;創建新的虛擬環境&#xff08;本項目名設置為zhineng&#xff09;&#xff0c;并設置python版本 conda create -n zhineng python3.6 &#xff08;2&#xff09;查看python版本 python --version &am…

【計算機視覺】語義分割:MMSegmentation:OpenMMLab開源語義分割框架實戰指南

深度解析MMSegmentation&#xff1a;OpenMMLab開源語義分割框架實戰指南 技術架構與設計哲學系統架構概覽核心技術特性 環境配置與安裝指南硬件配置建議詳細安裝步驟環境驗證 實戰全流程解析1. 數據集準備2. 配置文件定制3. 模型訓練與優化4. 模型評估與推理 核心功能擴展1. 自…

計算機圖形學編程(使用OpenGL和C++)(第2版)學習筆記 01.環境搭建

計算機圖形學編程(使用OpenGL和C)(第2版) 這是我學習計算機圖形學編程(使用OpenGL和C)的筆記&#xff0c;主要記錄學習心得及一些學習過程中遇到的問題和解決方案。源代碼存放在github上。 參考資料&#xff1a; 原書資源(程序代碼、模型、紋理、貼圖及圖表)下載ShaderToy學習…

代碼隨想錄算法訓練營第三十二天

LeetCode/卡碼網題目: 518. 零錢兌換 II377. 組合總和 Ⅳ790. 多米諾和托米諾平鋪(每日一題)57. 爬樓梯&#xff08;第八期模擬筆試&#xff09; 其他: 今日總結 往期打卡 背包問題特點: 滾動數組背包遍歷順序 完全背包從小到大,即基于當前物品更新過的繼續更新01背包從大到…

第十六屆藍橋杯 2025 C/C++組 密密擺放

目錄 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路&#xff1a; 思路詳解: 發個牢騷&#xff1a; 代碼&#xff1a; 代碼詳解&#xff1a; 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; P12337 [藍橋杯 2025 省 AB/Python B 第二…

分析rand()和srand()函數的功能

rand()和srand()函數原型&#xff1a; int rand(void) 返回一個范圍在 0 到 RAND_MAX 之間的偽隨機數。 void srand(unsigned int seed)用來給rand() 設置隨機數發生器&#xff0c;隨機數發生器輸出不同的數值&#xff0c;rand() 就會生成不同的隨機數 1)、在“D:\Keil_v5\AR…

debuginfo詳解

debuginfo 是 Linux 系統中存儲調試符號和源代碼信息的特殊軟件包&#xff0c;用于分析內核或用戶態程序的崩潰轉儲文件&#xff08;如 vmcore、coredump&#xff09;。它在調試復雜問題&#xff08;如內核崩潰、程序段錯誤&#xff09;時至關重要。以下是其核心作用、安裝方法…

Python 爬取微店商品列表接口(item_search)的實戰指南

在電商數據分析、市場調研或競品分析中&#xff0c;獲取商品列表信息是常見的需求。微店作為知名的電商平臺&#xff0c;提供了豐富的商品資源和相應的 API 接口。本文將詳細介紹如何使用 Python 爬蟲技術&#xff0c;通過微店的 item_search 接口根據關鍵詞搜索商品列表&#…

【bazel】bazel簡介及簡單使用

文章目錄 1. What is bazel?2. bazel的核心原理2.1 bazel的構建模型2.2 bazel的核心概念2.3 bazel的關鍵特性 3. bazel的使用3.1 劃分項目結構3.2 編寫BUILD文件3.3 bazel常用命令3.4 bazel依賴管理 參考內容 1. What is bazel? bazel是一個開源的構建工具&#xff0c;它基于…

【Mytais系列】Myatis的設計模式

目錄 設計模式 1. 工廠模式&#xff08;Factory Pattern&#xff09; 2. 建造者模式&#xff08;Builder Pattern&#xff09; 3. 動態代理模式&#xff08;Dynamic Proxy Pattern&#xff09; 4. 模板方法模式&#xff08;Template Method Pattern&#xff09; 5. 策略模…

【unity游戲開發入門到精通——UGUI】Mask組件實現UGUI遮罩

注意&#xff1a;考慮到UGUI的內容比較多&#xff0c;我將UGUI的內容分開&#xff0c;并全部整合放在【unity游戲開發——UGUI】專欄里&#xff0c;感興趣的小伙伴可以前往逐一查看學習。 文章目錄 前言如何實現UI遮罩1、Mask組件2、實例3、注意 專欄推薦完結 前言 Mask遮罩是…

Github2025-05-04php開源項目日報 Top10

根據Github Trendings的統計,今日(2025-05-04統計)共有10個項目上榜。根據開發語言中項目的數量,匯總情況如下: 開發語言項目數量PHP項目10Shell項目1Vue項目1Java項目1ASP項目1SecLists - 安全測試人員的伴侶 創建周期:4375 天開發語言:PHP協議類型:MIT LicenseStar數量…

MyBatis 一對多與多對一映射詳解教程

一、基礎概念與場景 一對多&#xff08;One-to-Many&#xff09; ? 定義&#xff1a;一個父對象包含多個子對象。 例如&#xff1a;一個商品&#xff08;Goods&#xff09;對應多個商品詳情&#xff08;GoodsDetail&#xff09; ? 實體類表現&#xff1a;父類中包含 List&l…

ChatGPT:重塑人工智能交互范式的破曉之作

2022年11月30日,總部位于舊金山的研究公司OpenAI正式發布了ChatGPT——一款以病毒式傳播速度席卷全球的AI聊天機器人。它不僅能像人類一樣生成內容、回答問題和解決問題,更在推出后的兩個月內吸引了超過1億月活躍用戶,刷新了消費級技術應用的最快采用率紀錄。這一里程碑事件…

在項目中如何對Map List等對象序列化及反序列化

我們知道&#xff0c;在自定義類中&#xff0c;若想完成序列化必須要實現Serializable接口。 那么在實現后如何進行序列化呢&#xff1f; 一.普通對象 序列化&#xff1a; 1.首先我們要定義一個 序列化所需要的工具類 ObjectMapper //定義序列化所需要的工具類 轉化機器…

筆試專題(十五)

文章目錄 排序子序列題解代碼 消減整數題解代碼 最長公共子序列(二)題解代碼 排序子序列 題目鏈接 題解 1. 貪心 模擬 2. 1 2 3 2 2 應該是有兩個排列子序列的&#xff0c;所以i n-1時ret 3. 把水平的位置和上升部分&#xff0c;水平位置和下降部分分為一個排列子序列 代…

Amazon Bedrock Converse API:開啟對話式AI新體驗

Amazon Bedrock Converse API&#xff1a;開啟對話式AI新體驗 前言 在當今人工智能飛速發展的時代&#xff0c;對話式AI已成為眾多應用的核心組成部分。從智能客服到智能助手&#xff0c;對話式AI為用戶帶來了便捷且高效的交互體驗。而Amazon Bedrock Converse API的出現&…

【Springboot知識】Springboot計劃任務Schedule詳解

文章目錄 Spring Boot 定時任務從原理到實現詳解一、核心原理分析1. 架構分層2. 核心組件3. 線程模型 二、基礎實現步驟1. 添加依賴2. 主類配置3. 定時任務類 三、高級配置技巧1. 自定義線程池2. 動態配置參數3. 分布式鎖集成&#xff08;Redis示例&#xff09; 四、異常處理機…

MySQL:聯合查詢

目錄 一、笛卡爾積 ?二、內連接 三、外連接 &#xff08;1&#xff09;左外連接 &#xff08;2&#xff09;右外連接 &#xff08;3&#xff09;全外連接 四、自連接 五、子查詢 &#xff08;1&#xff09;單行子查詢 &#xff08;2&#xff09;多行子查詢 &…