Niv Sardi commited on
Commit
4e1c07d
1 Parent(s): 63501c1

imtool: better types and use our data structures

Browse files

Signed-off-by: Niv Sardi <xaiki@evilgiggle.com>

Files changed (1) hide show
  1. python/imtool.py +54 -67
python/imtool.py CHANGED
@@ -4,7 +4,7 @@ import os
4
  import math
5
  import cv2
6
  import numpy as np
7
- from typing import NamedTuple, Tuple
8
 
9
  from entity import Entity
10
  from common import mkdir
@@ -19,8 +19,8 @@ class BoundingBox(NamedTuple):
19
  h: float = 0.0
20
 
21
  @classmethod
22
- def from_centroid(cls, c, shape = (1,1,1)):
23
- (h, w, c) = shape
24
  print(cls, c, shape)
25
  self = cls(x=math.floor(w*(c.x - c.w/2))
26
  , y=math.floor(h*(c.y - c.h/2))
@@ -35,21 +35,48 @@ class BoundingBox(NamedTuple):
35
 
36
  @property
37
  def start(self):
38
- return (self.x, self.y)
39
 
40
  @property
41
  def end(self):
42
- return (self.x + self.w, self.y + self.h)
43
 
44
- def to_centroid(self, shape = (1,1,1)):
45
  (h, w, c) = shape
46
  return Centroid(x=math.floor(self.x + self.w/2)/w
47
  , y=math.floor(self.y + self.h/2)/h
48
  , w=math.ceil(self.w)/w
49
  , h=math.ceil(self.h)/h)
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  class Centroid(BoundingBox):
52
- def to_bounding_box(self, shape = (1,1,1)):
53
  (h, w, c) = shape
54
 
55
  return BoundingBox(
@@ -58,10 +85,8 @@ class Centroid(BoundingBox):
58
  , w=math.ceil(w*self.w)
59
  , h=math.ceil(h*self.h))
60
 
61
- def to_anotation(self, id: int, shape=(1,1,1)):
62
- (h, w, c) = shape
63
-
64
- return f'{id} {self.x/w} {self.y/h} {self.w/w} {self.h/h}'
65
 
66
  def read_marker(filename: str, Type: type):
67
  ret = []
@@ -70,8 +95,7 @@ def read_marker(filename: str, Type: type):
70
  lines = f.readlines()
71
  for l in lines:
72
  (b, x,y,w,h) = [float(i) for i in l.split(' ')]
73
- bco = b
74
- print(b, x,y,w,h)
75
  ret.append(Type(x,y,w,h))
76
  return bco, ret
77
 
@@ -93,17 +117,16 @@ def floor_point(x: float, y: float):
93
  return (math.floor(x), math.floor(y))
94
 
95
  def cut_img(im, s: Tuple[float, float], e: Tuple[float, float]):
96
- x = s[0]
97
- y = s[1]
98
- w = e[0] - x
99
- h = e[1] - y
100
 
101
- print("DEBUG", im.shape, x, y, w, h)
102
- return im[y:h, x:w]
103
 
104
  def cut_logo(im, l):
105
  (x, y, w, h) = floor_logo(l)
106
- return im[x:w, y:h]
107
 
108
  def add_alpha(img):
109
  b, g, r = cv2.split(img)
@@ -200,62 +223,26 @@ def crop(id, fn, logos):
200
  rim = cv2.rectangle(rim, start, end, color, 10)
201
  li = []
202
  for l in logos:
203
- rim = cv2.rectangle(rim,
204
- floor_point(l.x, l.y),
205
- floor_point(l.x + l.w, l.y + l.h),
206
- logo_color, 5)
207
- def intersect():
208
- six = l.x - f.x
209
- siy = l.y - f.y
210
- eix = six + l.w
211
- eiy = siy + l.h
212
-
213
- #print('intersect', (six, siy), (eix, eiy), f, l)
214
-
215
- if six < 0:
216
- if six + l.w < 0:
217
- return None
218
- six = 0
219
- if siy < 0:
220
- if siy + l.h < 0:
221
- return None
222
- siy = 0
223
- if eix > tw:
224
- if eix - l.w > tw:
225
- return None
226
- eix = tw
227
- if eiy > th:
228
- if eiy - l.h > th:
229
- return None
230
- eiy = th
231
-
232
- return BoundingBox(six, siy, eix - six, eiy - siy)
233
-
234
- p = intersect()
235
  if p:
236
  li.append(p)
237
 
238
- nim = im[start[1]:end[1], start[0]:end[0]]
239
- rnim = rim[start[1]:end[1], start[0]:end[0]]
240
  img_name =f"{img_out}/{basename}-x{x}y{y}.jpg"
241
  txt_name =f"{txt_out}/{basename}-x{x}y{y}.txt"
242
 
243
  cv2.imwrite(img_name, nim)
244
  if len(li):
245
- with open(txt_name, 'w') as f:
246
  for p in li:
247
- cx = p.x
248
- cy = p.y
249
-
250
- dim = cv2.rectangle(rnim,
251
- floor_point(cx - p.w/2, cy - p.h/2),
252
- floor_point(cx + p.w/2, cy + p.h/2),
253
- logo_color,
254
- 5)
255
-
256
- a = f"{int(id)} {cx/TILE_SIZE} {cy/TILE_SIZE} {p.w/TILE_SIZE} {p.h/TILE_SIZE}\n"
257
- f.write(a)
258
- print(a)
259
  cv2.imwrite(f'{debug_out}/{basename}{x}{y}.debug.png', dim)
260
 
261
  cv2.imwrite(f'{debug_out}/{basename}.debug.png', rim)
 
4
  import math
5
  import cv2
6
  import numpy as np
7
+ from typing import NamedTuple, Tuple, List
8
 
9
  from entity import Entity
10
  from common import mkdir
 
19
  h: float = 0.0
20
 
21
  @classmethod
22
+ def from_centroid(cls, c, shape):
23
+ (ih, iw, ic) = shape
24
  print(cls, c, shape)
25
  self = cls(x=math.floor(w*(c.x - c.w/2))
26
  , y=math.floor(h*(c.y - c.h/2))
 
35
 
36
  @property
37
  def start(self):
38
+ return floor_point(self.x, self.y)
39
 
40
  @property
41
  def end(self):
42
+ return floor_point(self.x + self.w, self.y + self.h)
43
 
44
+ def to_centroid(self, shape):
45
  (h, w, c) = shape
46
  return Centroid(x=math.floor(self.x + self.w/2)/w
47
  , y=math.floor(self.y + self.h/2)/h
48
  , w=math.ceil(self.w)/w
49
  , h=math.ceil(self.h)/h)
50
 
51
+ def intersect(self, f):
52
+ six = self.x - f.x
53
+ siy = self.y - f.y
54
+ eix = six + self.w
55
+ eiy = siy + self.h
56
+
57
+
58
+
59
+ if six < 0:
60
+ if six + self.w < 0:
61
+ return None
62
+ six = 0
63
+ if siy < 0:
64
+ if siy + self.h < 0:
65
+ return None
66
+ siy = 0
67
+ if eix > f.w:
68
+ if eix - self.w > f.w:
69
+ return None
70
+ eix = f.w
71
+ if eiy > f.h:
72
+ if eiy - self.h > f.h:
73
+ return None
74
+ eiy = f.h
75
+
76
+ return BoundingBox(six, siy, eix - six, eiy - siy)
77
+
78
  class Centroid(BoundingBox):
79
+ def to_bounding_box(self, shape):
80
  (h, w, c) = shape
81
 
82
  return BoundingBox(
 
85
  , w=math.ceil(w*self.w)
86
  , h=math.ceil(h*self.h))
87
 
88
+ def to_anotation(self, id: int):
89
+ return f'{id} {self.x} {self.y} {self.w} {self.h}'
 
 
90
 
91
  def read_marker(filename: str, Type: type):
92
  ret = []
 
95
  lines = f.readlines()
96
  for l in lines:
97
  (b, x,y,w,h) = [float(i) for i in l.split(' ')]
98
+ bco = int(b)
 
99
  ret.append(Type(x,y,w,h))
100
  return bco, ret
101
 
 
117
  return (math.floor(x), math.floor(y))
118
 
119
  def cut_img(im, s: Tuple[float, float], e: Tuple[float, float]):
120
+ x1 = math.floor(s[0])
121
+ y1 = math.floor(s[1])
122
+ x2 = math.floor(e[0])
123
+ y2 = math.floor(e[1])
124
 
125
+ return im[y1:y2, x1:x2]
 
126
 
127
  def cut_logo(im, l):
128
  (x, y, w, h) = floor_logo(l)
129
+ return im[y:y+h, x:x+w]
130
 
131
  def add_alpha(img):
132
  b, g, r = cv2.split(img)
 
223
  rim = cv2.rectangle(rim, start, end, color, 10)
224
  li = []
225
  for l in logos:
226
+ bl = l.to_bounding_box(im.shape)
227
+ rim = cv2.rectangle(rim, bl.start, bl.end, logo_color, 5)
228
+ p = bl.intersect(f)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  if p:
230
  li.append(p)
231
 
232
+ nim = cut_img(im, start, end)
233
+ rnim = cut_img(im, start, end)
234
  img_name =f"{img_out}/{basename}-x{x}y{y}.jpg"
235
  txt_name =f"{txt_out}/{basename}-x{x}y{y}.txt"
236
 
237
  cv2.imwrite(img_name, nim)
238
  if len(li):
239
+ with open(txt_name, 'w') as label:
240
  for p in li:
241
+ dim = cv2.rectangle(rnim, p.start, p.end, logo_color, 5)
242
+ lc = p.to_centroid((TILE_SIZE, TILE_SIZE, 3))
243
+
244
+ a = f"{int(id)} {lc.x} {lc.y} {lc.w} {lc.h}"
245
+ label.write(a)
 
 
 
 
 
 
 
246
  cv2.imwrite(f'{debug_out}/{basename}{x}{y}.debug.png', dim)
247
 
248
  cv2.imwrite(f'{debug_out}/{basename}.debug.png', rim)