-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscan.py
149 lines (112 loc) · 4.32 KB
/
scan.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# -*- coding: utf-8 -*-
import cv2
import time
class ImgScanner(object):
def __init__(self, image, step_y=16, step_x=16, win_y=64, win_x=64):
self._layer = image
self._step_x = step_x
self._step_y = step_y
self._win_x = win_x
self._win_y = win_y
self.x1 = None
self.x2 = None
self.y1 = None
self.y2 = None
def generate_next(self):
"""Generate next patch
# Yields
patch : ndarray, shape of (self._win_y, self._win_x) or (self._win_y, self._win_x, 3)
"""
for y in range(0, self._layer.shape[0] - self._win_y, self._step_y):
for x in range(0, self._layer.shape[1] - self._win_x, self._step_x):
self.y1 = y
self.y2 = y + self._win_y
self.x1 = x
self.x2 = x + self._win_x
patch = self._layer[self.y1:self.y2, self.x1:self.x2]
yield patch
def get_bb(self):
p1 = (self.x1, self.y1)
p2 = (self.x2, self.y2)
return p1, p2
def get_patches(self):
patches = [patch for patch in self.generate_next()]
return patches
def show_process(self):
for _ in self.generate_next():
clone = self._layer.copy()
p1, p2 = self.get_bb()
cv2.rectangle(clone, p1, p2, (0, 255, 0), 2)
cv2.imshow("Test Image Scanner", clone)
cv2.waitKey(1)
time.sleep(0.025)
class ImgPyramid(object):
def __init__(self, image, scale=0.8, min_y=96, min_x=96):
self.layer = image.copy()
self.scale_for_original = 1.0
self._scale = scale
self._min_y = min_y
self._min_x = min_x
def generate_next(self):
# yield self.layer
while True:
h = int(self.layer.shape[0] * self._scale)
w = int(self.layer.shape[1] * self._scale)
self.layer = cv2.resize(self.layer, (w, h))
if h < self._min_y or w < self._min_x:
break
self.scale_for_original = self.scale_for_original * self._scale
yield self.layer
def show_process(self):
for _ in self.generate_next():
clone = self.layer.copy()
cv2.imshow("Test Image Pyramid", clone)
cv2.waitKey(1)
time.sleep(0.25)
class MultipleScanner(object):
def __init__(self, image):
self._image = image
self.layer = None
self.img_scanner = None
self.img_pyramid = None
self._updated = False
def generate_next(self):
self.img_pyramid = ImgPyramid(self._image)
for layer in self.img_pyramid.generate_next():
self.img_scanner = ImgScanner(layer)
self.layer = layer
self._updated = True
for patch in self.img_scanner.generate_next():
p1, p2 = self.img_scanner.get_bb()
self._set_original_box(p1, p2)
yield patch
self._updated = False
def get_bb(self):
"""Get coordinates being scanned in the original image"""
p1 = (self._x1, self._y1)
p2 = (self._x2, self._y2)
return p1, p2
def get_pyramid_bb(self):
"""Get coordinates being scanned in the scaled layer"""
p1, p2 = self.img_scanner.get_bb()
return p1, p2
def is_updated_layer(self):
return self._updated
def show_process(self):
for _ in self.generate_next():
clone = self._image.copy()
p1, p2 = self.get_bb()
cv2.rectangle(clone, p1, p2, (0, 255, 0), 2)
cv2.imshow("Test Image Scanner", clone)
cv2.waitKey(1)
time.sleep(0.025)
def _set_original_box(self, p1, p2):
"""Set bounding box coordinate in the original image"""
p1_original = [int(c / self.img_pyramid.scale_for_original) for c in (p1)]
p2_original = [int(c / self.img_pyramid.scale_for_original) for c in (p2)]
self._x1, self._y1 = p1_original
self._x2, self._y2 = p2_original
if __name__ == "__main__":
image = cv2.imread("..//test_images//test1.jpg")[400:656, :, :]
slider = MultipleScanner(image)
slider.show_process()