pawandev commited on
Commit
6368900
·
1 Parent(s): 37c2aa4

Added PanOCR refined code to do Pan Card ocr

Browse files
.gitignore CHANGED
@@ -1,2 +1,4 @@
1
  env
2
- .env
 
 
 
1
  env
2
+ .env
3
+ *.pyc
4
+ *.DS_Store
app/__init__.py CHANGED
@@ -10,7 +10,7 @@ def create_app():
10
  # Load model once
11
  app.models = {
12
  'adhaarModel': YOLO('models/aadhaarYolov8.pt'),
13
- 'panModel': YOLO('models/PanYolov8.pt') # Load additional models as needed
14
  }
15
 
16
  return app
 
10
  # Load model once
11
  app.models = {
12
  'adhaarModel': YOLO('models/aadhaarYolov8.pt'),
13
+ 'panModel': YOLO('models/PanModal_v3.pt') # Load additional models as needed
14
  }
15
 
16
  return app
app/routes/panApi.py CHANGED
@@ -55,7 +55,9 @@ def ocrPan(mode, session):
55
  # Run detection
56
  model = current_app.models.get('panModel')
57
  results = model.predict(source=img, save=False)
 
58
  extracted_data = process_results(results, img)
 
59
 
60
  if extracted_data.get('statusCode') == 400:
61
  return jsonify(extracted_data), 400
@@ -67,4 +69,4 @@ def ocrPan(mode, session):
67
  return jsonify({"error": "Unable to identify image format."}), 400
68
  except Exception as e:
69
  current_app.logger.error(f"Unexpected error: {str(e)}")
70
- return jsonify({"error": "An unexpected error occurred."}), 500
 
55
  # Run detection
56
  model = current_app.models.get('panModel')
57
  results = model.predict(source=img, save=False)
58
+ # print(results,"model result")
59
  extracted_data = process_results(results, img)
60
+ # print(extracted_data, "extracted data")
61
 
62
  if extracted_data.get('statusCode') == 400:
63
  return jsonify(extracted_data), 400
 
69
  return jsonify({"error": "Unable to identify image format."}), 400
70
  except Exception as e:
71
  current_app.logger.error(f"Unexpected error: {str(e)}")
72
+ return jsonify({"error": "An unexpected error occurred on api call."}), 500
app/services/panServices/panDataExtractor.py CHANGED
@@ -1,7 +1,8 @@
1
  import re
2
 
3
  def extract_panData(data):
4
- unwanted_words = ["Name","/Name", "Date of Birth", "/Date of Birth", "Permanent Account Number", "Father's Name", "14 /Name", "/Father's Name"]
 
5
 
6
  # Clean the array by removing unwanted words and invalid entries
7
  cleaned_data = []
@@ -24,30 +25,30 @@ def extract_panData(data):
24
  }
25
 
26
  # Check and extract PAN number
27
- print(cleaned_data)
28
  pan_pattern = re.compile(r'^[A-Z]{5}[0-9]{4}[A-Z]$')
29
- if len(cleaned_data) > 0 and pan_pattern.match(cleaned_data[3]):
30
- result["data"]["panNo"] = cleaned_data[3]
31
  else:
32
  result["data"]["panNo"] = ''
33
 
34
  # Check and extract name
35
  name_pattern = re.compile(r'^[A-Za-z .]+$')
36
- if len(cleaned_data) > 1 and name_pattern.match(cleaned_data[2]):
37
- result["data"]["name"] = cleaned_data[2]
38
  else:
39
  result["data"]["name"] = ''
40
 
41
  # Check and extract father's name
42
- if len(cleaned_data) > 2 and name_pattern.match(cleaned_data[1]):
43
- result["data"]["fatherName"] = cleaned_data[1]
44
  else:
45
  result["data"]["fatherName"] = ''
46
 
47
  # Check and extract date of birth
48
  dob_pattern = re.compile(r'^\d{2}[-/]\d{2}[-/]\d{4}$')
