Adding Cascade Solution
Browse files
app.py
CHANGED
|
@@ -75,20 +75,79 @@ def find_and_straighten_document(image):
|
|
| 75 |
return perspective_transform(image, box)
|
| 76 |
|
| 77 |
def correct_orientation(image):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
try:
|
| 79 |
-
osd = pytesseract.image_to_osd(image, output_type=pytesseract.Output.DICT)
|
| 80 |
rotation = osd['rotate']
|
| 81 |
-
|
|
|
|
|
|
|
| 82 |
if rotation == 90:
|
| 83 |
-
|
| 84 |
elif rotation == 180:
|
| 85 |
-
|
| 86 |
else: # 270
|
| 87 |
-
|
| 88 |
-
|
| 89 |
except Exception as e:
|
| 90 |
-
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
| 93 |
# ==============================================================================
|
| 94 |
# NEW AND IMPROVED: Table Structure Recognition using OpenCV for Drawing
|
|
|
|
| 75 |
return perspective_transform(image, box)
|
| 76 |
|
| 77 |
def correct_orientation(image):
|
| 78 |
+
"""
|
| 79 |
+
Corrects the orientation of an image using a robust cascade method.
|
| 80 |
+
1. Tries fast OSD (Orientation and Script Detection).
|
| 81 |
+
2. If OSD fails, falls back to analyzing word bounding boxes.
|
| 82 |
+
"""
|
| 83 |
+
print("--- Running Orientation Check ---")
|
| 84 |
+
|
| 85 |
+
# --- METHOD 1: Fast Orientation and Script Detection (OSD) ---
|
| 86 |
try:
|
| 87 |
+
osd = pytesseract.image_to_osd(image, output_type=pytesseract.Output.DICT, timeout=5)
|
| 88 |
rotation = osd['rotate']
|
| 89 |
+
print(f"OSD check successful. Detected rotation: {rotation} degrees.")
|
| 90 |
+
if rotation > 0:
|
| 91 |
+
# Tesseract's rotation is counter-clockwise
|
| 92 |
if rotation == 90:
|
| 93 |
+
return cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
| 94 |
elif rotation == 180:
|
| 95 |
+
return cv2.rotate(image, cv2.ROTATE_180)
|
| 96 |
else: # 270
|
| 97 |
+
return cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
|
| 98 |
+
return image # Return as is if rotation is 0
|
| 99 |
except Exception as e:
|
| 100 |
+
print(f"OSD check failed: {e}. Falling back to word box analysis.")
|
| 101 |
+
|
| 102 |
+
# --- METHOD 2: Fallback using Word Bounding Box Analysis ---
|
| 103 |
+
# This method is slower but more robust for images with little text.
|
| 104 |
+
best_rotation = 0
|
| 105 |
+
max_horizontal_boxes = -1
|
| 106 |
+
|
| 107 |
+
# Pre-process image once for all rotations
|
| 108 |
+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 109 |
+
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
|
| 110 |
+
|
| 111 |
+
orientations = {
|
| 112 |
+
0: thresh,
|
| 113 |
+
90: cv2.rotate(thresh, cv2.ROTATE_90_CLOCKWISE),
|
| 114 |
+
180: cv2.rotate(thresh, cv2.ROTATE_180),
|
| 115 |
+
270: cv2.rotate(thresh, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
for angle, rotated_img in orientations.items():
|
| 119 |
+
try:
|
| 120 |
+
data = pytesseract.image_to_data(rotated_img, output_type=pytesseract.Output.DICT, timeout=5)
|
| 121 |
+
horizontal_boxes = 0
|
| 122 |
+
num_boxes = len(data['level'])
|
| 123 |
+
for i in range(num_boxes):
|
| 124 |
+
# We only consider word-level boxes (level 5) with some confidence
|
| 125 |
+
if data['level'][i] == 5 and int(data['conf'][i]) > 10:
|
| 126 |
+
w = data['width'][i]
|
| 127 |
+
h = data['height'][i]
|
| 128 |
+
if w > h: # Check if the box is horizontal
|
| 129 |
+
horizontal_boxes += 1
|
| 130 |
+
|
| 131 |
+
print(f" Rotation {angle}°: Found {horizontal_boxes} horizontal word boxes.")
|
| 132 |
+
|
| 133 |
+
if horizontal_boxes > max_horizontal_boxes:
|
| 134 |
+
max_horizontal_boxes = horizontal_boxes
|
| 135 |
+
best_rotation = angle
|
| 136 |
+
except Exception as e:
|
| 137 |
+
print(f" Word box analysis failed for rotation {angle}°: {e}")
|
| 138 |
+
continue
|
| 139 |
+
|
| 140 |
+
print(f"--> Best rotation found at {best_rotation} degrees.")
|
| 141 |
+
|
| 142 |
+
# Apply the best rotation to the ORIGINAL color image
|
| 143 |
+
if best_rotation == 90:
|
| 144 |
+
return cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
|
| 145 |
+
elif best_rotation == 180:
|
| 146 |
+
return cv2.rotate(image, cv2.ROTATE_180)
|
| 147 |
+
elif best_rotation == 270:
|
| 148 |
+
return cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
| 149 |
+
else: # 0 degrees
|
| 150 |
+
return image
|
| 151 |
|
| 152 |
# ==============================================================================
|
| 153 |
# NEW AND IMPROVED: Table Structure Recognition using OpenCV for Drawing
|