Read Japanese manga inside browser with selectable text.

Overview

mokuro

Read Japanese manga with selectable text inside a browser.

See demo: https://kha-white.github.io/manga-demo

mokuro_demo.mp4

Demo contains excerpt from Manga109-s dataset. うちの猫’ず日記 © がぁさん

mokuro is aimed towards Japanese learners, who want to read manga in Japanese with a pop-up dictionary like Yomichan. It works like this:

  1. Perform text detection and OCR for each page.
  2. After processing a whole volume, generate a HTML file, which you can open in a browser.
  3. All processing is done offline (before reading). You can transfer the resulting HTML file together with manga images to another device (e.g. your mobile phone) and read there.

mokuro uses comic-text-detector for text detection and manga-ocr for OCR.

Try running on your manga in Colab: Open In Colab

For a comprehensive guide on setting up a reading and mining workflow with manga-ocr/mokuro, check out Xelieu's guide.

Installation

You need Python 3.6, 3.7, 3.8 or 3.9. Unfortunately, PyTorch does not support Python 3.10 yet.

Some users have reported problems with Python installed from Microsoft Store. If you see an error: ImportError: DLL load failed while importing fugashi: The specified module could not be found., try installing Python from the official site.

If you want to run with GPU, install PyTorch as described here, otherwise this step can be skipped.

Run in command line:

pip3 install mokuro

Usage

Run on one volume

mokuro /path/to/manga/vol1

This will generate /path/to/manga/vol1.html file, which you can open in a browser.

Run on multiple volumes

mokuro /path/to/manga/vol1 /path/to/manga/vol2 /path/to/manga/vol3

For each volume, a separate HTML file will be generated.

Run on a directory containing multiple volumes

If your directory structure looks somewhat like this:

manga_title/
├─vol1/
├─vol2/
├─vol3/
└─vol4/

You can process all volumes by running:

mokuro --parent_dir manga_title/

Other options

--force_cpu - disable GPU
--as_one_file - generate separate css and js files instead of embedding everything in html
--disable_confirmation - run without asking for confirmation

Contact

For any inquiries, please feel free to contact me at [email protected]

Acknowledgments