49
- if len(cleaned_data) > 3 and dob_pattern.match(cleaned_data[0]):
50
- result["data"]["dob"] = cleaned_data[0]
51
  else:
52
  result["data"]["dob"] = ''
53
 
 
1
  import re
2
 
3
  def extract_panData(data):
4
+ unwanted_words = ["Name","/Name",'Permanent', 'Account', 'Number', 'Card', 'नाम', '/Name',
5
+ "पिता का नाम",'नाम / Name', "पिता का नाम/ Father's Name", 'नाम /Name',"पिता का नाम / Father's Name", 'जन्म का वाराज़', 'Date of Birth', 'Permanent Account Number Card', "Date of Birth", "/Date of Birth", "Permanent Account Number", "Father's Name", "14 /Name", "/Father's Name"]
6
 
7
  # Clean the array by removing unwanted words and invalid entries
8
  cleaned_data = []
 
25
  }
26
 
27
  # Check and extract PAN number
28
+ print(cleaned_data, "cleaned data")
29
  pan_pattern = re.compile(r'^[A-Z]{5}[0-9]{4}[A-Z]$')
30
+ if len(cleaned_data) > 0 and pan_pattern.match(cleaned_data[0]):
31
+ result["data"]["panNo"] = cleaned_data[0]
32
  else:
33
  result["data"]["panNo"] = ''
34
 
35
  # Check and extract name
36
  name_pattern = re.compile(r'^[A-Za-z .]+$')
37
+ if len(cleaned_data) > 1 and name_pattern.match(cleaned_data[1]):
38
+ result["data"]["name"] = cleaned_data[1]
39
  else:
40
  result["data"]["name"] = ''
41
 
42
  # Check and extract father's name
43
+ if len(cleaned_data) > 2 and name_pattern.match(cleaned_data[2]):
44
+ result["data"]["fatherName"] = cleaned_data[2]
45
  else:
46
  result["data"]["fatherName"] = ''
47
 
48
  # Check and extract date of birth
49
  dob_pattern = re.compile(r'^\d{2}[-/]\d{2}[-/]\d{4}$')
50
+ if len(cleaned_data) > 3 and dob_pattern.match(cleaned_data[3]):
51
+ result["data"]["dob"] = cleaned_data[3]
52
  else:
53
  result["data"]["dob"] = ''
54
 
app/services/panServices/panOcr.py CHANGED
@@ -2,41 +2,55 @@ from io import BytesIO
2
  from ...utils.azureOCR import analyze_image
3
  from ...utils.imageUtils import resize_if_needed, all_cropped_images_to_one_image
4
  from .panDataExtractor import extract_panData
 
5
 
6
  def process_results(results, img):
7
- label_indices = {"dob": 0, "father": 1, "name": 2, "pan_num": 3}
8
  confidence_threshold = 0.3
9
  input_image_format = img.format if img.format else "PNG"
10
  valid_formats = ["JPEG", "PNG", "BMP", "GIF", "TIFF"]
11
  input_image_format = input_image_format if input_image_format in valid_formats else "PNG"
12
 
13
- cropped_images_with_labels = []
 
14
  precision_data = {label: {"correct": 0, "total": 0} for label in label_indices.keys()}
15
- # extracted_data = {"pan_num": "", "name": "", "father": "", "dob": ""}
16
 
17
  for result in results:
18
  for bbox, cls, conf in zip(result.boxes.xyxy, result.boxes.cls, result.boxes.conf):
19
- label = ["dob", "father", "name", "pan_num"][int(cls)]
 
 
 
 
 
20
  print(label, conf)
21
  if conf < confidence_threshold:
22
  continue
23
-
24
  x1, y1, x2, y2 = map(int, bbox.tolist())
25
  crop_img = img.crop((x1, y1, x2, y2))
26
  crop_img = resize_if_needed(crop_img)
27
- # crop_img.save(f"temp_{label}.png")
28
- cropped_images_with_labels.append((crop_img, label_indices[label], conf))
29
- precision_data[label]["total"] += 1
30
- precision_data[label]["correct"] += 1 # Replace with actual OCR validation check
 
 
 
 
 
 
 
