@frswataru (本石 渉)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

tesseract-ocr Multiple Rectanglesの方法を教えてください

Q&A

Closed

解決したいこと

tesseract-ocr Multiple Rectanglesの方法を教えてください
シングルでは上手くいきました

image.png

該当するソースコード

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" >
    <title>ECSS3.0</title>
    <link rel="stylesheet" href="css/stylesheet.css">
    <link href="css/slick.css" rel="stylesheet" type="text/css">
    <link href="css/slick-theme.css" rel="stylesheet" type="text/css">
<style>
    #container2 {
    overflow: hidden;
    }
    canvas {
    float: left;
    }
    #result-text {
    float: left;
    margin-left: 10px;
    }
</style>
</head>

<body>
    <script src="script.js"></script>
    <div class="header">
        <div class="header-logo"font-weight:bold;>E<span style="font-size:0.3em;font-weight:normal;">lectronic</span>
                                 C<span style="font-size:0.3em;font-weight:normal;">heck</span>
                                 S<span style="font-size:0.3em;font-weight:normal;">heet</span>
                                 S<span style="font-size:0.3em;font-weight:normal;">ystem</span>

        </div>

            <div id="container">
                <div class="circle icon">
                    <span class="bar top"></span>
                    <span class="bar middle"></span>
                    <span class="bar bottom"></span>
                </div>
            </div>

            <div id="containerLogo">
                    <a href="index.html"><img src="images/TCD_B.jpg"></a>   
            </div>




        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script>
            $("#container").click(function () {
                $(".icon").toggleClass("close");
            })
        </script>
    </div>

<!-- <div class="main"> -->
    <nav id="nav">
        <ul>
            <!-- <li><a href="#" onclick="window.close(); return false;">Close</a></li> -->
            <li><a href="index.html">Menu</a></li>
        </ul>

    </nav>

    <div id='container2'>
        <canvas width='500' height='400'></canvas>
        <div id='result-text'></div>
        </div>

        <script src='https://cdnjs.cloudflare.com/ajax/libs/tesseract.js/2.1.4/tesseract.min.js'></script>
            <script>
            // canvas(video)&text(result-text)宣言
            const canvas = document.querySelector('canvas');
            const context = canvas.getContext('2d');

            const image = document.createElement('video');

            const resultText = document.getElementById('result-text');
            let textBlocks = [];

            // videoのサイズ変更
            image.videoWidth = canvas.width;
            image.videoHeight = canvas.height;

            navigator.mediaDevices.getUserMedia({
            video: {
            facingMode: { ideal: 'environment' },
            }
            })
            .then(stream => {
            image.srcObject = stream;
            image.play();

            videoDisplay();

            setTimeout(analysis);
            });


            // 赤枠の発火条件_Textデータの個数が0以上
            const videoDisplay = () => {
            context.drawImage(image, 0, 0, canvas.width, canvas.height);
            context.strokeStyle = "rgb(255, 0, 0) ";
            context.lineWidth = 3;
            // Path描画(閉じたオブジェクト)_ED
            context.beginPath(100, 175);
            context.lineTo(300, 175);
            context.lineTo(300, 250);
            context.lineTo(100, 250);
            context.lineTo(100, 175);
            context.closePath();
            context.stroke(); 
            // Path描画(閉じたオブジェクト)_DS
            context.beginPath(305, 175);
            context.lineTo(390, 175);
            context.lineTo(390, 225);
            context.lineTo(305, 225);
            context.lineTo(305, 175);
            context.closePath();
            context.stroke(); 





            // 青枠の発火条件_Textデータの個数が1以上
            context.strokeStyle = "rgb(0, 0, 255) ";
            textBlocks.forEach((block) => {
            context.beginPath(block.bbox.x0, block.bbox.y0);
            context.lineTo(block.bbox.x1, block.bbox.y0);
            context.lineTo(block.bbox.x1, block.bbox.y1);
            context.lineTo(block.bbox.x0, block.bbox.y1);
            context.lineTo(block.bbox.x0, block.bbox.y0);
            context.closePath();
            context.stroke();
            });

            // textBlocks
            console.log(textBlocks) 

            requestAnimationFrame(videoDisplay);
            };

            // 発火条件
            // async, awaitは非同期処理が終わるまで先に進まずに待つ
            const analysis = () => {
                (async () => {
                    // 文字を解析するための前準備
                    const worker = Tesseract.createWorker();
                    await worker.load();
                    await worker.loadLanguage('eng');
                    await worker.initialize('eng');
                    // recognizeで画像から文字を検出する
                    // { data: { text, blocks } }は分割代入でググって
                    const { data: { text, blocks } } = await worker.recognize(canvas.toDataURL(), {
                    // videoDisplayで文字を認識した範囲を表示したいからグローバルな変数に代入
                        rectangle: {
                        left: 100, top: 175, width: 200, height: 75
                        },
                    });
                    // textBlocks = blocks;
                    // Tesseract.createWorkerで作ったworkerを終了させる
                    await worker.terminate();

                    // recognizeで検出した文字を改行コードで区切ってをHTML上に表示させる
                    // resultText.innerHTML = text.replace(/\r?\n/g, '<br>');
                    // 1.0秒後にanalysisメソッドを実行する
                    setTimeout(analysis, 1000);
                    input1.value = text
                })();
            };



            </script>


    <!-- <div class="main"> 

        <div class="contents">

            <div class="contents-item">
                <a href="ocr.html"><img src="images/Camera.png"></a>
                <p>Camera</p>
            </div>
            <div class="contents-item">
                <img src="images/Create.png">
                <p>Create</p>   
            </div>

        </div>      
    </div> -->

