1. 程式人生 > 其它 >線上中文字元識別網站(前後端分離 REST)

線上中文字元識別網站(前後端分離 REST)

還是搭建單個django專案,需要把Django專案的各模組內容輸入到指定的檔案中

可檢視單檔案Django操作

一。搭建個檔案框架

二.編寫settings.py檔案

import os
# 設定專案根目錄
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# 加密簽名
SECRET_KEY = 'b!iohd&_vv@gmva5b6gq@k9t01_k^52uludvw8@h0)1fnez^8l'
DEBUG = True  # 設定當前為除錯模式
INSTALLED_APPS = ['app'] # 新增應用
ROOT_URLCONF = 'ocr.urls' # 設定專案路由檔案urls

三.編寫views.py檔案
通過匯入HttpResponse函式響應前端,返回內容為一個字串

from django.http import HttpResponse

def home1(request):
    return HttpResponse("hello world 8080!")

四.配置路由urls.py檔案

from django.urls import path
from app.views import home1
urlpatterns = [
    path('',home1,name='home'), # 其實一個的話,也可以不用加','這相當於個列表
]

五.編寫manage.py檔案

if __name__ == '__main__':
    import sys
    import django
    import os
    DJANGO_SETTINGS_MODULE = 'ocr.settins'
    # 設定環境變數
    os.environ.setdefault('DJANGO_SETTINGS_MODULE','ocr.settings')
    django.setup()
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)

完成了大致的配置

前端開發

前端的所有開發檔案全部放置在frontend資料夾中,style.css檔案是為本例項的個性話樣式定製檔案使用。
依然採用Bootstrap框架設計頁面
頁面頭部引入必要的CSS和JS檔案

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <title>線上中文字元識別</title>
</head>

頁面body部分採用Bootstrap柵格佈局,分為左右2個部分,各佔6個柵格,左6上傳圖片處,右6用來顯示結果

 <!--bootstrap柵格結構進行佈局;左6上傳圖片處,右6用來顯示結果-->
    <div class="container">
        <!--標題-->
        <div class="row">
            <div class="col-lg-12">
                <p class="text-center h1">
                    線上中文字元識別
                </p>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-12">
                <p class="text-center h3">
                    照片的尺寸窄些,效果好
                </p>
            </div>
        </div>
        <!--分隔符-->
        <div class="hr">
            <hr> <!--可省略結束符 /hr-->
        </div>
        <!--主體內容-->
        <div class="row">
            <br>
            <!--圖片上傳-->
            <div class="col-md-6">
                <img src="img/sample.jpg" alt="請上傳圖片" class="img-responsive" id="photoIn">
                <!--id 和 class  有順序關序麼,在標籤中==>突然的想法-->
                <input type="file" name="photo" id="photo"/><!--單結束符標籤麼-->
            </div>
            <!--執行結果-->
            <div class="col-md-6">
                <div class="col-md-12">
                    <textarea name="result" id="output" disabled class="form-control" rows="5"></textarea>
                </div>
                <br>
                <div class="col-md-12">
                    <p class="text-center h4">識別結果</p>
                </div>
            </div>       
        </div>
        <br>
        <!--下一行識別按鈕-->
        <div class="row">
            <div class="text-center">
                <button type="button" id="recognition" class="btn btn-primary">
                    識別
                </button>
            </div>
        </div>
    </div>

在style.css檔案中新增對應的樣式設計

/*新增分割線對應的樣式*/

div.hr{
    height: 3px;
    background:red;
}

div.hr hr{
    display: none;
}

影象上傳及時瀏覽功能(重點)

小技巧:關於script放的位置:頁面實現效果的指令碼放在body中,與使用者互動的指令碼放在body外。這樣好

<script>
    $(function(){//input中的photo提取到圖片資料;img中的photoIn返回資料;標籤的話就這2個
        $('#photo').on('change', function(){ //.om('change',function()不理解)
            var r = new FileReader(); //定義r變數,FileReader()是不是特殊的資料型別
            f = document.getElementById('photo').files[0]; //// 把圖片資料封裝到f變數中,'.files'是啥呢
            // r.readAsArrayBuffer(f);//readAsArrayBuffer作用是啥
            r.readAsDataURL(f);
            r.onload = function(e){ //這段函式不理解,這裡的e哪來的
                document.getElementById('photoIn').src = this.result;
            };
        });
    });
