/
main.py
162 lines (128 loc) · 6.13 KB
/
main.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
150
151
152
153
154
155
156
157
158
159
160
161
162
import glob
import cv2
import sys
import numpy as np
from matcher import matcher
debugShowIm = False
class Stitching:
#Constructor stitching
def __init__(self, args):
#Salvam argumentul de intrare in program (path-ul catre directorul cu poze si setam algoritm surf/sift
self.path = args
self.siftOrSurf = 'surf'
#Citim imaginile din director, le facem un resize si le memoram in images
self.images = [cv2.resize(cv2.imread(file), (700, 610)) for file in glob.glob(self.path + "*.jpg")]
#Salvam numarul de imagini
self.count = len(self.images)
print("Imagini gasite: ", self.count)
#Initializare de array-uri
self.leftList, self.rightList = [], []
#Initializam un obiect de tip matcher caruia ii pasam tipul de algoritm definit mai sus
self.matcher_obj = matcher(siftOrSurf=self.siftOrSurf)
def addLeftToRight(self, indexMid):
#Memoram imaginea din centru
left = self.images[indexMid]
#Parcurgem catre dreapta urmatoarele imagini
for i in range(indexMid, self.count):
#Salvam urmatoarea imaginie
right = self.images[i]
#Determinam match-ul intre imaginea dreapta si stanga
H = self.matcher_obj.match(right, left)
#Facem un warp pe imaginea ce urmeaza sa fie adaugata in dreapta
right = cv2.warpPerspective(right, H, (right.shape[1] + left.shape[1], right.shape[0]))
#Debug imshow
if debugShowIm:
imgName='warped-LTR-'+str(i)+'.jpg'
cv2.imshow(imgName, right)
cv2.waitKey()
#Cautam coloana dupa care urmeaza sa cropam imaginea din stanga, conditia de cropare:
#gasirea celei mai indepartat pixel (de marginea din dreapta) ce are valoarea [0,0,0].
#Cautarea se face pe prima linie si pe ultima linie
value = left.shape[1]
for i in reversed(range(left.shape[1])):
if left[0][i][0] == 0 and left[0][i][1] == 0 and left[0][i][2] == 0:
value = i
if left[-1][i][0] == 0 and left[-1][i][1] == 0 and left[-1][i][2] == 0:
value = i
#Cropam imaginea din stanga
left = left[:, 0:value, :]
#Adaugam peste imaginea warpped (rightImage) imaginea din stanga - prima iteratie: imaginea din stanga = imaginea centrala)
# a doua iteratie: imaginea din stanga= imaginea centrala+imaginea warpped la prima iteratie
# ...
#Pentru aceast pas am realizat croparea de la linia 63, deoarece daca nu realizam croparea
#imaginea de suprapus continea parti negre care suprascriau informatia din imaginea warpped
#parti negre obtinute in urma warp-ului
right[:, 0:left.shape[1]] = left
#Debug imshow
if debugShowIm:
imgName='right-LTR-'+str(i)+'.jpg'
cv2.imshow(imgName, right)
cv2.waitKey()
left = right
#Debug imshow
if debugShowIm:
imgName='final-addLeftToRight.jpg'
cv2.imshow(imgName, left)
cv2.waitKey()
#Memoram rezultatul metodei
self.rightImage = left
def addRightToLeft(self, indexMid):
#Memoram imaginea din centru
right = self.images[indexMid]
#Parcurgem catre stanga urmatoarele imagini
for i in reversed(range(indexMid)):
#Salvam urmatoarea imaginie
left = self.images[i]
#Determinam match-ul intre imaginea dreapta si stanga
H = self.matcher_obj.match(right, left)
# Ii facem inversa matricei de transformare deoarece in mod normal orientarea warpului
#era '/' iar noi pentru a adauga la dreapta avem nevoie de orientare '\'
H = np.linalg.inv(H)
#Am adaugat si un offset pe axa X, deoarece fara el o parte din imaginea
#warpped era in afara ferestrei de afisare
H[0][2] = H[0][2]+left.shape[1]
#Facem un warp pe imaginea ce urmeaza sa fie adaugata in stanga
left = cv2.warpPerspective(left, H, (left.shape[1], left.shape[0]))
#Debug imshow
if debugShowIm:
imgName='warped-RTL-'+str(i)+'.jpg'
cv2.imshow(imgName, left)
cv2.waitKey()
#Unim cele 2 imagini
left = np.concatenate((left[:,0:right.shape[1],:], right), axis=1)
# Similar cu croparea de mai sus, doar ca de data aceasta vom sterge partea neagra
#care a ramas in stanga imaginii
valueUp = -2
valueDown = -2
for i in range(left.shape[1]):
if left[0][i][0] != 0 and left[0][i][1] != 0 and left[0][i][2] != 0:
valueUp = i - 1
if valueDown != -2:
break
if left[-1][i][0] != 0 and left[-1][i][1] != 0 and left[-1][i][2] != 0:
valueDown = i - 1
if valueUp != -2:
break
#Realizam croparea
left = left[:, max(valueUp, valueDown):left.shape[1], :]
#Debug imshow
if debugShowIm:
imgName='warped-LTR-'+str(i)+'.jpg'
cv2.imshow(imgName, right)
cv2.waitKey()
right = left
#Memoram rezultatul metodei
self.leftImage = right
if __name__ == '__main__':
args = sys.argv[1]
#Instantie obiectul
stitch_obj = Stitching(args)
#Apelarea metodelor
midIndex = stitch_obj.count//2
stitch_obj.addLeftToRight(midIndex)
stitch_obj.addRightToLeft(midIndex)
imRight = stitch_obj.rightImage
imLeft = stitch_obj.leftImage
#Generam rezultatul final
imageFinal = np.concatenate((imLeft, imRight[:, stitch_obj.images[midIndex].shape[1]:]), axis=1)
cv2.imwrite('Image.jpg', imageFinal)