darknet-ocr web ui 优化


docker-compose.yml

version: '3.8'

services:
  webmvc:
    image: postor/darknet-ocr:1.0-image
    restart: unless-stopped
    ports:
      - "18080:8080"
    volumes:
      - ./clipboard.min.js:/root/darknet-ocr/static/js/clipboard.min.js
      - ./helps.js:/root/darknet-ocr/static/js/helps.js
      - ./text.html:/root/darknet-ocr/templates/text.html
      - ./base.html:/root/darknet-ocr/templates/base.html
    command: python app.py

base.html

$def with (page)  
<html lang="zh-cn">
    <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <title>darknet-ocr</title>
    
    </head>
<body>



 $:page

</body>
</html>

text.html

$def with(post)
<script type="text/javascript" src="static/js/jquery.js"></script>   
<script type="text/javascript" src="static/js/helps.js"></script> 
<script type="text/javascript" src="static/js/clipboard.min.js"></script> 
<link rel="stylesheet" href="static/css/main.css">

<script type="text/javascript">
    imgJson={"width":$post['width'],
        "height":$post['height'],
        "uuid":"$post['uuid']",
        'istext':true,//文字检测
            }

</script> 

<div>
$for bill in post['billList']:
    <div style="font-size:10px" class="billname" onclick="getValue('$bill',this)"><a href="#" class="button"><span >$bill</span>/ </a></div>
</div>
</br>
<div class="imgInput">

    <div class= "imgInput">
     <input type="text" id ="texturl" style="width:$post['textwidth']px;"  placeholder="图像URL地址">
     <button class="imagebutton" onclick="postBill('$post['url']')" >识别</button>
     <button class="pasteButton" onclick="pasteImg()">粘贴板</button>
    </div> 
    <div class= "imgInput" style="width:200px;">
    <label for="fileupload" >
        <input type="button" id="btn" value="上传本地图片">
        <input type="file"  id='imageButton' accept="image/png, image/bmp, image/jpg, image/jpeg">
    </div>    
    </label>                             
</div>
</br>
</br>

<div>
    <table class="aglin-line">
        <tr>
            <th>
                 <div class="imgshow" >
                 <div  style="background:#000;width:$post['width']px;height:10px;" ></div>
                  <div class="imgDisplay" style="position:relative;background:#000;width:$post['width']px;height:$post['height']px;" >
                    <img id='imgimg' width="$post['width']" height="$post['height']"  src="" style="top:0px; left:0px;position: absolute;z-index:1;"></img>
                    <canvas id="imgcanvas" width="$post['width']" height="$post['height']"   style="top:0px; left:0px;position: absolute;z-index:2;"></canvas>
                    <img id='loadingGif' width="$post['width']" height="$post['height']"  src="static/img/loading.gif" style="position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0.5);z-index:3;display:none"></img>

                  </div>
                  <div  style="background:#000;width:$post['width']px;height:10px;" ></div> 
                </div>
            </th>
        </tr>
    </table>

     <!#############################识别结果######################################################### ---->   
                <div style="position: absolute; right: 1%; top: 12%;" >
                    <div class="json">
                        <div class="json-request-title" id="billmodelname">$post.get('name')</div>
                            <div style="height:600px;width:660px; overflow:scroll;">
                                <div id="billNameList"></div>
                                <div id="mytable"></div>

                            </div>

                    </div>
                </div>
             </div>       
<!##############################识别结果######################################################### ---->

</div>
<script type="text/javascript">
            imgUploadPreview();//预览上传文件
            urlPreview();//预览url图片
</script> 

helps.js

function getValue(value,that){
    var divStyle = document.getElementsByClassName("billname");
    for(var i=0;i<divStyle.length;i++){
        divStyle[i].style.background = 'white';
    }
    that.style.background = 'pink';
    imgJson.billModel = value;
} 

function resizeImg(width,height){
    rate = height/imgJson.height;
    newW = width/rate;
    newH = height/rate;
    if(newW>imgJson.width){
        rate = width/imgJson.width;
        newW = width/rate;
        newH = height/rate;
    }
    return [newW,newH];

}