<!-- </div> -->

<div class="SDkEP">
    <div id="inputWrapper">
        <div class="inputTextBox" >
            <input id="input1" type="search" autocomplete="off"  aria-live="polite" placeholder="ED を入力">
        </div>      
        <div class="inputTextBox">          
            <input id="input" type="search" autocomplete="off" aria-live="polite" placeholder="DS を入力">           
        </div>          
    </div>
</div>


</body>
</html>


0 likes

1Answer

公式のサンプルをまねただけ

<html>
<head>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/tesseract.js/2.1.4/tesseract.min.js'></script>
    <style>
    div {
        display: inline-block;
        font-size: 32px;
        border: solid 1px black;
    }
    </style>
</head>
<body>
    <canvas></canvas><br>
    <div id="result1">解析中…</div><br>
    <div id="result2">解析中…</div>
<script>
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
const result1 = document.getElementById('result1');
const result2 = document.getElementById('result2');

const rectangles = [
    {
        left: 0,
        top: 0,
        width: 250,
        height: 125,
    },
    {
        left: 250,
        top: 0,
        width: 250,
        height: 125,
    },
];

const image = new Image();
image.crossOrigin = 'Anonymous';
image.src='https://tesseract.projectnaptha.com/img/eng_bw.png';

image.onload = () => {
    canvas.width = image.width / 2;
    canvas.height = image.height / 2;
    context.drawImage(image, 0, 0, canvas.width, canvas.height);
    context.strokeStyle = "rgb(255, 0, 0)";
    rectangles.forEach(rectange => {
        const x0 = rectange.left;
        const y0 = rectange.top;
        const x1 = x0 + rectange.width;
        const y1 = y0 + rectange.height;
        context.beginPath(x0, y0);
        context.lineTo(x1, y0);
        context.lineTo(x1, y1);
        context.lineTo(x0, y1);
        context.lineTo(x0, y0);
        context.closePath();
        context.stroke();
    });
    analysis();
};

const analysis = () => {
    // 参照
    // https://github.com/naptha/tesseract.js/blob/master/docs/examples.md#with-only-part-of-the-image-201
    // Multiple Rectangles (with scheduler to do recognition in parallel)

    const scheduler = Tesseract.createScheduler();
    const worker1 = Tesseract.createWorker();
    const worker2 = Tesseract.createWorker();

    (async () => {
        await worker1.load();
        await worker2.load();
        await worker1.loadLanguage('eng');
        await worker2.loadLanguage('eng');
        await worker1.initialize('eng');
        await worker2.initialize('eng');
        scheduler.addWorker(worker1);
        scheduler.addWorker(worker2);
        const results = await Promise.all(rectangles.map((rectangle) => (
            scheduler.addJob('recognize', canvas.toDataURL(), { rectangle })
        )));
        result1.innerHTML = results[0].data.text.replace(/\r?\n/g, '<br>');
        result2.innerHTML = results[1].data.text.replace(/\r?\n/g, '<br>');
        await scheduler.terminate();
    })();
};

</script>
</body>

</html>
1Like

Comments

  1. 質問するときはソースを見やすいように整形してください。
    インデントとかタグ、かっこの開始終了位置が正しくないです。
    ついでにscriptタグは基本的にheaderかbodyの最下部に書くのが一般的です。
  2. @frswataru

    Questioner

    なるほどそのような作法があるのですね
    知らなかったです
  3. @frswataru

    Questioner

    Multiple Rectangleギブです
    質問クローズして仕切り直します

Your answer might help someone💌