Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import PIL
|
3 |
+
from PIL import Image
|
4 |
+
from PIL import ImageDraw
|
5 |
+
import gradio as gr
|
6 |
+
import torch
|
7 |
+
import easyocr
|
8 |
+
import re
|
9 |
+
|
10 |
+
# Download example images (same as before)
|
11 |
+
# Download example images
|
12 |
+
torch.hub.download_url_to_file('https://github.com/JaidedAI/EasyOCR/raw/master/examples/english.png', 'english.png')
|
13 |
+
torch.hub.download_url_to_file('https://i.imgur.com/mwQFd7G.jpeg', 'Hindi.jpeg')
|
14 |
+
torch.hub.download_url_to_file('https://github.com/JaidedAI/EasyOCR/raw/master/examples/thai.jpg', 'thai.jpg')
|
15 |
+
torch.hub.download_url_to_file('https://github.com/JaidedAI/EasyOCR/raw/master/examples/french.jpg', 'french.jpg')
|
16 |
+
torch.hub.download_url_to_file('https://github.com/JaidedAI/EasyOCR/raw/master/examples/chinese.jpg', 'chinese.jpg')
|
17 |
+
torch.hub.download_url_to_file('https://github.com/JaidedAI/EasyOCR/raw/master/examples/japanese.jpg', 'japanese.jpg')
|
18 |
+
torch.hub.download_url_to_file('https://github.com/JaidedAI/EasyOCR/raw/master/examples/korean.png', 'korean.png')
|
19 |
+
|
20 |
+
def draw_boxes(image, bounds, color='yellow', width=2):
|
21 |
+
draw = ImageDraw.Draw(image)
|
22 |
+
for bound in bounds:
|
23 |
+
p0, p1, p2, p3 = bound[0]
|
24 |
+
draw.line([*p0, *p1, *p2, *p3, *p0], fill=color, width=width)
|
25 |
+
return image
|
26 |
+
|
27 |
+
def format_extracted_text(bounds):
|
28 |
+
return " ".join([text for _, text, _ in bounds])
|
29 |
+
|
30 |
+
def highlight_search_results(text, search_query):
|
31 |
+
if not search_query:
|
32 |
+
return text, []
|
33 |
+
pattern = re.compile(re.escape(search_query), re.IGNORECASE)
|
34 |
+
matches = list(pattern.finditer(text))
|
35 |
+
highlighted_text = pattern.sub(lambda m: f"**{m.group()}**", text)
|
36 |
+
return highlighted_text, matches
|
37 |
+
|
38 |
+
def inference(img, lang):
|
39 |
+
reader = easyocr.Reader(lang)
|
40 |
+
bounds = reader.readtext(img)
|
41 |
+
im = PIL.Image.open(img)
|
42 |
+
draw_boxes(im, bounds)
|
43 |
+
im.save('result.jpg')
|
44 |
+
|
45 |
+
extracted_text = format_extracted_text(bounds)
|
46 |
+
|
47 |
+
return ['result.jpg', extracted_text]
|
48 |
+
|
49 |
+
def search_text(text, search_query):
|
50 |
+
highlighted_text, matches = highlight_search_results(text, search_query)
|
51 |
+
|
52 |
+
if matches:
|
53 |
+
result = f"Found {len(matches)} occurrence(s) of \"{search_query}\":\n"
|
54 |
+
for i, match in enumerate(matches, 1):
|
55 |
+
context_start = max(0, match.start() - 20)
|
56 |
+
context_end = min(len(text), match.end() + 20)
|
57 |
+
context = text[context_start:context_end]
|
58 |
+
result += f"{i}. ...{context}...\n"
|
59 |
+
else:
|
60 |
+
result = f"No occurrences of \"{search_query}\" found."
|
61 |
+
|
62 |
+
return highlighted_text, result
|
63 |
+
|
64 |
+
title = 'Image To Text OCR Converter'
|
65 |
+
subtitle = 'Extract Hindi/English or both or any Text From Image'
|
66 |
+
|
67 |
+
note = """
|
68 |
+
*Note: This application is being built on the request of IIT R Internship Assignment. It allows users to upload a single image, processes the image to extract text using OCR, and provides a basic search feature.*
|
69 |
+
*Please keep patience while processing the OCR, as it may take a few seconds to complete.*
|
70 |
+
"""
|
71 |
+
|
72 |
+
alternative_link = "[Alternative: Ready-to-use OCR using Vercel](https://iitr-haq-nawaz-maliks-projects.vercel.app/)"
|
73 |
+
|
74 |
+
examples = [
|
75 |
+
['english.png', ['en', 'hi']],
|
76 |
+
['Hindi.jpeg', ['hi', 'en']],
|
77 |
+
['thai.jpg', ['th', 'en', 'hi']],
|
78 |
+
['french.jpg', ['fr', 'en', 'hi']],
|
79 |
+
['chinese.jpg', ['ch_sim', 'en', 'hi']],
|
80 |
+
['japanese.jpg', ['ja', 'en', 'hi']],
|
81 |
+
['korean.png', ['ko', 'en', 'hi']]
|
82 |
+
]
|
83 |
+
|
84 |
+
css = """
|
85 |
+
.output_image, .input_image {height: 40rem !important; width: 100% !important;}
|
86 |
+
.search_results {margin-top: 1rem; padding: 1rem; background-color: #f0f0f0; border-radius: 4px;}
|
87 |
+
.centered-title {text-align: center; font-size: 2.5em; font-weight: bold; margin-bottom: 0.5em;}
|
88 |
+
.centered-subtitle {text-align: center; font-size: 1.5em; margin-bottom: 1em;}
|
89 |
+
.alternative-link {text-align: center; margin-top: 1em; font-style: italic;}
|
90 |
+
"""
|
91 |
+
|
92 |
+
|
93 |
+
choices = [
|
94 |
+
"abq", "ady", "af", "ang", "ar", "as", "ava", "az", "be", "bg", "bh", "bho", "bn", "bs", "ch_sim", "ch_tra",
|
95 |
+
"che", "cs", "cy", "da", "dar", "de", "en", "es", "et", "fa", "fr", "ga", "gom", "hi", "hr", "hu", "id",
|
96 |
+
"inh", "is", "it", "ja", "kbd", "kn", "ko", "ku", "la", "lbe", "lez", "lt", "lv", "mah", "mai", "mi", "mn",
|
97 |
+
"mr", "ms", "mt", "ne", "new", "nl", "no", "oc", "pi", "pl", "pt", "ro", "ru", "rs_cyrillic", "rs_latin",
|
98 |
+
"sck", "sk", "sl", "sq", "sv", "sw", "ta", "tab", "te", "th", "tjk", "tl", "tr", "ug", "uk", "ur", "uz", "vi"
|
99 |
+
]
|
100 |
+
|
101 |
+
with gr.Blocks(css=css) as iface:
|
102 |
+
gr.Markdown(f"# {title}")
|
103 |
+
gr.Markdown(f"## {subtitle}")
|
104 |
+
gr.Markdown(description)
|
105 |
+
gr.Markdown(note)
|
106 |
+
|
107 |
+
with gr.Row():
|
108 |
+
with gr.Column(scale=2):
|
109 |
+
input_image = gr.Image(type="filepath", label="Upload Image")
|
110 |
+
lang_select = gr.CheckboxGroup(choices=choices, label="Select Languages", value=['hi', 'en'])
|
111 |
+
ocr_button = gr.Button("Perform OCR")
|
112 |
+
|
113 |
+
with gr.Column(scale=3):
|
114 |
+
output_image = gr.Image(type="filepath", label="OCR Result")
|
115 |
+
extracted_text = gr.Markdown(label="Extracted Text")
|
116 |
+
search_box = gr.Textbox(label="Search in extracted text")
|
117 |
+
search_button = gr.Button("Search")
|
118 |
+
search_results = gr.Markdown(label="Search Results")
|
119 |
+
|
120 |
+
ocr_button.click(inference, inputs=[input_image, lang_select], outputs=[output_image, extracted_text])
|
121 |
+
search_button.click(search_text, inputs=[extracted_text, search_box], outputs=[extracted_text, search_results])
|
122 |
+
|
123 |
+
gr.Examples(examples, inputs=[input_image, lang_select])
|
124 |
+
gr.Markdown(article)
|
125 |
+
|
126 |
+
iface.launch()
|