</script>

Ajax完成影象像後端的傳輸以及顯示從後端返回的結果(不懂)

<script>
    // 影象傳送至後臺伺服器進行識別
    $('#recognition').click(function(){
        formdata = new FormData(); // 定義formdata變數 Formdata是不是特殊的資料型別
        var file = $('#photo')[0].files[0]; // 把圖片資料用file變量表示
        formdata.append('image',file); // 把圖片資料封裝到formdata變數中
        $.ajax({
            url:'/ocr/', // 傳送地址是ocr url地址寫錯/ocr 導致Not Found: /ocr;地址後還要加/
            type:'POST', // 傳送方式是post
            data:formdata, //傳送的資料是formdata
            dataType:'json', // 資料型別是json
            processData:false, 
            contentType:false,
            success:ShowResult //收到結果後,執行ShowResult函式,將輸出文字的值改為識別到的文字資訊
        })

    })
    
</script>
<!--返回結果顯示-->
<script>
    function ShowResult(data){
        output.value = data['output'];
    }
</script>

後端開發
配置靜態資原始檔

將所有的靜態資原始檔按照資料夾路徑建立對應的檢視處理函式

以檔案讀取方式獲取檔案內容並通過HttpResponse返回

我並沒有用django模板建立檔案,這個只是我搭建罷了

呼叫django屬性,建立靜態資源路徑

def read_css(request,filename):
    with open('frontend/css/{}'.format(filename),'rb') as f:
        css_content = f.read()
        print('css檔案')
        return HttpResponse(content=css_content,content_type = 'text/css')

def read_js(request,filename):
    with open('frontend/js/{}'.format(filename),'rb') as f:
        js_content = f.read()
        print('js檔案')
        return HttpResponse(content=js_content,content_type = 'application/Jacascript')
def read_img(request,filename):
    with open('frontend/img/{}'.format(filename),'rb') as f:
        img_content = f.read()
        print('img檔案')
        return HttpResponse(content=img_content,content_type = 'image/jpeg')

配置靜態資源的訪問路由

  path('css/<str:filename>',read_css,name='read_css'),
    path('js/<str:filename>',read_js,name='read_js'),
    path('img/<str:filename>',read_img,name='read_img'),

重寫編寫views.py檔案中的home1函式

from django.http import HttpResponse

def home1(request):
#     return HttpResponse("hello world 8080!")
    with open('frontend/index.html','rb') as f:
        html = f.read()
        return HttpResponse(html)

安裝pytesseract過程
開發文字識別後端處理模組(一點都不懂)

import numpy as np # numpy不會有,至少要會用來影象分割
import urllib # 也不熟,很少用他做爬蟲
import json # json資料返回的包
import cv2 # 要學的,重點,但我不會
import pytesseract # 文字識別包
from PIL import Image # 影象處理的
import os
from django.views.decorators.csrf import csrf_exempt # 防止啥csrf_什麼的攻擊
from django.http import JsonResponse

def read_image(stream=None):
    data_temp = stream.read()
    image = np.asarray(bytearray(data_temp),dtype = 'uint8')
    image = cv2.imdecode(image,cv2.IMREAD_COLOR) # cv2處理不知
    return image

@csrf_exempt # 用於規避跨站點請求攻擊
def ocrDetect(request):
    result = {'code':None}
    if request.method == 'POST':
        img = read_image(stream = request.FILES["image"])
        # OpenCV轉PIL
        # frommarry寫錯他顯示白色,就代表他不是函式;fromarray才是
        # COLOR_BAYER_BG2BGR寫錯這是編輯器快速提示時沒看直接選的
        img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
        # 執行識別
        code = pytesseract.image_to_string(img,lang='chi_sim')
        result.update({"output":code}) # ()內加了引號,字典外加引號,這錯誤哎;這裡字典只要值加"",鍵不需要
    return JsonResponse(result)

最後在urls.py檔案中urlpatterns中新增對應的路由(這裡我也不明白)

  path('ocr/',ocrDetect,name='ocrDetect'),
努力拼搏吧,不要害怕,不要去規劃,不要迷茫。但你一定要在路上一直的走下去,儘管可能停滯不前,但也要走。