SalmanML commited on
Commit
351c297
1 Parent(s): 094601a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +285 -37
app.py CHANGED
@@ -23,36 +23,124 @@
23
 
24
 
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  import easyocr
27
  import cv2
28
  import requests
29
  import re
30
  from PIL import Image
31
  import streamlit as st
32
- # import os
33
-
34
 
35
  # Load the EasyOCR reader
36
  reader = easyocr.Reader(['en'])
37
 
38
-
39
- # key=os.environ.getattribute("api_key")
40
- # print(key)
41
  API_URL = "https://api-inference.huggingface.co/models/flair/ner-english-large"
42
  headers = {"Authorization": st.secrets["api_key"]}
43
 
44
  ## Image uploading function ##
45
- def image_upload_and_ocr(reader):
46
- uploaded_file=st.file_uploader(label=':red[**please upload a busines card** :sunglasses:]',type=['jpeg','jpg','png','webp'])
47
  if uploaded_file is not None:
48
- image=Image.open(uploaded_file)
49
- image=image.resize((640,480))
50
- result2 = reader.readtext(image)
51
- # result2=result
 
52
  texts = [item[1] for item in result2]
53
- result=' '.join(texts)
54
- return result2,result
55
-
 
 
56
 
57
  def query(payload):
58
  response = requests.post(API_URL, headers=headers, json=payload)
@@ -70,42 +158,202 @@ def get_ner_from_transformer(output):
70
 
71
  named_entities[entity_type].append(entity_text)
72
 
73
- # for entity_type, entities in named_entities.items():
74
- # print(f"{entity_type}: {', '.join(entities)}")
75
- return entity_type,named_entities
76
-
77
-
78
 
79
-
80
- ### DRAWING DETECTION FUNCTION ###
81
- def drawing_detection(image):
82
  # Draw bounding boxes around the detected text regions
83
- for detection in image:
84
  # Extract the bounding box coordinates
85
  points = detection[0] # List of points defining the bounding box
86
  x1, y1 = int(points[0][0]), int(points[0][1]) # Top-left corner
87
  x2, y2 = int(points[2][0]), int(points[2][1]) # Bottom-right corner
88
 
89
  # Draw the bounding box
90
- cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
91
 
92
  # Add the detected text
93
  text = detection[1]
