강세희

[UPDATE] 이미지 크롭 구현

No preview for this file type
No preview for this file type
No preview for this file type

585 KB | W: | H:

591 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

649 KB | W: | H:

621 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
...@@ -76,14 +76,19 @@ if __name__ == '__main__': ...@@ -76,14 +76,19 @@ if __name__ == '__main__':
76 # 객체 정보 및 계산 값 저장 76 # 객체 정보 및 계산 값 저장
77 detectionInfo.append([i, name, size, coordinatevalue, top, left, right, bottom]) 77 detectionInfo.append([i, name, size, coordinatevalue, top, left, right, bottom])
78 78
79 + # 검출 리스트 txt파일로 내보내기
79 f = open("detectionInfo.txt", 'w') 80 f = open("detectionInfo.txt", 'w')
80 for i in range(len(detectionInfo)): 81 for i in range(len(detectionInfo)):
81 data = str(detectionInfo[i][0]) +", " + detectionInfo[i][1] + ", " + str(detectionInfo[i][2]) + ", " + str(detectionInfo[i][3]) + ", " + str(detectionInfo[i][4]) + ", " + str(detectionInfo[i][5]) + ", " + str(detectionInfo[i][6]) + ", " + str(detectionInfo[i][7]) + "\n" 82 data = str(detectionInfo[i][0]) +", " + detectionInfo[i][1] + ", " + str(detectionInfo[i][2]) + ", " + str(detectionInfo[i][3]) + ", " + str(detectionInfo[i][4]) + ", " + str(detectionInfo[i][5]) + ", " + str(detectionInfo[i][6]) + ", " + str(detectionInfo[i][7]) + "\n"
82 f.write(data) 83 f.write(data)
83 f.close() 84 f.close()
84 85
86 + # 크롭할 이미지의 이름을 저장하는 딕셔너리
87 + cropDict = {}
88 +
85 # 검출된 물체 리스트(중복 없이) 89 # 검출된 물체 리스트(중복 없이)
86 namelist = {} 90 namelist = {}
91 +
87 for i in range(len(detectionInfo)): 92 for i in range(len(detectionInfo)):
88 if not detectionInfo[i][1] in namelist: 93 if not detectionInfo[i][1] in namelist:
89 namelist[detectionInfo[i][1]] = [] 94 namelist[detectionInfo[i][1]] = []
...@@ -98,11 +103,14 @@ if __name__ == '__main__': ...@@ -98,11 +103,14 @@ if __name__ == '__main__':
98 maxvalue = detectionInfo[j][2] 103 maxvalue = detectionInfo[j][2]
99 maxindex = detectionInfo[j][0] 104 maxindex = detectionInfo[j][0]
100 namelist[objectName].append(maxindex) 105 namelist[objectName].append(maxindex)
101 - 106 +
107 + cropDict[1] = []
102 for objectname, framelist in namelist.items(): 108 for objectname, framelist in namelist.items():
103 image = cv2.imread("mid/frame%d.png" % framelist[0]) 109 image = cv2.imread("mid/frame%d.png" % framelist[0])
104 output1 = cv2.GaussianBlur(image, (5,5), 0) 110 output1 = cv2.GaussianBlur(image, (5,5), 0)
105 - cv2.imwrite("output1/%s.png"% (objectname), output1) 111 + cv2.imwrite("output1/%s.png"% (objectname), output1)
112 + cropDict[1].append((objectname, detectionInfo[framelist[0]][4],detectionInfo[framelist[0]][5],
113 + detectionInfo[framelist[0]][6], detectionInfo[framelist[0]][7]))
106 114
107 # 가운데 위치 115 # 가운데 위치
108 for objectName in namelist.keys(): 116 for objectName in namelist.keys():
...@@ -117,12 +125,14 @@ if __name__ == '__main__': ...@@ -117,12 +125,14 @@ if __name__ == '__main__':
117 minvalue = detectionInfo[j][3] 125 minvalue = detectionInfo[j][3]
118 minindex = detectionInfo[j][0] 126 minindex = detectionInfo[j][0]
119 namelist[objectName].append(minindex) 127 namelist[objectName].append(minindex)
120 - 128 +
129 + cropDict[2] = []
121 for objectname, framelist in namelist.items(): 130 for objectname, framelist in namelist.items():
122 image = cv2.imread("mid/frame%d.png" % framelist[0]) 131 image = cv2.imread("mid/frame%d.png" % framelist[0])
123 output2 = cv2.GaussianBlur(image, (5,5), 0) 132 output2 = cv2.GaussianBlur(image, (5,5), 0)
124 cv2.imwrite("output2/%s.png"% (objectname), output2) 133 cv2.imwrite("output2/%s.png"% (objectname), output2)
125 - 134 + cropDict[2].append((objectname, detectionInfo[framelist[0]][4], detectionInfo[framelist[0]][5],
135 + detectionInfo[framelist[0]][6], detectionInfo[framelist[0]][7]))
126 136
127 # 계획2 : 프레임별로 나온 객체 겹치는 부분 제외하고 넓이 구해 큰거 Indexlist에 넣기 137 # 계획2 : 프레임별로 나온 객체 겹치는 부분 제외하고 넓이 구해 큰거 Indexlist에 넣기
128 # 모든 프레임에 적용하지 않고 여러 객체가 나온 프레임 선정, 프레임 인덱스 저장하는 best 딕셔너리 138 # 모든 프레임에 적용하지 않고 여러 객체가 나온 프레임 선정, 프레임 인덱스 저장하는 best 딕셔너리
...@@ -131,7 +141,7 @@ if __name__ == '__main__': ...@@ -131,7 +141,7 @@ if __name__ == '__main__':
131 for i in range(len(detectionInfo)): 141 for i in range(len(detectionInfo)):
132 if best.count(detectionInfo[i][0]) == 2: 142 if best.count(detectionInfo[i][0]) == 2:
133 if detectionInfo[i][0] in bestList: 143 if detectionInfo[i][0] in bestList:
134 - bestList[detectionInfo[i][0]].append(detectionInfo[i][1:]) 144 + bestList[detectionInfo[i][0]].append(detectionInfo[i][1:]) # 이름, 사이즈, 중심과의 거리, x, y, w, h 저장
135 else: 145 else:
136 bestList[detectionInfo[i][0]] = [detectionInfo[i][1:]] 146 bestList[detectionInfo[i][0]] = [detectionInfo[i][1:]]
137 elif best.count(best[i]) > 2: 147 elif best.count(best[i]) > 2:
...@@ -140,6 +150,7 @@ if __name__ == '__main__': ...@@ -140,6 +150,7 @@ if __name__ == '__main__':
140 else: 150 else:
141 bestList[best[i]] = [[i, detectionInfo[i][3]]] 151 bestList[best[i]] = [[i, detectionInfo[i][3]]]
142 152
153 + # 프레임에 등장하는 객체가 2개 이상인 경우, 가장 적합한 객체 두 개 선정
143 for key, value in bestList.items(): 154 for key, value in bestList.items():
144 if len(value[0]) == 2: 155 if len(value[0]) == 2:
145 tmpValue = deepcopy(value) 156 tmpValue = deepcopy(value)
...@@ -153,13 +164,15 @@ if __name__ == '__main__': ...@@ -153,13 +164,15 @@ if __name__ == '__main__':
153 second = indexList[minCordi] 164 second = indexList[minCordi]
154 bestList[key] = [detectionInfo[first][1:], detectionInfo[second][1:]] 165 bestList[key] = [detectionInfo[first][1:], detectionInfo[second][1:]]
155 166
156 - # beOverlap 에 선정된 두 객체의 top, left, right, bottom 값 비교하여 두 객체의 합산 size 계산, 이를 overlapped에 저장 167 + # beOverlap 에 선정된 두 객체의 top, left, right, bottom 값 비교하여 두 객체의 합산 size 계산, 이를 overlapped에 저장
157 - # 이 , value는 항상 두 가지 값만을 가짐 168 + # 이 후로, value는 항상 두 가지 값만을 가짐
158 deleteList = [] 169 deleteList = []
159 for key, value in bestList.items(): 170 for key, value in bestList.items():
160 a_top, a_left, a_right, a_bottom = value[0][3:] 171 a_top, a_left, a_right, a_bottom = value[0][3:]
161 b_top, b_left, b_right, b_bottom = value[1][3:] 172 b_top, b_left, b_right, b_bottom = value[1][3:]
162 o_top, o_left, o_right, o_bottom = 0, 0, 0, 0 173 o_top, o_left, o_right, o_bottom = 0, 0, 0, 0
174 +
175 + # 두 객체가 겹쳤는지 좌표 비교를 통해 확인, 겹쳤다면 겹친 부분의 좌표 값 o_xxx 에 저장
163 isOverlapped = False 176 isOverlapped = False
164 if a_top < b_top < a_bottom or b_top < a_top < b_bottom or a_left < b_left < a_right or b_left < a_left < b_right: 177 if a_top < b_top < a_bottom or b_top < a_top < b_bottom or a_left < b_left < a_right or b_left < a_left < b_right:
165 isOverlapped = True 178 isOverlapped = True
...@@ -168,7 +181,9 @@ if __name__ == '__main__': ...@@ -168,7 +181,9 @@ if __name__ == '__main__':
168 o_left = max(a_left, b_left) 181 o_left = max(a_left, b_left)
169 o_right = min(a_right, b_right) 182 o_right = min(a_right, b_right)
170 183
184 + # 겹친 부분의 넓이 구하기
171 o_size = (o_bottom-o_top)*(o_right-o_left) 185 o_size = (o_bottom-o_top)*(o_right-o_left)
186 + # 겹친 객체를 하나로 보고, 두 객체의 중심점을 찾아 프레임의 중앙과의 거리 구하기
172 if isOverlapped == True: 187 if isOverlapped == True:
173 a_object = Point2D(width= (a_top + a_bottom)//2, height=(a_left + a_right)//2) 188 a_object = Point2D(width= (a_top + a_bottom)//2, height=(a_left + a_right)//2)
174 b_object = Point2D(width= (b_top + b_bottom)//2, height=(b_left + b_right)//2) 189 b_object = Point2D(width= (b_top + b_bottom)//2, height=(b_left + b_right)//2)
...@@ -176,10 +191,11 @@ if __name__ == '__main__': ...@@ -176,10 +191,11 @@ if __name__ == '__main__':
176 toTheOrigin_w = image.shape[1] / 2 - o_object.width 191 toTheOrigin_w = image.shape[1] / 2 - o_object.width
177 toTheOrigin_h = image.shape[0] / 2 - o_object.height 192 toTheOrigin_h = image.shape[0] / 2 - o_object.height
178 coordiValue_object = int(math.sqrt((toTheOrigin_w ** 2) + (toTheOrigin_h ** 2))) 193 coordiValue_object = int(math.sqrt((toTheOrigin_w ** 2) + (toTheOrigin_h ** 2)))
179 - bestList[key] = [value[0][0] + ", "+ value[1][0], value[0][1]+value[1][1]-o_size, coordiValue_object] 194 + bestList[key] = [value[0][0] + ", "+ value[1][0], value[0][1]+value[1][1]-o_size, coordiValue_object, min(a_top, b_top), min(a_left, b_left), max(a_right, b_right), max(a_bottom, b_bottom)]
180 else: 195 else:
196 + # 겹치지 않았다면 목록에서 삭제
181 deleteList.append(key) 197 deleteList.append(key)
182 - for i in range(len(deleteList)): 198 + for i in range(len(deleteList)-1, -1, -1):
183 del bestList[deleteList[i]] 199 del bestList[deleteList[i]]
184 200
185 namelist.clear() 201 namelist.clear()
...@@ -194,25 +210,61 @@ if __name__ == '__main__': ...@@ -194,25 +210,61 @@ if __name__ == '__main__':
194 else: 210 else:
195 namelist[value[0]] = [key] + value[1:] 211 namelist[value[0]] = [key] + value[1:]
196 212
213 +
197 # output3에 출력 214 # output3에 출력
215 + cropDict[3] = []
198 for objectname, framelist in namelist.items(): 216 for objectname, framelist in namelist.items():
199 image = cv2.imread("mid/frame%d.png" % framelist[0]) 217 image = cv2.imread("mid/frame%d.png" % framelist[0])
200 output3 = cv2.GaussianBlur(image, (5, 5), 0) 218 output3 = cv2.GaussianBlur(image, (5, 5), 0)
201 cv2.imwrite("output3/%s.png" % (objectname), output3) 219 cv2.imwrite("output3/%s.png" % (objectname), output3)
202 - 220 + cropDict[3].append((objectname, detectionInfo[framelist[0]][4],detectionInfo[framelist[0]][5],
203 - 221 + detectionInfo[framelist[0]][6], detectionInfo[framelist[0]][7]))
204 222
205 # 계획3 : 객체가 특정 위치에 있는 프레임 뽑기 223 # 계획3 : 객체가 특정 위치에 있는 프레임 뽑기
206 -
207 # output1~3의 결과들을 가지고 특정 위치에 있게 이미지 크롭, 결과를 output1_1, output2_1, output3_1 에 저장 224 # output1~3의 결과들을 가지고 특정 위치에 있게 이미지 크롭, 결과를 output1_1, output2_1, output3_1 에 저장
208 - 225 + for outputNum, frameList in cropDict.items():
209 - 226 + for i in range(len(frameList)):
210 - 227 + image = cv2.imread("output%d/%s.png" % (outputNum, frameList[i][0]))
211 - 228 + crop_top = 0
212 - 229 + crop_bottom = image.shape[0]
213 - 230 + crop_left = 0
214 - 231 + crop_right = image.shape[1]
215 - 232 + output = image[crop_top:crop_bottom, crop_left:crop_right].copy()
216 -#kernel_sharpen_1 = np.array([[-1,-1,-1],[-1,9,-1],[-1,-1,-1]]) 233 + # 읽어온 이미지의 비가 거의 16:9이면, 입력받은 이미지 그대로 추천
217 -#output2 = cv2.filter2D(output1,-1,kernel_sharpen_1) 234 + if image.shape[0]//9 * 15 < image.shape[1] <= image.shape[0]//9 * 16:
218 - 235 + cropDict[outputNum][i] = (frameList[i][0], 0, image.shape[0], 0, image.shape[1])
236 + else:
237 + # 읽어온 이미지의 비가 16:9가 아니라면, 검출 객체의 높이를 가져와서 이에 맞는 16비의 너비 구함
238 + # frameList = (프레임이름, top, left, right, bottom)
239 + crop_top = int(frameList[i][1] + (frameList[i][4] - frameList[i][1]) * 0.15)
240 + crop_bottom = frameList[i][4]
241 + height = crop_bottom - crop_top
242 + width = height // 9 * 16
243 + crop_left = frameList[i][2]
244 + crop_right = frameList[i][3]
245 +
246 + # 원하는 가로길이가 원본프레임의 가로길이보다 큰 경우
247 + if width > image.shape[1]:
248 + padNum = width - image.shape[1]
249 + output = image[crop_top:crop_bottom, 0:image.shape[1]].copy()
250 + ratio = int((image.shape[1]+padNum)/image.shape[1])
251 + output = cv2.resize(output, dsize=(width, height), interpolation=cv2.INTER_LINEAR)
252 + # 물체가 프레임의 중앙에 있을 경우
253 + elif image.shape[1]//2 - image.shape[1]//20 < (crop_left + crop_right)// 2 <= image.shape[1]//2 + image.shape[1]//20:
254 + crop_left = (crop_left + crop_right)//2 - width//2
255 + crop_right = (crop_left + crop_right)//2 + width//2
256 + output = image[crop_top:crop_bottom, crop_left:crop_right].copy()
257 + # 물체가 프레임의 왼쪽에 있을 경우
258 + elif (crop_left + crop_right)//2 < image.shape[1]//2:
259 + crop_left = 0
260 + crop_right = width
261 + output = image[crop_top:crop_bottom, crop_left:crop_right].copy()
262 + elif (crop_left + crop_right)//2 > image.shape[1]//2:
263 + crop_left = image.shape[1]-width
264 + crop_right = image.shape[1]
265 + output = image[crop_top:crop_bottom, crop_left:crop_right].copy()
266 +
267 + output = cv2.GaussianBlur(output, (7, 7), 0)
268 + kernel_sharpen = np.array([[-1,-1,-1],[-1,9,-1],[-1,-1,-1]])
269 + output = cv2.filter2D(output,-1, kernel_sharpen)
270 + cv2.imwrite("output%d_crop/%s.png" % (outputNum, frameList[i][0]), output)
...\ No newline at end of file ...\ No newline at end of file
......