Ayesha352 commited on
Commit
1b629d9
·
verified ·
1 Parent(s): fc690df

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -30
app.py CHANGED
@@ -5,7 +5,7 @@ import gradio as gr
5
  import os
6
  import xml.etree.ElementTree as ET
7
 
8
- # ---------------- Helper Functions ----------------
9
  def get_rotated_rect_corners(x, y, w, h, rotation_deg):
10
  rot_rad = np.deg2rad(rotation_deg)
11
  cos_r, sin_r = np.cos(rot_rad), np.sin(rot_rad)
@@ -45,6 +45,18 @@ def parse_xml_points(xml_file):
45
  points.append([float(elem.get("x")), float(elem.get("y"))])
46
  return np.array(points,dtype=np.float32).reshape(-1,2)
47
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  # ---------------- Main Function ----------------
49
  def homography_all_detectors(flat_file, persp_file, json_file, xml_file):
50
  flat_img = cv2.imread(flat_file)
@@ -60,17 +72,15 @@ def homography_all_detectors(flat_file, persp_file, json_file, xml_file):
60
  xml_points = parse_xml_points(xml_file.name)
61
 
62
  methods = ["SIFT","ORB","BRISK","KAZE","AKAZE"]
63
- gallery_images = []
64
  download_files = []
65
 
66
  for method in methods:
67
  kp1,kp2,good_matches = detect_and_match(flat_gray,persp_gray,method)
68
  if kp1 is None or kp2 is None or len(good_matches)<4: continue
69
 
70
- # Feature matching
71
  match_img = cv2.drawMatches(flat_img,kp1,persp_img,kp2,good_matches,None,flags=2)
72
 
73
- # Homography & ROI
74
  src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1,1,2)
75
  dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1,1,2)
76
  H,_ = cv2.findHomography(src_pts,dst_pts,cv2.RANSAC,5.0)
@@ -86,38 +96,36 @@ def homography_all_detectors(flat_file, persp_file, json_file, xml_file):
86
  xml_mapped = cv2.perspectiveTransform(xml_points.reshape(-1,1,2),H).reshape(-1,2)
87
  for px,py in xml_mapped: cv2.circle(xml_gt_img,(int(px),int(py)),5,(0,0,255),-1)
88
 
89
- # --------- For display only: resize to match grid ---------
90
- def resize_to_height(img, target_h):
91
- h, w = img.shape[:2]
92
- scale = target_h / h
93
- new_w = int(w * scale)
94
- return cv2.resize(img, (new_w, target_h))
95
-
96
- target_h = 300 # temporary display height for gallery
97
- flat_disp = resize_to_height(flat_img, target_h)
98
- match_disp = resize_to_height(match_img, target_h)
99
- roi_disp = resize_to_height(persp_roi, target_h)
100
- xml_disp = resize_to_height(xml_gt_img, target_h)
101
-
102
- # Merge 2x2 grid for gallery display
103
- top = np.hstack([flat_disp, match_disp])
104
- bottom = np.hstack([roi_disp, xml_disp])
 
 
 
105
  combined_grid = np.vstack([top, bottom])
106
- gallery_images.append((combined_grid,f"{method} Detector"))
107
 
108
- # Save original resolution for download
109
  base_name = os.path.splitext(os.path.basename(persp_file))[0]
110
  file_name = f"{base_name}_{method.lower()}.png"
111
- # Merge original images for download
112
- top_orig = np.hstack([flat_img, match_img])
113
- bottom_orig = np.hstack([persp_roi, xml_gt_img])
114
- combined_orig = np.vstack([top_orig, bottom_orig])
115
- cv2.imwrite(file_name, combined_orig)
116
  download_files.append(file_name)
117
 
118
- # Ensure 5 outputs
119
  while len(download_files)<5: download_files.append(None)
120
- return gallery_images, download_files[0], download_files[1], download_files[2], download_files[3], download_files[4]
121
 
122
  # ---------------- Gradio UI ----------------
123
  iface = gr.Interface(
@@ -137,7 +145,7 @@ iface = gr.Interface(
137
  gr.File(label="Download AKAZE Result")
138
  ],
139
  title="Homography ROI Projection with Feature Matching & XML GT",
140
- description="Shows 4 views per detector. Grid resized for display, original resolution saved for download."
141
  )
142
 
143
  iface.launch()
 
5
  import os
6
  import xml.etree.ElementTree as ET
7
 
8
+ # ---------------- Helper functions ----------------
9
  def get_rotated_rect_corners(x, y, w, h, rotation_deg):