94
- cv2.putText(image, text, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
95
- st.image(image,caption='Detected text on the card ',width=710)
96
- return image
 
97
 
 
 
 
 
98
 
 
 
 
 
99
 
100
- st.title("_Business_ card data extractor using opencv and streamlit :sunglasses:")
101
- res2,res=image_upload_and_ocr(reader)
102
- darwing_image=drawing_detection(res2)
 
 
 
 
 
 
 
 
103
 
104
-
105
- output = query({
106
- "inputs": res,
107
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
- entity_type,named_entities= get_ner_from_transformer(output)
110
- st.write(entity_type)
111
- st.write(named_entities)
 
 
 
23
 
24
 
25
 
26
+ # import easyocr
27
+ # import cv2
28
+ # import requests
29
+ # import re
30
+ # from PIL import Image
31
+ # import streamlit as st
32
+ # # import os
33
+
34
+
35
+ # # Load the EasyOCR reader
36
+ # reader = easyocr.Reader(['en'])
37
+
38
+
39
+ # # key=os.environ.getattribute("api_key")
40
+ # # print(key)
41
+ # API_URL = "https://api-inference.huggingface.co/models/flair/ner-english-large"
42
+ # headers = {"Authorization": st.secrets["api_key"]}
43
+
44
+ # ## Image uploading function ##
45
+ # def image_upload_and_ocr(reader):
46
+ # uploaded_file=st.file_uploader(label=':red[**please upload a busines card** :sunglasses:]',type=['jpeg','jpg','png','webp'])
47
+ # if uploaded_file is not None:
48
+ # image=Image.open(uploaded_file)
49
+ # image=image.resize((640,480))
50
+ # result2 = reader.readtext(image)
51
+ # # result2=result
52
+ # texts = [item[1] for item in result2]
53
+ # result=' '.join(texts)
54
+ # return result2,result
55
+
56
+
57
+ # def query(payload):
58
+ # response = requests.post(API_URL, headers=headers, json=payload)
59
+ # return response.json()
60
+
61
+ # def get_ner_from_transformer(output):
62
+ # data = output
63
+ # named_entities = {}
64
+ # for entity in data:
65
+ # entity_type = entity['entity_group']
66
+ # entity_text = entity['word']
67
+
68
+ # if entity_type not in named_entities:
69
+ # named_entities[entity_type] = []
70
+
71
+ # named_entities[entity_type].append(entity_text)
72
+
73
+ # # for entity_type, entities in named_entities.items():
74
+ # # print(f"{entity_type}: {', '.join(entities)}")
75
+ # return entity_type,named_entities
76
+
77
+
78
+
79
+
80
+ # ### DRAWING DETECTION FUNCTION ###
81
+ # def drawing_detection(image):
82
+ # # Draw bounding boxes around the detected text regions
83
+ # for detection in image:
84
+ # # Extract the bounding box coordinates
85
+ # points = detection[0] # List of points defining the bounding box
86
+ # x1, y1 = int(points[0][0]), int(points[0][1]) # Top-left corner
87
+ # x2, y2 = int(points[2][0]), int(points[2][1]) # Bottom-right corner
88
+
89
+ # # Draw the bounding box
90
+ # cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
91
+
92
+ # # Add the detected text
93
+ # text = detection[1]
94
+ # cv2.putText(image, text, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
95
+ # st.image(image,caption='Detected text on the card ',width=710)
96
+ # return image
97
+
98
+
99
+
100
+ # st.title("_Business_ card data extractor using opencv and streamlit :sunglasses:")
101
+ # res2,res=image_upload_and_ocr(reader)
102
+ # darwing_image=drawing_detection(res2)
103
+
104
+
105
+ # output = query({
106
+ # "inputs": res,
107
+ # })
108
+
109
+ # entity_type,named_entities= get_ner_from_transformer(output)
110
+ # st.write(entity_type)
111
+ # st.write(named_entities)
112
+
113
+
114
+
115
+
116
  import easyocr
117
  import cv2
118
  import requests
119
  import re
120
  from PIL import Image
121
  import streamlit as st
122
+ import numpy as np
 
123
 
124
  # Load the EasyOCR reader
125
  reader = easyocr.Reader(['en'])
126
 
 
 
 
127
  API_URL = "https://api-inference.huggingface.co/models/flair/ner-english-large"
128
  headers = {"Authorization": st.secrets["api_key"]}
129
 
130
  ## Image uploading function ##
131
+ def image_upload_and_ocr(reader, uploaded_file):
 
132
  if uploaded_file is not None:
133
+ image = Image.open(uploaded_file)
134
+ image = image.resize((640, 480))
135
+
136
+ image_np = np.array(image) # Convert image to NumPy array
137
+ result2 = reader.readtext(image_np)
138
  texts = [item[1] for item in result2]
139
+ result = ' '.join(texts)
140
+
141
+ return result2, result, image
142
+ else:
143
+ return None, None, None
144
 
145
  def query(payload):
146
  response = requests.post(API_URL, headers=headers, json=payload)
 
158
 
159
  named_entities[entity_type].append(entity_text)
160
 
161
+ return entity_type, named_entities
 
 
 
 
162
 
163
+ def drawing_detection(res2, image):
164
+ cv2_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
 
165
  # Draw bounding boxes around the detected text regions
166
+ for detection in res2:
167
  # Extract the bounding box coordinates
168
  points = detection[0] # List of points defining the bounding box
169
  x1, y1 = int(points[0][0]), int(points[0][1]) # Top-left corner
170
  x2, y2 = int(points[2][0]), int(points[2][1]) # Bottom-right corner
171
 
172
  # Draw the bounding box
173
+ cv2.rectangle(cv2_image, (x1, y1), (x2, y2), (255, 0, 0), 1)
174
 
175
  # Add the detected text
176
  text = detection[1]
177
+ cv2.putText(cv2_image, text, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
178
+
179
+ st.image(cv2_image, caption='Detected text on the card', width=710)
180
+ return cv2_image
181
 
182
+ # Function to extract phone numbers from text using regular expression
183
+ def extract_phone_numbers(text):
184
+ # Regular expression pattern for detecting phone numbers
185
+ PHONE_PATTERN = r'(?:ph|phone|phno)?\s*(?:[+-]?\d\s*[\(\)]*){7,}'
186
 
187
+ # Find phone numbers using regular expression
188
+ phone_numbers = re.findall(PHONE_PATTERN, text, re.IGNORECASE)
189
+ # Return the extracted phone numbers
190
+ return phone_numbers or None
191
 
192
+ # Function to extract email addresses from text using regular expression
193
+ def extract_email(text):
194
+ emails = []
195
+ # Regular expression pattern for detecting email addresses with variations
196
+ reg = r'[a-z0-9_.-]+(?:\s*@\s*)[a-z]+(?:\s*\.?\s*[a-z]{2,3})\s*'
197
+ # Find email addresses using regular expression
198
+ res = re.findall(reg, text, re.IGNORECASE)
199
+ # Print the extracted email addresses
200
+ for email in res:
201
+ emails.append(email.strip())
202
+ return emails or None
203
 
204
+ # Function to extract designations from text using regular expression
205
+ def extract_designation(text):
206
+ designations = []
207
+ # Regular expression pattern for detecting designations
208
+ designation_regex = r'\b(?:CEO|CFO|CTO|COO|CMO|CIO|President|Vice\s?President|Director|Manager|Executive\s?Director|Assistant\s?Manager|Account\s?Manager|Sales\s?Manager|Marketing\s?Manager|Product\s?Manager|Project\s?Manager|HR\s?Manager|Human\s?Resources\s?Manager|Operations\s?Manager|Business\s?Development\s?Manager|Senior\s?Manager|General\s?Manager|Team\s?Lead|Consultant|Analyst|Engineer|Architect|Designer|Developer|Programmer|Coordinator|Specialist|Supervisor|Administrator|Assistant|Associate|Partner|Founder|Owner|Principal|Expert|Technician|Officer|Representative|Agent|Accountant|Auditor|Trainer|Coach|Educator|Professor|Instructor|Researcher|Scientist|Doctor|Nurse|Therapist|Pharmacist|Attorney|Lawyer|Legal\s?Counsel|Paralegal|Advocate|Solicitor|Notary|Financial\s?Advisor|Investment\s?Advisor|Wealth\s?Manager|Broker|Realtor|Mortgage\s?Broker|Insurance\s?Agent)\b'
209
+
210
+ # Find designations using regular expression
211
+ designations = re.findall(designation_regex, text, re.IGNORECASE)
212
+
213
+ return designations or None
214
+
215
+ # Function to extract website URLs from text using regular expression
216
+ def extract_websites(text):
217
+ websites_found=[]
218
+ pattern = r'(https?://)?(www\.)?(\w+)(\.\w+)+'
219
+ websites = re.findall(pattern, text)
220
+ return ["".join(website) for website in websites] or None
221
+
222
+ # Function to extract PIN codes from text using regular expression
223
+ def extract_pin_code(text):
224
+ pin_code_pattern = r'\b\d{6}\b'
225
+ pin_code_match = re.search(pin_code_pattern, text.lower())
226
+
227
+ # Retrieve the PIN code if found
228
+ if pin_code_match:
229
+ pin_code = pin_code_match.group()
230
+ return pin_code
231
+ else:
232
+ return None
233
+
234
+ import pandas as pd
235
+
236
+ # Streamlit UI
237
+ st.title("Business Card Data Extractor using OpenCV and Streamlit")
238
+
239
+ uploaded_file = st.file_uploader(label="Please upload a business card", type=['jpeg', 'jpg', 'png', 'webp'], accept_multiple_files=False)
240
+
241
+ if uploaded_file is not None:
242
+ res2, res, image = image_upload_and_ocr(reader, uploaded_file)
243
+
244
+ if res2 is not None:
245
+ drawing_image = drawing_detection(res2, image)
246
+
247
+ try:
248
+ output = query({
249
+ "inputs": res,
250
+ })
251
+
252
+ entity_type, named_entities = get_ner_from_transformer(output)
253
+ except Exception as e:
254
+ st.error("An error occurred while processing the business card. Please try again later.")
255
+ st.error(f"Error details: {str(e)}")
256
+
257
+ extracted_data = {}
258
+
259
+ # Function to extract person's name
260
+ # Assuming the person's name is extracted by NER
261
+ names = named_entities.get("PER", [])
262
+ if names:
263
+ selected_name = st.selectbox("Select Person's Name:", [""] + names)
264
+ if selected_name:
265
+ extracted_data["Name"] = selected_name
266
+ else:
267
+ manual_name = st.text_input("Enter Person's Name manually:")
268
+ if manual_name:
269
+ extracted_data["Name"] = manual_name
270
+
271
+ # Function to extract designations
272
+ designations = extract_designation(res)
273
+ if designations is not None:
274
+ selected_designation = st.selectbox("Select Designation:", [""] + designations)
275
+ if selected_designation:
276
+ extracted_data["Designation"] = selected_designation
277
+ else:
278
+ manual_designation = st.text_input("Enter Designation manually:")
279
+ if manual_designation:
280
+ extracted_data["Designation"] = manual_designation
281
+
282
+ # Function to extract company names
283
+ # Assuming the organization names extracted by NER represent company names
284
+ company_names = named_entities.get("ORG", [])
285
+ if company_names:
286
+ selected_company_name = st.selectbox("Select Company Name:", [""] + company_names)
287
+ if selected_company_name:
288
+ extracted_data["Company Name"] = selected_company_name
289
+ else:
290
+ manual_company_name = st.text_input("Enter Company Name manually:")
291
+ if manual_company_name:
292
+ extracted_data["Company Name"] = manual_company_name
293
+
294
+ # Function to extract email addresses
295
+ emails = extract_email(res)
296
+ if emails is not None:
297
+ selected_email = st.selectbox("Select Email:", [""] + emails)
298
+ if selected_email:
299
+ extracted_data["Email"] = selected_email
300
+ else:
301
+ manual_email = st.text_input("Enter Email manually:")
302
+ if manual_email:
303
+ extracted_data["Email"] = manual_email
304
+
305
+ # Function to extract website URLs
306
+ websites = extract_websites(res)
307
+ if websites is not None:
308
+ selected_website = st.selectbox("Select Website:", [""] + websites)
309
+ if selected_website:
310
+ extracted_data["Website"] = selected_website
311
+ else:
312
+ manual_website = st.text_input("Enter Website manually:")
313
+ if manual_website:
314
+ extracted_data["Website"] = manual_website
315
+
316
+ # Function to extract phone numbers
317
+ phone_numbers = extract_phone_numbers(res)
318
+ if phone_numbers is not None:
319
+ selected_phone_number = st.selectbox("Select Phone Number:", [""] + phone_numbers)
320
+ if selected_phone_number:
321
+ extracted_data["Phone Number"] = selected_phone_number
322
+ else:
323
+ manual_phone_number = st.text_input("Enter Phone Number manually:")
324
+ if manual_phone_number:
325
+ extracted_data["Phone Number"] = manual_phone_number
326
+
327
+ # Concatenate all the text returned by the API for location
328
+ locations = named_entities.get("LOC", [])
329
+ if locations:
330
+ concatenated_location = ", ".join(locations)
331
+ selected_location = st.selectbox("Select Location:", [""] + [concatenated_location])
332
+ if selected_location:
333
+ extracted_data["Location"] = selected_location
334
+ else:
335
+ manual_location = st.text_input("Enter Location manually:")
336
+ if manual_location:
337
+ extracted_data["Location"] = manual_location
338
+ else:
339
+ manual_location = st.text_input("Enter Location manually:")
340
+ if manual_location:
341
+ extracted_data["Location"] = manual_location
342
+
343
+
344
+ # Function to extract PIN codes
345
+ pin_code = extract_pin_code(res)
346
+ if pin_code is not None:
347
+ selected_pin_code = st.selectbox("Select PIN Code:", ["", pin_code])
348
+ if selected_pin_code:
349
+ extracted_data["PIN Code"] = selected_pin_code
350
+ else:
351
+ manual_pin_code = st.text_input("Enter PIN Code manually:")
352
+ if manual_pin_code:
353
+ extracted_data["PIN Code"] = manual_pin_code
354
 
355
+ # Display extracted data
356
+ if extracted_data:
357
+ st.write("Extracted Data:")
358
+ df = pd.DataFrame([extracted_data], columns=["Name", "Designation", "Company Name", "Email", "Website", "Phone Number", "Location", "PIN Code"])
359
+ st.write(df)