lukas-blecher / LaTeX-OCR

pix2tex: Using a ViT to convert images of equations into LaTeX code.
https://lukas-blecher.github.io/LaTeX-OCR/
MIT License
12.57k stars 1.03k forks source link

Could not find the Qt platform #318

Open eliemada opened 1 year ago

eliemada commented 1 year ago

Hi everyone, i tried doing this installation on M2 Mac, i installed python and pytorch but i have an issue with latexocr qt.qpa.plugin: Could not find the Qt platform plugin "cocoa" in "" This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. I am unsure how to fix this

baitian752 commented 1 year ago

Can you try my simple Web UI?

preview:

image

app.py

import os
from pathlib import Path

import httpx
from flask import Flask, jsonify, render_template, request

API_ENTRYPOINT = os.environ["API_ENTRYPOINT"]

app = Flask(__name__, template_folder=Path(__file__).parent)

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/img2tex", methods=["POST"])
def img2tex():
    response: dict[str, str] = {}
    with httpx.Client() as client:
        for name, file in request.files.items():
            response[name] = (
                client.post(
                    f"http://{API_ENTRYPOINT}/predict/",
                    files={"file": file},
                    timeout=60,
                )
                .content.decode("unicode_escape")
                .strip('"')
            )
    return jsonify(response)

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>LaTeX OCR</title>

    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/mdui@1.0.0/dist/css/mdui.min.css"
      integrity="sha384-2PJ2u4NYg6jCNNpv3i1hK9AoAqODy6CdiC+gYiL2DVx+ku5wzJMFNdE3RoWfBIRP"
      crossorigin="anonymous"
    />
    <script
      src="https://cdn.jsdelivr.net/npm/mdui@1.0.0/dist/js/mdui.min.js"
      integrity="sha384-aB8rnkAu/GBsQ1q6dwTySnlrrbhqDwrDnpVHR2Wgm8pWLbwUnzDcIROX3VvCbaK+"
      crossorigin="anonymous"
    ></script>

    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css"
      integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn"
      crossorigin="anonymous"
    />

    <!-- The loading of KaTeX is deferred to speed up page rendering -->
    <script
      defer
      src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js"
      integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx"
      crossorigin="anonymous"
    ></script>

    <!-- To automatically render math in text elements, include the auto-render extension: -->
    <script
      defer
      src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js"
      integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05"
      crossorigin="anonymous"
      onload="renderMathInElement(document.body);"
    ></script>

    <script
      src="https://code.jquery.com/jquery-3.7.1.slim.min.js"
      integrity="sha256-kmHvs0B+OpCW5GVHUNjv9rOmY0IvSIRcf7zGUDTDQM8="
      crossorigin="anonymous"
    ></script>

    <style>
      textarea {
        width: 100%;
        margin: 0;
        padding: 0;
        border-width: 0;
      }
    </style>
  </head>
  <body class="mdui-theme-layout-auto">
    <div class="mdui-container-fluid">
      <div class="mdui-row">
        <div class="mdui-col-sm-4">
          <img
            alt="Please paste your image on this page"
            id="input-image"
            width="100%"
          />
        </div>
        <div class="mdui-col-sm-4">
          <div class="mdui-textfield">
            <textarea
              id="tex"
              class="mdui-textfield-input"
              placeholder="\int_0^1f(x)=F(1)-F(0)"
              rows="10"
            ></textarea>
          </div>
        </div>
        <div class="mdui-col-sm-4" id="preview">$$\int_0^1f(x)=F(1)-F(0)$$</div>
      </div>
    </div>

    <script>
      $(function () {
        $(document.body).on("paste", function (ev) {
          // Get the data of clipboard
          const clipboardItems = ev.originalEvent.clipboardData.items;
          const items = [].slice.call(clipboardItems).filter(function (item) {
            // Filter the image items only
            return item.type.indexOf("image") !== -1;
          });
          if (items.length === 0) {
            return;
          }

          /** @type {DataTransferItem} */
          const item = items[0];
          // Get the blob of image
          const blob = item.getAsFile();
          const fileReader = new FileReader();
          fileReader.onload = function (e) {
            $("#input-image").attr("src", e.target.result);
          };
          fileReader.readAsDataURL(blob);

          const formData = new FormData();
          formData.append("file", blob);
          $("#tex").val("Waiting for LaTeX OCR...");
          fetch("/img2tex", {
            method: "POST",
            body: formData,
          }).then((response) => {
            response.json().then((data) => {
              $("#tex")
                .val(data.file)
                .get(0)
                .dispatchEvent(new Event("change"));
            });
          });
        });

        function onTexChange(ev) {
          /** @type {string} */
          const value = ev.target.value;
          $("#preview").text(`$$ ${value} $$`);
          renderMathInElement(document.getElementById("preview"));
        }

        $("#tex")
          .on("change", function (ev) {
            onTexChange(ev);
          })
          .on("keyup", function (ev) {
            onTexChange(ev);
          });
      });
    </script>
  </body>
</html>

requirements.txt

Flask
httpx

Dockerfile

FROM python:alpine

ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0

WORKDIR /work

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["flask", "run"]

docker-compose.yml

services:
  web:
    build: .
    ports:
      - host_ip: "127.0.0.1"
        target: 5000
        published: 8502
    volumes:
      - .:/work
    environment:
      API_ENTRYPOINT: 172.17.0.1:8502

  api:
    image: "lukasblecher/pix2tex:api"
    ports:
      - host_ip: "172.17.0.1"
        target: 8502
        published: 8502
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

run:

docker compose up -d

visit http://127.0.0.1:8502

Note: maybe you can remove the extra GPU request of the API container

eliemada commented 1 year ago

when i type docker compose up -d I get : `unknown shorthand flag: 'd' in -d See 'docker --help'.

Usage: docker [OPTIONS] COMMAND`

baitian752 commented 1 year ago

when i type docker compose up -d I get : `unknown shorthand flag: 'd' in -d See 'docker --help'.

Usage: docker [OPTIONS] COMMAND`

Without docker compose:

build:

docker build -t latex-ocr-web .

run api:

docker run -d --restart always -p 172.17.0.1:8502:8502 lukasblecher/pix2tex:api

run web:

docker run -d --restart always -p 127.0.0.1:8502:5000 -v `pwd`:/work -e API_ENTRYPOINT="172.17.0.1:8502" latex-ocr-web
eliemada commented 1 year ago

What do you call latex-ocr-web Here is my file architecture. I am a bit lost sorry

image
baitian752 commented 1 year ago

What do you call latex-ocr-web Here is my file architecture. I am a bit lost sorry image

latex-ocr-web is just the name of the built docker image. I noticed that the gateway of docker on Mac maybe not 172.17.0.1.

you can run api with:

docker run -d --restart always -p 127.0.0.1:8502:8502 lukasblecher/pix2tex:api

then run web on the host:

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
API_ENTRYPOINT="127.0.0.1:8502" flask run
eliemada commented 1 year ago

Sorry but i do not understand what to do. Would you mind resuming the command to type in the folder?

baitian752 commented 1 year ago

Sorry but i do not understand what to do. Would you mind resuming the command to type in the folder?

I noticed that this repo already has a frontend, you can run:

docker run --rm -it -p 8501:8501 --entrypoint python lukasblecher/pix2tex:api pix2tex/api/run.py

then visit http://127.0.0.1:8501