站長資訊網
最全最豐富的資訊網站

淺析node怎么實現ocr

怎么實現ocr(光學字符識別)?下面本篇文章給大家介紹一下使用node實現實現實現ocr的方法,希望對大家有所幫助!

淺析node怎么實現ocr

node.js極速入門課程:進入學習

ocr即光學字符識別,簡單的來說就是把圖片上的文字識別出來。

很遺憾我只是一個底層的web程序員?,不咋會AI,要想實現ocr,只能找找第三方庫了。

python語言有很多ocr的第三方庫,找了很久nodejs實現ocr的第三方庫,最后發現了tesseract.js這個庫還是能很方便的實現ocr。【相關教程推薦:nodejs視頻教程】

效果展示

在線示例: http://www.lolmbbs.com/tool/ocr

淺析node怎么實現ocr

詳細代碼

tesserract.js 這個庫提供了多個版本供選擇,我這里使用的是離線的版本tesseract.js-offline,畢竟誰都由網絡不好的時候。
淺析node怎么實現ocr
默認示例代碼

const { createWorker } = require('tesseract.js'); const path = require('path');  const worker = createWorker({   langPath: path.join(__dirname, '..', 'lang-data'),    logger: m => console.log(m), });  (async () => {   await worker.load();   await worker.loadLanguage('eng');   await worker.initialize('eng');   const { data: { text } } = await worker.recognize(path.join(__dirname, '..', 'images', 'testocr.png'));   console.log(text);   await worker.terminate(); })();
登錄后復制

1. 支持多語言識別

tesseract.js 離線版本默認示例代碼只支持識別英文,如果識別中文,結果會是一堆問號。但是幸運的是你可以導入多個訓練好的語言模型,讓它支持多個語言的識別。

  • 從https://github.com/naptha/tessdata/tree/gh-pages/4.0.0這里下載你需要的對應語言模型,放入到根目錄下的lang-data目錄下
    我這里選擇了中(chi_sim.traineddata.gz)日(jpn.traineddata.gz)英(eng.traineddata.gz)三國語言模型。

  • 修改代碼中加載和初始化模型的語言項配置,來同時支持中日英三國語言。

await worker.loadLanguage('chi_sim+jpn+eng'); await worker.initialize('chi_sim+jpn+eng');
登錄后復制

為了方便大家的測試,我在示例的離線版本,已經放入了中日韓三國語言的訓練模型和實例代碼以及測試圖片。
https://github.com/Selenium39/tesseract.js-offline

2. 提高識別性能

如果你運行了離線的版本,你會發現模型的加載和ocr的識別有點慢。可以通過這兩個步驟優化。

  • web項目中,你可以在應用一啟動的時候就加載模型,這樣后續接收到ocr請求的時候就可以不用等待模型加載了。

  • 參照Why I refactor tesseract.js v2?這篇博客,可以通過createScheduler方法添加多個worker線程來并發的處理ocr請求。

多線程并發處理ocr請求示例