function imgUploadPreview() {
    //预览图像
    jQuery("#imageButton").change(function () {
        var obj=jQuery("#imageButton")[0].files[0];
        imgJson.filename = obj.name;
        var fr=new FileReader();
        fr.readAsDataURL(obj);
        fr.onload=function () {
            jQuery("#imgimg").attr('src',this.result);
            imgJson.imgString = this.result;
            imgJson.url = null;
            document.getElementById("texturl").value=""
            var image = new Image();
            image.onload=function(){
                var width = image.width;
                var height = image.height;
                imgJson.W = width;
                imgJson.H = height;
                var tmp = resizeImg(width,height);
                width=tmp[0];
                height=tmp[1];

                jQuery("#imgimg").attr('width',width);
                jQuery("#imgimg").attr('height',height);
                jQuery("#imgcanvas").attr('width',width);
                jQuery("#imgcanvas").attr('height',height);
                postBill('text');
            };
            image.src= this.result;

        };

    })
}

function pasteImg() {
    navigator.clipboard.read().then(function(items) {
        for (var i = 0; i < items.length; i++) {
            if (items[i].types.indexOf('image/png') != -1) {
                var blob = items[i].getType('image/png');
                blob.then(function(imageBlob) {
                    var fr = new FileReader();
                    fr.onload=function () {
                        jQuery("#imgimg").attr('src',this.result);
                        imgJson.imgString = this.result;
                        imgJson.url = null;
                        document.getElementById("texturl").value=""
                        var image = new Image();
                        image.onload=function(){
                            var width = image.width;
                            var height = image.height;
                            imgJson.W = width;
                            imgJson.H = height;
                            var tmp = resizeImg(width,height);
                            width=tmp[0];
                            height=tmp[1];

                            jQuery("#imgimg").attr('width',width);
                            jQuery("#imgimg").attr('height',height);
                            jQuery("#imgcanvas").attr('width',width);
                            jQuery("#imgcanvas").attr('height',height);
                            postBill('text');
                        };
                        image.src= this.result;
                    };
                    fr.readAsDataURL(imageBlob);
                });
            }
        }
    });
}


function urlPreview() {
    //预览图像
    jQuery("#texturl").change(function () {
        var url=jQuery("#texturl").val();
        imgJson.url = url;
        imgJson.imgString =null;
        imgJson.filename=null;
        jQuery("#imgimg").attr('src',url); 
        var image = new Image(); //创建一个image对象
        image.src=url;
        image.onerror = function(){
            alert(" 图片url错误");
        };

        image.onload = function(){
            var width = image.width;
            var height = image.height;
            imgJson.W = width;
            imgJson.H = height;
            var tmp = resizeImg(width,height);
            width=tmp[0];
            height=tmp[1];

            jQuery("#imgimg").attr('width',width);
            jQuery("#imgimg").attr('height',height);
            jQuery("#imgcanvas").attr('width',width);
            jQuery("#imgcanvas").attr('height',height);
        }

    })//jQuery("#"+avatarSlect)
}






function postBill(url){
    //识别请求
    if(imgJson.url || imgJson.imgString){

        loadingGif();

        jQuery.ajax({
            type: "post",
            url: url,
            data:JSON.stringify(imgJson),
            success:function(d){

                imgJson['num']=0;//防止重复提交
                imgJson["data"] = JSON.parse(d);//返回识别结果
                if(imgJson.data.data){
                    if(imgJson.data.data.length>0){
                        plotBox(imgJson.data.data);//绘制切图坐标
                    }
                      else if(imgJson.data.errCode==3){
                          alert("图像错误");
                      }

                }
                loadingGif(); 
                },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                // 状态码
                console.log(XMLHttpRequest.status);
                // 状态
                console.log(XMLHttpRequest.readyState);
                // 错误信息   
                console.log(textStatus);
                loadingGif(); 
                alert("识别异常!");

            }
        })}
            else{
                alert("上传图片或者URL,再提交!");
            }

}



function clearCan(){
    //清除myCanvas容器
    var canvas = document.getElementById('imgcanvas');
    canvas.width=canvas.width;
    canvas.height=canvas.height;
}