Comments
  • Manga pages out of order without leading zeroes

    Manga pages out of order without leading zeroes

    Went to process a manga that had volumes with and without leading zeroes on the page, the ones without got completely out of order (going 1 10-19 100 and so on instead)

    Using a program to batch rename them fixed the issue, but I figured would be worth reporting if it's a fixable problem in the program itself

    opened by pedipanol 3
  • Add the option to toggle individual OCR text boxes on and off

    Add the option to toggle individual OCR text boxes on and off

    In reference to Issue #30.

    Add an option to toggle the OCR boxes with a click on them. When clicking on something else on the page it turns the OCR box off. This makes it easier to read on mobile devices with various pop-up dictionary applications.

    opened by trd-db 3
  • Blank HTML File

    Blank HTML File

    Hello, I recently followed Xelieu's guide on using Mokuro. I finished creating the HTML and OCR files for 18 volumes of Karakai Takagi-san but none of the HTML works. Done through google collab.

    opened by SebyKebby 3
  • Folders with spaces don't work

    Folders with spaces don't work

    When the folder is named with spaces like this image it thinks that every space is another directory image when in fact its only one folder when you run it like this it will give you instantly bunch of errors and not work image

    if i rename that same folder so that there are no spaces image image it works like it should image

    opened by OltiP2 3
  • Improved image sorting.

    Improved image sorting.

    Sorts images by folder then file name.

    Addresses issue #25.

    This was tested with files named as shown below.

    Sort before code change:

    • Chapter 1/0003.jpg
    • Chapter 20/0051.jpg
    • Chapter 69/13.jpg
    • Chapter 69/3.jpg
    • Chapter 9/0079.jpg

    Sort after code change:

    • Chapter 1/0003.jpg
    • Chapter 9/0079.jpg
    • Chapter 20/0051.jpg
    • Chapter 69/3.jpg
    • Chapter 69/13.jpg

    Disclaimer: I don't really know Python, so I figured things as out I went to try and address this issue.

    opened by ChristopherFritz 2
  • Fails if file extensions are uppercase (.JPG or .PNG)

    Fails if file extensions are uppercase (.JPG or .PNG)

    If the file extensions are uppercase (I've witnessed this a few times from downloaded manga) then the program will fail to find any of them.

    I can see there was a pull request (#11) for this, but it haven't been pushed to pip because it still fails with uppercase extensions.

    Installation with

    pip3 install mokuro
    
    opened by Tenpi 2
  • Issues converting certain types of speech bubbles

    Issues converting certain types of speech bubbles

    Thanks again for your hard work.

    I've encountered this issue a few times across 3 or so volumes of One Piece. When one bubble is above another, the text will get slightly jumbled, and the outputted text will alternate between the first box and second rather than showing each line of text in sequential order.

    Mokuro Issue before Mokuro issue after

    opened by wJosuke 2
  • Converted manga won't work with yomichan

    Converted manga won't work with yomichan

    image

    I converted this manga and tried to shift hover over multiple pages. Nothing came up but when I went to the other tab it worked with just random text on google.

    opened by KolbyML 2
  • ImportError: DLL load failed while importing fugashi: The specified module could not be found.

    ImportError: DLL load failed while importing fugashi: The specified module could not be found.

    C:\Users\Seven7>mokuro "C:\A\Summertime renderer v01"
    
    Paths to process:
    
    C:\A\Summertime renderer v01
    
    Each of the paths above will be treated as one volume. Continue? [yes/no]
    yes
    2022-05-05 13:18:13.152 | INFO     | mokuro.run:run:40 - Processing 1/1: C:\A\Summertime renderer v01
    Processing pages...:   0%|                                                                                                                                                                                          | 0/294 [00:00<?, ?it/s]2022-05-05 13:18:13.170 | INFO     | mokuro.manga_page_ocr:__init__:30 - Initializing text detector
    2022-05-05 13:18:13.614 | INFO     | manga_ocr.ocr:__init__:13 - Loading OCR model from kha-white/manga-ocr-base
    Processing pages...:   0%|                                                                                                                                                                                          | 0/294 [00:06<?, ?it/s]
    2022-05-05 13:18:19.524 | ERROR    | mokuro.run:run:44 - Error while processing C:\A\Summertime renderer v01
    Traceback (most recent call last):
    
      File "c:\program files\python39\lib\runpy.py", line 197, in _run_module_as_main
        return _run_code(code, main_globals, None,
               │         │     └ {'__name__': '__main__', '__doc__': None, '__package__': '', '__loader__': <zipimporter object "C:\Users\Seven7\AppData\...
               │         └ <code object <module> at 0x000002AF10CFFF50, file "C:\Users\Seven7\AppData\Roaming\Python\Python39\Scripts\mokuro.exe\__...
               └ <function _run_code at 0x000002AF104DECA0>
    
      File "c:\program files\python39\lib\runpy.py", line 87, in _run_code
        exec(code, run_globals)
             │     └ {'__name__': '__main__', '__doc__': None, '__package__': '', '__loader__': <zipimporter object "C:\Users\Seven7\AppData\...
             └ <code object <module> at 0x000002AF10CFFF50, file "C:\Users\Seven7\AppData\Roaming\Python\Python39\Scripts\mokuro.exe\__...
    
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\Scripts\mokuro.exe\__main__.py", line 7, in <module>
        sys.exit(main())
        │   │    └ <function main at 0x000002AF10CEC280>
        │   └ <built-in function exit>
        └ <module 'sys' (built-in)>
    
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\mokuro\__main__.py", line 7, in main
        fire.Fire(run)
        │    │    └ <function run at 0x000002AF36438CA0>
        │    └ <function Fire at 0x000002AF36438F70>
        └ <module 'fire' from 'C:\\Users\\Seven7\\AppData\\Roaming\\Python\\Python39\\site-packages\\fire\\__init__.py'>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\fire\core.py", line 141, in Fire
        component_trace = _Fire(component, args, parsed_flag_args, context, name)
                          │     │          │     │                 │        └ 'mokuro'
                          │     │          │     │                 └ {}
                          │     │          │     └ Namespace(verbose=False, interactive=False, separator='-', completion=None, help=False, trace=False)
                          │     │          └ ['C:\\A\\Summertime renderer v01']
                          │     └ <function run at 0x000002AF36438CA0>
                          └ <function _Fire at 0x000002AF364C0F70>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\fire\core.py", line 466, in _Fire
        component, remaining_args = _CallAndUpdateTrace(
        │                           └ <function _CallAndUpdateTrace at 0x000002AF364C20D0>
        └ <function run at 0x000002AF36438CA0>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\fire\core.py", line 681, in _CallAndUpdateTrace
        component = fn(*varargs, **kwargs)
                    │   │          └ {}
                    │   └ ['C:\\A\\Summertime renderer v01']
                    └ <function run at 0x000002AF36438CA0>
    > File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\mokuro\run.py", line 42, in run
        ovg.process_dir(path, as_one_file=as_one_file)
        │   │           │                 └ True
        │   │           └ WindowsPath('C:/A/Summertime renderer v01')
        │   └ <function OverlayGenerator.process_dir at 0x000002AF36438790>
        └ <mokuro.overlay_generator.OverlayGenerator object at 0x000002AF364AE490>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\mokuro\overlay_generator.py", line 82, in process_dir
        self.init_models()
        │    └ <function OverlayGenerator.init_models at 0x000002AF36438700>
        └ <mokuro.overlay_generator.OverlayGenerator object at 0x000002AF364AE490>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\mokuro\overlay_generator.py", line 55, in init_models
        self.mpocr = MangaPageOcr(self.pretrained_model_name_or_path, self.force_cpu, **self.kwargs)
        │    │       │            │    │                              │    │            │    └ {}
        │    │       │            │    │                              │    │            └ <mokuro.overlay_generator.OverlayGenerator object at 0x000002AF364AE490>
        │    │       │            │    │                              │    └ False
        │    │       │            │    │                              └ <mokuro.overlay_generator.OverlayGenerator object at 0x000002AF364AE490>
        │    │       │            │    └ 'kha-white/manga-ocr-base'
        │    │       │            └ <mokuro.overlay_generator.OverlayGenerator object at 0x000002AF364AE490>
        │    │       └ <class 'mokuro.manga_page_ocr.MangaPageOcr'>
        │    └ None
        └ <mokuro.overlay_generator.OverlayGenerator object at 0x000002AF364AE490>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\mokuro\manga_page_ocr.py", line 34, in __init__
        self.mocr = MangaOcr(pretrained_model_name_or_path, force_cpu)
        │           │        │                              └ False
        │           │        └ 'kha-white/manga-ocr-base'
        │           └ <class 'manga_ocr.ocr.MangaOcr'>
        └ <mokuro.manga_page_ocr.MangaPageOcr object at 0x000002AF36512BE0>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\manga_ocr\ocr.py", line 15, in __init__
        self.tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path)
        │                │             │               └ 'kha-white/manga-ocr-base'
        │                │             └ <classmethod object at 0x000002AF36322BB0>
        │                └ <class 'transformers.models.auto.tokenization_auto.AutoTokenizer'>
        └ <manga_ocr.ocr.MangaOcr object at 0x000002AF36512BB0>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\transformers\models\auto\tokenization_auto.py", line 528, in from_pretrained
        return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
               │               │               │                               │         └ {'_from_auto': True}
               │               │               │                               └ ()
               │               │               └ 'kha-white/manga-ocr-base'
               │               └ <classmethod object at 0x000002AF362883D0>
               └ <class 'transformers.models.bert_japanese.tokenization_bert_japanese.BertJapaneseTokenizer'>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\transformers\tokenization_utils_base.py", line 1780, in from_pretrained
        return cls._from_pretrained(
               │   └ <classmethod object at 0x000002AF36288490>
               └ <class 'transformers.models.bert_japanese.tokenization_bert_japanese.BertJapaneseTokenizer'>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\transformers\tokenization_utils_base.py", line 1915, in _from_pretrained
        tokenizer = cls(*init_inputs, **init_kwargs)
                    │    │              └ {'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]', 'do_lower_ca...
                    │    └ ()
                    └ <class 'transformers.models.bert_japanese.tokenization_bert_japanese.BertJapaneseTokenizer'>
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\transformers\models\bert_japanese\tokenization_bert_japanese.py", line 151, in __init__
        self.word_tokenizer = MecabTokenizer(
        │                     └ <class 'transformers.models.bert_japanese.tokenization_bert_japanese.MecabTokenizer'>
        └ PreTrainedTokenizer(name_or_path='kha-white/manga-ocr-base', vocab_size=6144, model_max_len=1000000000000000019884624838656, ...
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\transformers\models\bert_japanese\tokenization_bert_japanese.py", line 231, in __init__
        import fugashi
      File "C:\Users\Seven7\AppData\Roaming\Python\Python39\site-packages\fugashi\__init__.py", line 1, in <module>
        from .fugashi import *
    
    ImportError: DLL load failed while importing fugashi: The specified module could not be found.
    2022-05-05 13:18:19.552 | INFO     | mokuro.run:run:48 - Processed successfully: 0/1
    
    opened by YinnVI 2
  • numpy 1.24: AttributeError: module 'numpy' has no attribute 'int'

    numpy 1.24: AttributeError: module 'numpy' has no attribute 'int'

    I think there was a breaking change in numpy 1.24.

      File "/usr/local/lib/python3.10/dist-packages/comic_text_detector/utils/db_utils.py", line 200, in box_score_fast
        xmin = np.clip(np.floor(box[:, 0].min()).astype(np.int), 0, w - 1)
               │  │    │  │     │                       │           └ 1024
               │  │    │  │     │                       └ <module 'numpy' from '/usr/local/lib/python3.10/dist-packages/numpy/__init__.py'>
               │  │    │  │     └ array([[ 752,  999],
               │  │    │  │              [ 753,  999],
               │  │    │  │              [ 754, 1000],
               │  │    │  │              [ 755, 1000],
               │  │    │  │              [ 756, 1001],
               │  │    │  │              [ 755, 1000],...
               │  │    │  └ <ufunc 'floor'>
               │  │    └ <module 'numpy' from '/usr/local/lib/python3.10/dist-packages/numpy/__init__.py'>
               │  └ <function clip at 0x7fbe149ea8c0>
               └ <module 'numpy' from '/usr/local/lib/python3.10/dist-packages/numpy/__init__.py'>
      File "/usr/local/lib/python3.10/dist-packages/numpy/__init__.py", line 284, in __getattr__
        raise AttributeError("module {!r} has no attribute "
    
    AttributeError: module 'numpy' has no attribute 'int'
    

    Installing version 1.23.0 instead of 1.24.0 of numpy works instead.

    opened by elizagamedev 1
  • RuntimeError

    RuntimeError

    I am getting this error both on google colab and on PC.

    RuntimeError: Failed to import transformers.models.bert_japanese.tokenization_bert_japanese because of the following error (look up to see its traceback): No module named 'sentencepiece'

    opened by kyogirikon 1
  • Bug: Mokuro html files breaking due to unicode weirdness

    Bug: Mokuro html files breaking due to unicode weirdness

    How to reproduce

    1. Create a folder in google drive manga/. upload this Test folder. Test.zip
    2. Directory structure should look like this: manga > Test > [あずまきよひこ] よつばと! 第01巻 > some images.
    3. Run https://colab.research.google.com/github/kha-white/mokuro/blob/master/notebooks/mokuro_demo.ipynb, changing the last line of code to !mokuro --parent_dir "/content/drive/MyDrive/manga/Test"
    4. Download the entire Test folder.
    5. Open the mokuro generated html. Verify the manga images not loading. image

    Something weird is going on with Unicode parsing, particularly with the ず and ば characters. Both characters get transformed into another identical-looking but different character in the HTML file.

    opened by justremember 1
  • AttributeError: 'NoneType' object has no attribute 'shape'

    AttributeError: 'NoneType' object has no attribute 'shape'

    Getting an error while running mokuro. This is being thrown from line 38 in manga_page_ocr.py

    AttributeError: 'NoneType' object has no attribute 'shape' 2022-11-23 22:34:43.023 | INFO | mokuro.run:run:51 - Processed successfully: 0/1

    opened by hlawlovell 0
  • Failed to install package via pip

    Failed to install package via pip

    Hiya, I'm trying to run the project on python 3.9.13 and am getting the following error:

    error: subprocess-exited-with-error
    
      × python setup.py egg_info did not run successfully.
      │ exit code: 1
      ╰─> [8 lines of output]
          Traceback (most recent call last):
            File "<string>", line 2, in <module>
            File "<pip-setuptools-caller>", line 34, in <module>
            File "/private/var/folders/rz/d266t0dn1md992kgv7z8tp480000gn/T/pip-install-mxoysvv8/fugashi_621defc0e8774e36a8d22bd2f46c3d4a/setup.py", line 15, in <module>
              output, data_files = check_libmecab()
            File "/private/var/folders/rz/d266t0dn1md992kgv7z8tp480000gn/T/pip-install-mxoysvv8/fugashi_621defc0e8774e36a8d22bd2f46c3d4a/fugashi_util.py", line 58, in check_libmecab
              raise RuntimeError("Could not configure working env. Have you installed MeCab?")
          RuntimeError: Could not configure working env. Have you installed MeCab?
          [end of output]
    
    opened by fernandofleury 1
  • Mokuro html lags after a while of being open..

    Mokuro html lags after a while of being open..

    This is an issue I see more with manga with larger file sizes but it still happens on small files as well. The page just stops working when I try to hover over text, or even turn the page. I don't know why it happens, so I was wondering if there's anything I could do. Also, browser doesn't matter whether it be a fresh chrome account, one with extensions or even another browser like Vivaldi.

    opened by evkaw 0
  • Manga missing - Blank pages

    Manga missing - Blank pages

    Not sure what is happening now, but it was working before and now everything is just broken. The pages do not come up only the words but its more of trying to find them. Not sure what happened or why image

    opened by noxxid3 1
Owner
Maciej Budyś
Maciej Budyś
Table recognition inside douments using neural networks

TableTrainNet A simple project for training and testing table recognition in documents. This project was developed to make a neural network which reco

Giovanni Cavallin 93 Jul 24, 2022
computer vision, image processing and machine learning on the web browser or node.

Image processing and Machine learning labs   computer vision, image processing and machine learning on the web browser or node note Fast Fourier Trans

ryohei tanaka 487 Nov 11, 2022
Read-only mirror of https://gitlab.gnome.org/GNOME/ocrfeeder

================================= OCRFeeder - A Complete OCR Suite ================================= OCRFeeder is a complete Optical Character Recogn

GNOME Github Mirror 81 Dec 23, 2022
Deskew is a command line tool for deskewing scanned text documents. It uses Hough transform to detect "text lines" in the image. As an output, you get an image rotated so that the lines are horizontal.

Deskew by Marek Mauder https://galfar.vevb.net/deskew https://github.com/galfar/deskew v1.30 2019-06-07 Overview Deskew is a command line tool for des

Marek Mauder 127 Dec 3, 2022
An Implementation of the alogrithm in paper IncepText: A New Inception-Text Module with Deformable PSROI Pooling for Multi-Oriented Scene Text Detection

InceptText-Tensorflow An Implementation of the alogrithm in paper IncepText: A New Inception-Text Module with Deformable PSROI Pooling for Multi-Orien

GeorgeJoe 115 Dec 12, 2022
Code for the paper STN-OCR: A single Neural Network for Text Detection and Text Recognition

STN-OCR: A single Neural Network for Text Detection and Text Recognition This repository contains the code for the paper: STN-OCR: A single Neural Net

Christian Bartz 496 Jan 5, 2023
text detection mainly based on ctpn model in tensorflow, id card detect, connectionist text proposal network

text-detection-ctpn Scene text detection based on ctpn (connectionist text proposal network). It is implemented in tensorflow. The origin paper can be

Shaohui Ruan 3.3k Dec 30, 2022
keras复现场景文本检测网络CPTN: 《Detecting Text in Natural Image with Connectionist Text Proposal Network》;欢迎试用,关注,并反馈问题...

keras-ctpn [TOC] 说明 预测 训练 例子 4.1 ICDAR2015 4.1.1 带侧边细化 4.1.2 不带带侧边细化 4.1.3 做数据增广-水平翻转 4.2 ICDAR2017 4.3 其它数据集 toDoList 总结 说明 本工程是keras实现的CPTN: Detecti

mick.yi 107 Jan 9, 2023
Detecting Text in Natural Image with Connectionist Text Proposal Network (ECCV'16)

Detecting Text in Natural Image with Connectionist Text Proposal Network The codes are used for implementing CTPN for scene text detection, described

Tian Zhi 1.3k Dec 22, 2022
huoyijie 1.2k Dec 29, 2022
OCR system for Arabic language that converts images of typed text to machine-encoded text.

Arabic OCR OCR system for Arabic language that converts images of typed text to machine-encoded text. The system currently supports only letters (29 l

Hussein Youssef 144 Jan 5, 2023
OCR, Scene-Text-Understanding, Text Recognition

Scene-Text-Understanding Survey [2015-PAMI] Text Detection and Recognition in Imagery: A Survey paper [2014-Front.Comput.Sci] Scene Text Detection and

Alan Tang 354 Dec 12, 2022
Total Text Dataset. It consists of 1555 images with more than 3 different text orientations: Horizontal, Multi-Oriented, and Curved, one of a kind.

Total-Text-Dataset (Official site) Updated on April 29, 2020 (Detection leaderboard is updated - highlighted E2E methods. Thank you shine-lcy.) Update

Chee Seng Chan 671 Dec 27, 2022
Code related to "Have Your Text and Use It Too! End-to-End Neural Data-to-Text Generation with Semantic Fidelity" paper

DataTuner You have just found the DataTuner. This repository provides tools for fine-tuning language models for a task. See LICENSE.txt for license de

null 81 Jan 1, 2023
Handwritten Text Recognition (HTR) system implemented with TensorFlow (TF) and trained on the IAM off-line HTR dataset. This Neural Network (NN) model recognizes the text contained in the images of segmented words.

Handwritten-Text-Recognition Handwritten Text Recognition (HTR) system implemented with TensorFlow (TF) and trained on the IAM off-line HTR dataset. T

null 27 Jan 8, 2023
Code for generating synthetic text images as described in "Synthetic Data for Text Localisation in Natural Images", Ankush Gupta, Andrea Vedaldi, Andrew Zisserman, CVPR 2016.

SynthText Code for generating synthetic text images as described in "Synthetic Data for Text Localisation in Natural Images", Ankush Gupta, Andrea Ved

Ankush Gupta 1.8k Dec 28, 2022
This can be use to convert text in a file to handwritten text.

TextToHandwriting This can be used to convert text to handwriting. Clone this project or download the code. Run TextToImage.py give the filename of th

Ashutosh Mahapatra 2 Feb 6, 2022