인프런 커뮤니티 질문&답변

이준우님의 프로필 이미지
이준우

작성한 질문수

[개정판] 딥러닝 컴퓨터 비전 완벽 가이드

OpenCV DNN으로 Faster RCNN Object Detection 실습 02

질문이 있습니다.

작성

·

185

0

예전에 Selective Search 를 학습하였을 당시에는, bounding box의 coordinate의 right와 bottom에  left와 top을 더해주어야 제대로된 bounding box가 형성되었습니다.

 

또한, 저번에도 이와 관련된 질문을 했었는데, 그때 답하신 것이

----------------------------------------------------------

 opencv의 rectangle()함수가 좌상단 좌표, 우하단 좌표를 필요로 하기 때문입니다. 

selective search는 좌상단 좌표와 너비, 높이를 반환합니다. 때문에 우하단 좌표의 x축값(right)은 좌상단 좌표의 x축값(left) + 너비, y축값(bottom)은 좌상단 좌표의 y축값(top) + 높이로 계산합니다. 

-------------------------------------------------------------

이로 답변하셨거든요. 근데 이번 예제는 달랐습니다. 같은 cv2.rectangle() 함수를 썼는데도 불구하고 left와 top값을 더하지 않고도 제대로된 bounding box가 형성되었거든요. 

우선 하나의 bounding box만 출력하고 좌표를 확인했을때의 right와 bottom의 coordinate는 아직 더해지지 않은 값이 입력하였으나, rectangle()에 그대로 넣어도 bounding box가 제대로 출력되는게 신기합니다. 이해를 돕기 위한 관련 사진 첨부합니다.

그림을 보면 right와 bottom에 각각 left와 top을 더하지 않아도 출력이 되는 것을 확인할 수 있습니다.

또한,

left coordinate : 225

top coordinate : 260

right coordinate : 375

bottom coordinate : 544

로 나오는데, matplotlib의 plot을 보게 되면 right와 bottom의 coordinate는 각각 left와 top의 coordinate를 더해야 나올 수 있는 bounding box인데 말이죠..ㅠㅠ 이해가 되지 않네요,

답변 1

0

권 철민님의 프로필 이미지
권 철민
지식공유자

안녕하십니까, 

질문을 제가 잘 이해했는지 모르겠지만,,,

selective search의 반환값과 opencv dnn의 반환값이 서로 다릅니다. 

selective search는 좌상단 좌표 left, top과 너비, 높이를 반환하는 것이고 opencv dnn은 좌상단 좌표 left, top과 우하단 좌표 right, bottom을 반환합니다. 

opencv의 rectangle()함수는 좌상단 좌표, 우하단 좌표를 인자로 받으므로 selective search의 반환값에 left, top, left +너비, top+높이를 해주는 것이고, opencv dnn의 반환값은 좌상단 좌표, 우하단 좌표로 되어 있으므로 그대로 적용하면 됩니다. 다만 opencv dnn은 이미지의 너비, 높이로 정규화된 값을 반환해주므로 너비 또는 높이 값을 곱해서 계산해 줍니다. 

원하시는 답변이 아니면 다시 말씀해 주십시요. 

감사합니다. 

이준우님의 프로필 이미지
이준우
질문자

음... 그래도 조금 이상합니다. 

left coordinate : 225

top coordinate : 260

right coordinate : 375

bottom coordinate : 544

본문에 말씀드린대로 cv_out을 통해 나온 좌표는 다음과 같습니다. (너비와 높이를 곱한 값이 말이죠.)  강사님이 말씀하신대로 opecv dnn은 좌상단 좌표와 우하단 좌표로 되어 나온다면 이와 같은 값이 나와야 한다고 생각해서요..

left coordinate : 225

top coordinate : 260

right coordinate : 225 + 375 = 600

bottom coordinate : 260 + 544 = 804

 

내부적으로 이와 같은 작업을 자동으로 해주는 것인지 궁금하네요.

권 철민님의 프로필 이미지
권 철민
지식공유자

왜 right coordinate : 225 + 375 = 600 되어야 하는지요? right는 그대로 우하단 x 좌표 입니다. 굳이 우하단 x좌표에 left를 더할 이유가 없어 보입니다만...  

원래 좌표에 왜 left를 더하는 지 생각하신바를 말씀해 주시겠습니까? 

이준우님의 프로필 이미지
이준우
질문자

만약 더해진 값이 들어가지 않고

right coordinate :  375

bottom coordinate : 544 가 들어간다면 

어떻게 질문의 본문과 같이 bounding box가 쳐지는지 이해가 안갑니다.  

만약 right와 bottom의 coordinate가 375와 544라면 그에 맞게 bounding box가 형성되어야 하는데, 출력되는 것을 보면 right coordinate에 left를 더하고, bottom coordinate에 top을 더한 것처럼 출력되어서 질문드렸습니다. 

나온 좌표를 보면 두번째 사람의 bounding box에 대한 정보를 갖고 있는데, cv2.rectangle()를 통해 출력된 것을 보면 더해진 것처럼 나와서요.. 

----------------------------------------------------------------------------------------------

아래의 그림도 동일합니다. 해당 되는 좌표값으로  bounding box가 형성되는 것이 아니라,  다른 무엇과 더해진 체로 출력되는 것 같아서요. 좌표값을 뽑고 비교해 보았을때 이상해서 문의드렸습니다. 저의 실수이거나 낮은 이해력으로 인해 강사님의 시간을 뺐게 되어 죄송하지만, 아직 저의 눈에는 무엇이 문제인지 모르겠습니다. ㅠㅠ

 

권 철민님의 프로필 이미지
권 철민
지식공유자

음, 아마 이미지 크기 x, y와 rectangle x, y를 헷갈리신것 같습니다만... 

이미지 크기는 633 * 806 입니다. 여기서 633은 너비가 아니라 높이입니다. 즉 y 좌표계입니다. 806은 너비이며 x 좌표계입니다. 그러니까 이미지 크기를 행렬로 표현하면 633 pixel row (height) * 806 pixel column(width) 입니다. 

비틀즈 멤머 4명에 대해서 맨 왼쪽 부터 opencv dnn으로 검출된 left, top, right, bottom을 보면, 

맨 왼쪽: 46 261 210 565 두번째: 225 260 375 544 세번째: 385 278 558 560

맨 오른쪽: 555 259 725 585

이므로, 높이(y좌표계) * 너비(x좌표계) 인 이미지상에서 좌상단 x, y좌표(left, top), 우하단 x,y 좌표(right, bottom)을 잘 매핑하실 수 있을 것 입니다. 

 

 

 

이준우님의 프로필 이미지
이준우
질문자

아... 괄호가 빠졌었네요. 

cv2.rectangle(copy_img, (int(left), int(top)), (int(right), int(bottom)), color = blue_color, thickness=2) 로 넣어야 하는데

cv2.rectangle(copy_img, (int(left), int(top), int(right), int(bottom)), color = blue_color, thickness=2) 로 넣었네요.. 그래서 좌표가 안맞었네요..ㅠㅠ

 

((Xmin, Ymin), (Xmax, Ymax)) 꼴로 넣어야 했으나, ((Xmin, Ymin, Xmax, Ymax))로 넣어버렸네요. 

이상한 질문에 끝까지 답변 감사합니다. 

권 철민님의 프로필 이미지
권 철민
지식공유자

해결이 되었다니, 다행입니다. ^^

이준우님의 프로필 이미지
이준우

작성한 질문수

질문하기