function createTable(result){
    //根据获取的数据,创建table
    jQuery("#mytable").empty();
    var jsObject = result;
    imgBoxes=[];
    //var jsObject = [{"name":10,"value":20},{"name":10,"value":20}];

    var tableString ="<table id='billmodeltable' class='gridtable'><tr><th>序号</th><th>值</th><th>文本检测置信度</th><th>OCR置信度</th></tr>"
    var textString = ""

    for(var i=0;i<jsObject.length;i++){
        var index = "<td>"+i+"</td>";
        var text     =  "<td><p contenteditable='true'>"+ jsObject[i]["text"]+"</p></td>";
        var textProb =  "<td>"+ jsObject[i]["textprob"]+ "</td>";
        var ocrProb  =  "<td>"+ jsObject[i]["prob"]+ "</td>" ;
        tableString += "<tr>"+index+text+textProb+ocrProb;
        textString += jsObject[i]["text"].replace(' ','')
        imgBoxes.push(jsObject[i]["box"]);
    }
    tableString+="</table>";
    
    textHtmlString = '<button class="copy-btn" data-clipboard-text="' + textString + '">Copy</button>'
    textHtmlString += "<p>" + textString + "</p>"
    
    jQuery("#mytable").append(textHtmlString);
    jQuery("#mytable").append(tableString);
    
    new ClipboardJS('.copy-btn');
    jQuery("#imageButton").val('');
}


function plotBox(boxes){
    /*根据box 绘制box
            W,H:原始图像尺寸
            */
    var W = imgJson['W'];
    var H = imgJson['H'];
    var canvas = document.getElementById('imgcanvas');
    canvas.width=canvas.width;
    canvas.height=canvas.height;
    if(canvas.getContext){
        //获取对应的CanvasRenderingContext2D对象(画笔)
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        //设置线条颜色为蓝色
        ctx.strokeStyle = "blue";
        for(var i=0;i<boxes.length;i++){
            var x1 = parseInt(boxes[i]['box'][0])/W*(parseInt(canvas.width));
            var y1 = parseInt(boxes[i]['box'][1])/H*(parseInt(canvas.height));
            var x2 = parseInt(boxes[i]['box'][2])/W*(parseInt(canvas.width));
            var y2 = parseInt(boxes[i]['box'][3])/H*(parseInt(canvas.height));
            var x3 = parseInt(boxes[i]['box'][4])/W*(parseInt(canvas.width));
            var y3 = parseInt(boxes[i]['box'][5])/H*(parseInt(canvas.height));
            var x4 = parseInt(boxes[i]['box'][6])/W*(parseInt(canvas.width));
            var y4 = parseInt(boxes[i]['box'][7])/H*(parseInt(canvas.height));
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.moveTo(x2, y2);
            ctx.lineTo(x3, y3);
            ctx.moveTo(x3, y3);
            ctx.lineTo(x4, y4);
            ctx.moveTo(x4, y4);
            ctx.lineTo(x1, y1);
            //ctx.fillText('prob:'+boxes[i]['prob']+' text:'+i, x1-5, y1-5);
        }
        ctx.stroke();
        ctx.closePath();

    } 
    createTable(boxes);

}



function loadingGif(){
    //加载请求时旋转动态图片
    var imgId=document.getElementById('loadingGif');
    if(imgId.style.display=="block")
    {imgId.style.display="none";}
        else
        {imgId.style.display="block";}

}

clipboard.min.js

