VietCat commited on
Commit
4da1757
·
1 Parent(s): f489532

Fix tiling strategy to avoid infinite loops

Browse files

- Replace while loops with for loops using calculated tile counts
- Add _calculate_tiles_count() to compute optimal number of tiles per dimension
- Ensure minimum overlap ratio while minimizing total tile count
- Fix infinite loop issue in previous implementation
- Example: 1360x800 image → 2 tiles (1x2 grid) with 30% overlap instead of timeout

Files changed (1) hide show
  1. model.py +61 -35
model.py CHANGED
@@ -107,44 +107,80 @@ class TrafficSignDetector:
107
 
108
  print("="*80 + "\n")
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  def _create_tiles(self, image, overlap_ratio=0.2):
111
  """
112
- Cắt ảnh thành các tiles vuông với overlap.
 
 
113
  :param image: input image (numpy array)
114
- :param overlap_ratio: tỉ lệ overlap giữa các tiles (0.2 = 20%)
115
- :return: list of (tile_image, tile_coords) - tile_coords = (y1, x1, y2, x2) trong ảnh gốc
116
  """
117
  height, width = image.shape[:2]
118
- min_dim = min(height, width)
119
 
120
- print(f"\n[TILING] Image: {width}x{height}, Min dimension: {min_dim}")
121
 
122
- # Xác định stride (bước nhảy) dựa trên overlap
123
- # Nếu overlap = 20%, thì stride = 80% của tile_size
124
- stride = int(min_dim * (1 - overlap_ratio))
 
 
 
 
 
 
 
 
125
 
126
  tiles = []
127
- tile_size = min_dim
128
 
129
  # Tạo grid tiles
130
- y = 0
131
- while y < height:
132
- y_end = min(y + tile_size, height)
133
- # Nếu đây tiles cuối cùng, đảm bảo nó có đủ kích thước
134
- if y_end - y < tile_size and y > 0:
135
- y = height - tile_size
136
- y_end = height
137
-
138
- x = 0
139
- while x < width:
140
- x_end = min(x + tile_size, width)
141
- # Nếu đây tiles cuối cùng, đảm bảo nó có đủ kích thước
142
- if x_end - x < tile_size and x > 0:
143
- x = width - tile_size
144
- x_end = width
145
 
146
  # Extract tile
147
  tile = image[y:y_end, x:x_end]
 
148
  tiles.append({
149
  'image': tile,
150
  'y_min': y,
@@ -152,18 +188,8 @@ class TrafficSignDetector:
152
  'y_max': y_end,
153
  'x_max': x_end
154
  })
155
-
156
- x += stride
157
- if x >= width:
158
- break
159
-
160
- y += stride
161
- if y >= height:
162
- break
163
 
164
- print(f" - Tile size: {tile_size}x{tile_size}")
165
- print(f" - Stride: {stride} (overlap: {overlap_ratio*100:.0f}%)")
166
- print(f" - Số tiles: {len(tiles)}")
167
 
168
  return tiles
169
 
 
107
 
108
  print("="*80 + "\n")
109
 
110
+ def _calculate_tiles_count(self, length, tile_size, min_overlap=0.2):
111
+ """
112
+ Tính số tiles tối thiểu cần thiết cho 1 chiều.
113
+ Đảm bảo overlap >= min_overlap.
114
+
115
+ :param length: chiều dài của ảnh (width hoặc height)
116
+ :param tile_size: kích thước tile
117
+ :param min_overlap: overlap tối thiểu (0.2 = 20%)
118
+ :return: (num_tiles, stride)
119
+ """
120
+ if length <= tile_size:
121
+ return 1, 0
122
+
123
+ # Cần ít nhất 2 tiles
124
+ num_tiles = 2
125
+ max_iterations = 100
126
+
127
+ for _ in range(max_iterations):
128
+ # stride = (length - tile_size) / (num_tiles - 1)
129
+ stride = (length - tile_size) / (num_tiles - 1)
130
+ overlap = (tile_size - stride) / tile_size
131
+
132
+ if overlap >= min_overlap:
133
+ return num_tiles, int(stride)
134
+
135
+ num_tiles += 1
136
+
137
+ return num_tiles, int((length - tile_size) / (num_tiles - 1))
138
+
139
  def _create_tiles(self, image, overlap_ratio=0.2):
140
  """
141
+ Cắt ảnh thành các tiles vuông với overlap tối thiểu.
142
+ Tính số tiles cần thiết để cover hết ảnh với overlap >= overlap_ratio.
143
+
144
  :param image: input image (numpy array)
145
+ :param overlap_ratio: tỉ lệ overlap tối thiểu (0.2 = 20%)
146
+ :return: list of tile dicts
147
  """
148
  height, width = image.shape[:2]
149
+ tile_size = min(height, width)
150
 
151
+ print(f"\n[TILING] Image: {width}x{height}, Min dimension (tile_size): {tile_size}")
152
 
153
+ # Tính số tiles stride cho mỗi chiều
154
+ num_tiles_h, stride_h = self._calculate_tiles_count(height, tile_size, min_overlap=overlap_ratio)
155
+ num_tiles_w, stride_w = self._calculate_tiles_count(width, tile_size, min_overlap=overlap_ratio)
156
+
157
+ # Tính overlap thực tế
158
+ overlap_h = (tile_size - stride_h) / tile_size if stride_h > 0 else 0
159
+ overlap_w = (tile_size - stride_w) / tile_size if stride_w > 0 else 0
160
+
161
+ print(f" - Tile size: {tile_size}x{tile_size}")
162
+ print(f" - Height: {height} → {num_tiles_h} tiles, stride={stride_h}, overlap={overlap_h*100:.0f}%")
163
+ print(f" - Width: {width} → {num_tiles_w} tiles, stride={stride_w}, overlap={overlap_w*100:.0f}%")
164
 
165
  tiles = []
 
166
 
167
  # Tạo grid tiles
168
+ for i in range(num_tiles_h):
169
+ for j in range(num_tiles_w):
170
+ # Tính vị trí
171
+ y = int(i * stride_h)
172
+ x = int(j * stride_w)
173
+
174
+ # Đảm bảo không vượt quá bounds
175
+ y = min(y, height - tile_size)
176
+ x = min(x, width - tile_size)
177
+
178
+ y_end = y + tile_size
179
+ x_end = x + tile_size
 
 
 
180
 
181
  # Extract tile
182
  tile = image[y:y_end, x:x_end]
183
+
184
  tiles.append({
185
  'image': tile,
186
  'y_min': y,
 
188
  'y_max': y_end,
189
  'x_max': x_end
190
  })
 
 
 
 
 
 
 
 
191
 
192
+ print(f" - Total tiles: {len(tiles)} ({num_tiles_h}x{num_tiles_w})")
 
 
193
 
194
  return tiles
195