10
  rot_rad = np.deg2rad(rotation_deg)
11
  cos_r, sin_r = np.cos(rot_rad), np.sin(rot_rad)
 
45
  points.append([float(elem.get("x")), float(elem.get("y"))])
46
  return np.array(points,dtype=np.float32).reshape(-1,2)
47
 
48
+ # ---------------- Padding Helper ----------------
49
+ def pad_to_size(img, target_h, target_w):
50
+ h, w = img.shape[:2]
51
+ top_pad = 0
52
+ left_pad = 0
53
+ bottom_pad = target_h - h
54
+ right_pad = target_w - w
55
+ # Create white canvas
56
+ canvas = np.ones((target_h, target_w,3), dtype=np.uint8)*255
57
+ canvas[top_pad:top_pad+h, left_pad:left_pad+w] = img
58
+ return canvas
59
+
60
  # ---------------- Main Function ----------------
61
  def homography_all_detectors(flat_file, persp_file, json_file, xml_file):
62
  flat_img = cv2.imread(flat_file)
 
72
  xml_points = parse_xml_points(xml_file.name)
73
 
74
  methods = ["SIFT","ORB","BRISK","KAZE","AKAZE"]
75
+ gallery_paths = []
76
  download_files = []
77
 
78
  for method in methods:
79
  kp1,kp2,good_matches = detect_and_match(flat_gray,persp_gray,method)
80
  if kp1 is None or kp2 is None or len(good_matches)<4: continue
81
 
 
82
  match_img = cv2.drawMatches(flat_img,kp1,persp_img,kp2,good_matches,None,flags=2)
83
 
 
84
  src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1,1,2)
85
  dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1,1,2)
86
  H,_ = cv2.findHomography(src_pts,dst_pts,cv2.RANSAC,5.0)
 
96
  xml_mapped = cv2.perspectiveTransform(xml_points.reshape(-1,1,2),H).reshape(-1,2)
97
  for px,py in xml_mapped: cv2.circle(xml_gt_img,(int(px),int(py)),5,(0,0,255),-1)
98
 
99
+ # Convert to RGB
100
+ flat_rgb = cv2.cvtColor(flat_img,cv2.COLOR_BGR2RGB)
101
+ match_rgb = cv2.cvtColor(match_img,cv2.COLOR_BGR2RGB)
102
+ roi_rgb = cv2.cvtColor(persp_roi,cv2.COLOR_BGR2RGB)
103
+ xml_rgb = cv2.cvtColor(xml_gt_img,cv2.COLOR_BGR2RGB)
104
+
105
+ # Determine max height and width for padding
106
+ max_h = max(flat_rgb.shape[0], match_rgb.shape[0], roi_rgb.shape[0], xml_rgb.shape[0])
107
+ max_w = max(flat_rgb.shape[1], match_rgb.shape[1], roi_rgb.shape[1], xml_rgb.shape[1])
108
+
109
+ # Pad all images to same size
110
+ flat_pad = pad_to_size(flat_rgb, max_h, max_w)
111
+ match_pad = pad_to_size(match_rgb, max_h, max_w)
112
+ roi_pad = pad_to_size(roi_rgb, max_h, max_w)
113
+ xml_pad = pad_to_size(xml_rgb, max_h, max_w)
114
+
115
+ # Merge 2x2 grid
116
+ top = np.hstack([flat_pad, match_pad])
117
+ bottom = np.hstack([roi_pad, xml_pad])
118
  combined_grid = np.vstack([top, bottom])
 
119
 
120
+ # Save combined grid
121
  base_name = os.path.splitext(os.path.basename(persp_file))[0]
122
  file_name = f"{base_name}_{method.lower()}.png"
123
+ cv2.imwrite(file_name, cv2.cvtColor(combined_grid,cv2.COLOR_RGB2BGR))
124
+ gallery_paths.append(file_name)
 
 
 
125
  download_files.append(file_name)
126
 
 
127
  while len(download_files)<5: download_files.append(None)
128
+ return gallery_paths, download_files[0], download_files[1], download_files[2], download_files[3], download_files[4]
129
 
130
  # ---------------- Gradio UI ----------------
131
  iface = gr.Interface(
 
145
  gr.File(label="Download AKAZE Result")
146
  ],
147
  title="Homography ROI Projection with Feature Matching & XML GT",
148
+ description="Flat + Perspective images with mockup.json & XML. Original resolution maintained. Grid aligned with white padding."
149
  )
150
 
151
  iface.launch()