/*!
 * clipboard.js v2.0.8
 * https://clipboardjs.com/
 *
 * Licensed MIT © Zeno Rocha
 */
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={134:function(t,e,n){"use strict";n.d(e,{default:function(){return r}});var e=n(279),i=n.n(e),e=n(370),a=n.n(e),e=n(817),o=n.n(e);function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function u(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}var l=function(){function e(t){!function(t){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this),this.resolveOptions(t),this.initSelection()}var t,n,r;return t=e,(n=[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"createFakeElement",value:function(){var t="rtl"===document.documentElement.getAttribute("dir");this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";t=window.pageYOffset||document.documentElement.scrollTop;return this.fakeElem.style.top="".concat(t,"px"),this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.fakeElem}},{key:"selectFake",value:function(){var t=this,e=this.createFakeElement();this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.container.appendChild(e),this.selectedText=o()(e),this.copyText(),this.removeFake()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=o()(this.target),this.copyText()}},{key:"copyText",value:function(){var e;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),document.activeElement.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==c(t)||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}])&&u(t.prototype,n),r&&u(t,r),e}();function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function f(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function h(t,e){return(h=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function d(n){var r=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}();return function(){var t,e=p(n);return t=r?(t=p(this).constructor,Reflect.construct(e,arguments,t)):e.apply(this,arguments),e=this,!(t=t)||"object"!==s(t)&&"function"!=typeof t?function(t){if(void 0!==t)return t;throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}(e):t}}function p(t){return(p=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function y(t,e){t="data-clipboard-".concat(t);if(e.hasAttribute(t))return e.getAttribute(t)}var r=function(){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&h(t,e)}(o,i());var t,e,n,r=d(o);function o(t,e){var n;return function(t){if(!(t instanceof o))throw new TypeError("Cannot call a class as a function")}(this),(n=r.call(this)).resolveOptions(e),n.listenClick(t),n}return t=o,n=[{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof t?[t]:t,e=!!document.queryCommandSupported;return t.forEach(function(t){e=e&&!!document.queryCommandSupported(t)}),e}}],(e=[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===s(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=a()(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){t=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(t){return y("action",t)}},{key:"defaultTarget",value:function(t){t=y("target",t);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(t){return y("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}])&&f(t.prototype,e),n&&f(t,n),o}()},828:function(t){var e;"undefined"==typeof Element||Element.prototype.matches||((e=Element.prototype).matches=e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector),t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}},438:function(t,e,n){var a=n(828);function i(t,e,n,r,o){var i=function(e,n,t,r){return function(t){t.delegateTarget=a(t.target,n),t.delegateTarget&&r.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,o),{destroy:function(){t.removeEventListener(n,i,o)}}}t.exports=function(t,e,n,r,o){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,r,o)}))}},879:function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},370:function(t,e,n){var l=n(879),s=n(438);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!l.string(e))throw new TypeError("Second argument must be a String");if(!l.fn(n))throw new TypeError("Third argument must be a Function");if(l.node(t))return c=e,u=n,(a=t).addEventListener(c,u),{destroy:function(){a.removeEventListener(c,u)}};if(l.nodeList(t))return r=t,o=e,i=n,Array.prototype.forEach.call(r,function(t){t.addEventListener(o,i)}),{destroy:function(){Array.prototype.forEach.call(r,function(t){t.removeEventListener(o,i)})}};if(l.string(t))return t=t,e=e,n=n,s(document.body,t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var r,o,i,a,c,u}},817:function(t){t.exports=function(t){var e,n="SELECT"===t.nodeName?(t.focus(),t.value):"INPUT"===t.nodeName||"TEXTAREA"===t.nodeName?((e=t.hasAttribute("readonly"))||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),e||t.removeAttribute("readonly"),t.value):(t.hasAttribute("contenteditable")&&t.focus(),n=window.getSelection(),(e=document.createRange()).selectNodeContents(t),n.removeAllRanges(),n.addRange(e),n.toString());return n}},279:function(t){function e(){}e.prototype={on:function(t,e,n){var r=this.e||(this.e={});return(r[t]||(r[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var r=this;function o(){r.off(t,o),e.apply(n,arguments)}return o._=e,this.on(t,o,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),r=0,o=n.length;r<o;r++)n[r].fn.apply(n[r].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),r=n[t],o=[];if(r&&e)for(var i=0,a=r.length;i<a;i++)r[i].fn!==e&&r[i].fn._!==e&&o.push(r[i]);return o.length?n[t]=o:delete n[t],this}},t.exports=e,t.exports.TinyEmitter=e}},o={},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,{a:e}),e},r.d=function(t,e){for(var n in e)r.o(e,n)&&!r.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r(134).default;function r(t){if(o[t])return o[t].exports;var e=o[t]={exports:{}};return n[t](e,e.exports,r),e.exports}var n,o});

文章作者: 钱不寒
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 钱不寒 !
  目录