31
 
32
  # Sort the images by their label indices in ascending order
33
  cropped_images_with_labels.sort(key=lambda x: x[1])
34
  print(cropped_images_with_labels, "cropped images with labels")
 
 
 
 
35
  # Extract only the images for concatenation
36
  cropped_images = [img for img, _, _ in cropped_images_with_labels]
37
- # print(cropped_images, "cropped images")
38
- if not cropped_images:
39
- raise ValueError("No images were cropped.")
40
 
41
  final_image = all_cropped_images_to_one_image(cropped_images, separator_image_path='app/utils/seprator3.png')
42
  buffer = BytesIO()
@@ -49,4 +63,4 @@ def process_results(results, img):
49
  texts = [line['text'] for line in lines]
50
  print(texts, "text after microsoft ocr")
51
  extracted_data = extract_panData(texts)
52
- return extracted_data
 
2
  from ...utils.azureOCR import analyze_image
3
  from ...utils.imageUtils import resize_if_needed, all_cropped_images_to_one_image
4
  from .panDataExtractor import extract_panData
5
+ from collections import defaultdict
6
 
7
  def process_results(results, img):
8
+ label_indices = {"pan_num": 0, "name": 1, "father": 2, "dob": 3}
9
  confidence_threshold = 0.3
10
  input_image_format = img.format if img.format else "PNG"
11
  valid_formats = ["JPEG", "PNG", "BMP", "GIF", "TIFF"]
12
  input_image_format = input_image_format if input_image_format in valid_formats else "PNG"
13
 
14
+ best_crops = {label: (None, -1) for label in label_indices.keys()} # Store best (image, confidence) pairs
15
+
16
  precision_data = {label: {"correct": 0, "total": 0} for label in label_indices.keys()}
 
17
 
18
  for result in results:
19
  for bbox, cls, conf in zip(result.boxes.xyxy, result.boxes.cls, result.boxes.conf):
20
+ # Ensure the class index is within the bounds of the label list
21
+ if int(cls) >= len(label_indices):
22
+ print(f"Warning: Class index {cls} is out of range. Skipping this bbox.")
23
+ continue
24
+
25
+ label = list(label_indices.keys())[int(cls)]
26
  print(label, conf)
27
  if conf < confidence_threshold:
28
  continue
29
+
30
  x1, y1, x2, y2 = map(int, bbox.tolist())
31
  crop_img = img.crop((x1, y1, x2, y2))
32
  crop_img = resize_if_needed(crop_img)
33
+ crop_img.save(f"temp_{label}.png")
34
+
35
+ # Replace old crop if new one has higher confidence
36
+ _, best_conf = best_crops[label]
37
+ if conf > best_conf:
38
+ best_crops[label] = (crop_img, conf)
39
+ precision_data[label]["total"] += 1
40
+ precision_data[label]["correct"] += 1 # Replace with actual OCR validation check
41
+
42
+ # Extract the images for final processing
43
+ cropped_images_with_labels = [(img, label_indices[label], conf) for label, (img, conf) in best_crops.items() if img is not None]
44
 
45
  # Sort the images by their label indices in ascending order
46
  cropped_images_with_labels.sort(key=lambda x: x[1])
47
  print(cropped_images_with_labels, "cropped images with labels")
48
+
49
+ if not cropped_images_with_labels:
50
+ raise ValueError("No images were cropped.")
51
+
52
  # Extract only the images for concatenation
53
  cropped_images = [img for img, _, _ in cropped_images_with_labels]
 
 
 
54
 
55
  final_image = all_cropped_images_to_one_image(cropped_images, separator_image_path='app/utils/seprator3.png')
56
  buffer = BytesIO()
 
63
  texts = [line['text'] for line in lines]
64
  print(texts, "text after microsoft ocr")
65
  extracted_data = extract_panData(texts)
66
+ return extracted_data