quran / ayah-detection

scripts to detect ayah markers from quran images
95 stars 41 forks source link

Quran Utilities

بسم الله الرحمن الرحيم

Quran utils is a set of scripts for detecting ayat in quran images. it's very rough, but it definitely works (tested on 3 sets of images - shamerly, qaloon, and warsh images).

Files

Setup

ideally, run something like this:

python3 -m venv virtualenv
source virtualenv/bin/activate
pip install -r requirements.txt

Suggested Workflow

# -u so it's unbuffered
python -u loop.py /path/ template.png | tee output.txt

Scripts

make_transparent.py

make_transparent.py takes in an image with a white background and attempts to make the background transparent. there are some tweakable parameters within the script, and it can theoretically be used with other background colors given the correct amount of tweaking.

make_white.py

make_white.py takes in a transparent image and makes all the transparent pixels white. this is helpful when images with white backgrounds are needed for better accuraccy while running ayat.py or lines.py.

ayat.py

ayat.py is responsible for detecting ayah images inside a page image. note that it works best on images with a white background (see make_white.py if your image has a transparent background).

requirements:

you also need a template image. you make one by cutting out an ayah marker image from one of your pages. the threshold is set low enough such that it will match all of the marker images despite the different numbers. some examples exist under images/templates.

lines.py

lines.py attempts to figure out where the lines are in a certain image. it does this by searching for white space between the images. consequently, it's the least accurate of the scripts. i typically verify it by running it across all images and making sure i get 15 lines for each page. run this on pages with white backgrounds for better results.

requirements:

there are 3 numbers you'll find configured in the main - line height (approximate height of each line), max pixels (a threshold - how many pixels in a line make the line a quran line vs a line of tashkeel between two lines), and mode (0 or 1 - i think this is used for how to handle the very first line - pass 0 for most cases).

main.py

main.py is what outputs sql from a set of images. before running it, you want to make sure you can run ayat.py and validate its output, along with lines.py and validate its output. main.py is just a wrapper that combines the results from the above scripts to generate sql, which it prints to the command line.

to run it: python main.py images/shamerly images/template/shamerly.png > shamerly.out

loop.py

loop.py is used in conjunction with things like find_errors.pl to do some basic validation. i was using it to figure out where each sura starts/ends, so i could then check that particular page and verify.

Quran Android

in order to be compatible with Quran Android, just generate a database file with similar structure to the existing ayahinfo database files.

    CREATE TABLE glyphs(
      glyph_id int primary key,
      page_number int not null,
      line_number int not null,
      sura_number int not null,
      ayah_number int not null,
      position int not null,
      min_x int not null,
      max_x int not null,
      min_y int not null,
      max_y int not null
    );
    CREATE INDEX sura_ayah_idx on glyphs(sura_number, ayah_number);
    CREATE INDEX page_idx on glyphs(page_number);

note: currently, glyph_id is set to NULL in the script, which is problematic. we can just put a number and increase it as need be, since using AUTOINCREMENT in sqlite has performance implications.

Experimental Scripts

marker_remover.py

marker_remover.py is an experimental script to remove markers. it uses the template marker as a "blueprint" by which it tries to remove existing markers. it figures out how amny pixels there are in each row of the template. it then tries to use that as an input to figure out how many pixels to remove from that particular row of the actual image. this is experimental and pretty dangerous, since it can eat pieces of touching ayahs, especially when things are really close together. really recommend using a tool like kaleidoscope to overlay the image without the ayahs on top of the ones with the ayahs and see that nothing extra is cut out, etc. configure its values at the top of the script.

header_remover.py

header_remover.py experimentally removes headers. it's safer than marker_remover.py and easier to validate, but still pretty experimental. configure its values in the top of the script.

find_ayat_v2.py

find_ayat_v2.py is a simpler version of ayat.py that uses OpenCV to find contours instead. consequently, this script doesn't need a template image. the downside of this approach, however, is that it can have many false positives since certain letters can still be detected as contours. this can greatly be reduced if the ayah markers have colors, which most do - simply checking for colors in a certain range greatly reduces (if not completely eliminates) these false positives. this is the recommended approach moving forward in sha' Allah. the old ayat.py will stay around since, in some cases, ayat.py works better than find_ayat_v2.py (also, ayat.py powers the header_remover.py script). whenever possible, use find_ayat_v2.py, but if it doesn't work well for the particular type of image, use ayat.py.

marker_remover_v2.py

marker_remover_v2.py is an updated version of marker_remover.py that uses find_ayat_v2.py to find and remove markers from pages. initial tests are very promising al7amdulillah. whenever v2 works, this is the recommended approach. fallback to v1 only when v2 doesn't work.