const Koa = require('koa') const Router = require('koa-router') const router = new Router() const app = new Koa() const path = require('path') const moment = require('moment') const { createWorker, createScheduler } = require('tesseract.js')  ;(async () => {   const scheduler = createScheduler()   for (let i = 0; i < 4; i++) {     const worker = createWorker({       langPath: path.join(__dirname, '.', 'lang-data'),       cachePath: path.join(__dirname, '.'),       logger: m => console.log(`${moment().format('YYYY-MM-DD HH:mm:ss')}-${JSON.stringify(m)}`)     })     await worker.load()     await worker.loadLanguage('chi_sim+jpn+eng')     await worker.initialize('chi_sim+jpn+eng')     scheduler.addWorker(worker)   }   app.context.scheduler = scheduler })()  router.get('/test', async (ctx) => {   const { data: { text } } = await ctx.scheduler.addJob('recognize', path.join(__dirname, '.', 'images', 'chinese.png'))   // await ctx.scheduler.terminate()   ctx.body = text })  app.use(router.routes(), router.allowedMethods()) app.listen(3002)
登錄后復制

發起并發請求,可以看到多個worker再并發執行ocr任務

ab -n 4 -c 4 localhost:3002/test

淺析node怎么實現ocr

3.前端代碼

效果展示中的前端代碼主要是用了elementui組件和vue-cropper這個組件實現。

vue-cropper組件具體的使用可以參考我的這篇博客vue圖片裁剪:使用vue-cropper做圖片裁剪

ps: 上傳圖片的時候可以先在前端加載上傳圖片的base64,先看到上傳的圖片,再請求后端上傳圖片 ,對用戶的體驗比較好

完整代碼如下

<template>   <div>     <div style="margin-top:30px;height:500px">       <div class="show">         <vueCropper           v-if="imgBase64"           ref="cropper"           :img="imgBase64"           :output-size="option.size"           :output-type="option.outputType"           :info="true"           :full="option.full"           :can-move="option.canMove"           :can-move-box="option.canMoveBox"           :original="option.original"           :auto-crop="option.autoCrop"           :fixed="option.fixed"           :fixed-number="option.fixedNumber"           :center-box="option.centerBox"           :info-true="option.infoTrue"           :fixed-box="option.fixedBox"           :max-img-size="option.maxImgSize"           style="background-image:none"           @mouseenter.native="enter"           @mouseleave.native="leave"         ></vueCropper>         <el-upload           v-else           ref="uploader"           class="avatar-uploader"           drag           multiple           action=""           :show-file-list="false"           :limit="1"           :http-request="upload"         >           <i class="el-icon-plus avatar-uploader-icon"></i>         </el-upload>       </div>       <div         class="ocr"         @mouseleave="leaveCard"       >         <el-card           v-for="(item,index) in ocrResult"           :key="index"           class="card-box"           @mouseenter.native="enterCard(item)"         >           <el-form             size="small"             label-width="100px"             label-position="left"           >             <el-form-item label="識別結果">               <el-input v-model="item.text"></el-input>             </el-form-item>           </el-form>         </el-card>       </div>     </div>     <div style="margin-top:10px">       <el-button         size="small"         type="primary"         style="width:60%"         @click="doOcr"       >         文字識別(OCR)       </el-button>     </div>   </div> </template>  <script> import { uploadImage, ocr } from '../utils/api' export default {   name: 'Ocr',   data () {     return {       imgSrc: '',       imgBase64: '',       option: {         info: true, // 裁剪框的大小信息         outputSize: 0.8, // 裁剪生成圖片的質量         outputType: 'jpeg', // 裁剪生成圖片的格式         canScale: false, // 圖片是否允許滾輪縮放         autoCrop: true, // 是否默認生成截圖框         fixedBox: false, // 固定截圖框大小 不允許改變         fixed: false, // 是否開啟截圖框寬高固定比例         fixedNumber: [7, 5], // 截圖框的寬高比例         full: true, // 是否輸出原圖比例的截圖         canMove: false, // 時候可以移動原圖         canMoveBox: true, // 截圖框能否拖動         original: false, // 上傳圖片按照原始比例渲染         centerBox: true, // 截圖框是否被限制在圖片里面         infoTrue: true, // true 為展示真實輸出圖片寬高 false 展示看到的截圖框寬高         maxImgSize: 10000       },       ocrResult: []     }   },   methods: {     upload (fileObj) {       const file = fileObj.file       const reader = new FileReader()       reader.readAsDataURL(file)       reader.onload = () => {         this.imgBase64 = reader.result       }       const formData = new FormData()       formData.append('image', file)       uploadImage(formData).then(res => {         this.imgUrl = res.imgUrl       })     },     doOcr () {       const cropAxis = this.$refs.cropper.getCropAxis()       const imgAxis = this.$refs.cropper.getImgAxis()       const cropWidth = this.$refs.cropper.cropW       const cropHeight = this.$refs.cropper.cropH       const position = [         (cropAxis.x1 - imgAxis.x1) / this.$refs.cropper.scale,         (cropAxis.y1 - imgAxis.y1) / this.$refs.cropper.scale,         cropWidth / this.$refs.cropper.scale,         cropHeight / this.$refs.cropper.scale       ]       const rectangle = {         top: position[1],         left: position[0],         width: position[2],         height: position[3]       }       if (this.imgUrl) {         ocr({ imgUrl: this.imgUrl, rectangle }).then(res => {           this.ocrResult.push(             {               text: res.text,               cropInfo: { //截圖框顯示的大小                 width: cropWidth,                 height: cropHeight,                 left: cropAxis.x1,                 top: cropAxis.y1               },               realInfo: rectangle //截圖框在圖片上真正的大小             })         })       }     },     enterCard (item) {       this.$refs.cropper.goAutoCrop()// 重新生成自動裁剪框       this.$nextTick(() => {         // if cropped and has position message, update crop box         // 設置自動裁剪框的寬高和位置         this.$refs.cropper.cropOffsertX = item.cropInfo.left         this.$refs.cropper.cropOffsertY = item.cropInfo.top         this.$refs.cropper.cropW = item.cropInfo.width         this.$refs.cropper.cropH = item.cropInfo.height       })     },     leaveCard () {       this.$refs.cropper.clearCrop()     },     enter () {       if (this.imgBase64 === '') {         return       }       this.$refs.cropper.startCrop() // 開始裁剪     },     leave () {       this.$refs.cropper.stopCrop()// 停止裁剪     }   }  } </script>
登錄后復制

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久国产成人亚洲精品影院 | 牛牛在线精品免费视频观看| 亚洲欧美精品午睡沙发| 久久99国内精品自在现线| 久久久久夜夜夜精品国产| 久久露脸国产精品| A级精品国产片在线观看| 日韩福利电影在线观看| 手机日韩精品视频在线看网站| 久久久无码精品亚洲日韩按摩| 四虎精品影库4HUTV四虎| 亚洲日韩国产成网在线观看 | 中文字幕日韩丝袜一区| 国产精品免费看香蕉| 国精产品一品二品国精品69xx | 青青草原精品国产亚洲av| 精品一区二区三区免费| 日韩精品亚洲aⅴ在线影院| 国产精品videossex白浆| 亚洲精品色婷婷在线影院| 亚洲av无码成人精品区| 视频二区国产精品职场同事| 亚洲熟妇AV日韩熟妇在线| 日韩精品人妻系列无码专区免费| 囯产精品久久久久久久久久妞妞| 久久精品成人免费网站| 7777久久久国产精品消防器材| 亚洲av日韩av无码| 日韩一区二区三区免费播放| 国产成人精品实拍在线| 国产91成人精品亚洲精品| 国产产在线精品亚洲AAVV| 日韩国产一区二区| 中文字幕无码日韩专区| 日韩亚洲AV无码一区二区不卡| 亚洲精品国产摄像头| 少妇人妻偷人精品无码AV| 国产精品视频永久免费播放| 亚洲国产精品成人AV在线| 精品国偷自产在线视频99| 精品久久久无码中文字幕边打电话|