영상을 편집하는데 opencv 만한 tool이 없죠.
영상 편집과 object detection를 동시에 할 순 없을까요?
오픈 cv에서는 이미 만들어진 detection모델들을 로드하여 사용할 수 있습니다.
이 글을 읽기 전 선수 지식 포스팅
1) detection 모델 load
어떤 프레임워크로 만들어진 모델이냐에 따라 사용방법은 조금씩 다른데요.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 1) detection 모델 load opencv에서 사용되는 다양한 프레임워크](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
기본적으로 첫 번째 인자에는 가중치 모델 파일 경로, 두 번째 인자에는 환경 파일(config파일)의 경로를 넣는 형태로 만들어집니다.
환경 파일은 모델을 어떻게 사용할지에 대한 가이드가 담겨 있는 파일입니다.
가중치 파일과 환경 파일은 어디에서 다운 받을 수 있을까요?
텐서플로우를 기준으로 설명드리겠습니다.
해당 링크에 접속하시고 스크롤을 조금 내리시면 모델별 weights와 config파일을 다운로드할 수 있는 표가 있습니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 1) detection 모델 load opencv에서 사용가능한 detection 모델](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
여러분이 원하는 파일을 다운로드하시면 됩니다.
파일 저장경로를 readNetFromTensorflow 함수 인자로 각각 넣어줍니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 1) detection 모델 load 파일경로를 입력하여 모델 초기화](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
2) 이미지 load
detection 모델에 이미지를 넣는 방법에 대해 알아보겠습니다.
초기화한 모델 객체 cv_net에는 setInput()이라는 메서드가 있는데요.
함수의 인자로 이미지를 넣어주면 됩니다.
특이한 점은 blobFromImage함수로 감싼 형태로 넣어주었다는 건데요.
blobFromImage 함수는 이미지의 크기나 색감 등을 조정하는 전처리 함수입니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 2) 이미지 load blobFromImage 함수로 이미지를 깜산형태](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
추가적으로 아래와 같이 이미지 사이즈를 변경할 수 있다는 점도 참고 바랍니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 2) 이미지 load 이미지 사이즈 고정 방법](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
swapRB기능을 굳이 왜 쓰는지 이해가 안 가시는 분들 위해 추가 설명을 하겠습니다.
opencv 를 이용하여 이미지를 읽어 결과를 출력해봅니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 2) 이미지 load cvtColor미적용](https://blog.kakaocdn.net/dn/c1PWlK/btrO9BRmieq/qQXY7cfM0nneXqxQ5hHDa0/img.png)
output:
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 2) 이미지 load bgr 이미지 output](https://blog.kakaocdn.net/dn/bQFMfM/btrO9ZyntZK/d1RhmiGU37I5fCt0BsHfT0/img.png)
output을 보면 색감이 이상한걸 알 수 있죠. opencv로 이미지를 읽으면 기본적으로 컬러를 bgr형태로 바꾸기 때문인데요.
출력 전 rgb형태로 변경해주는 작업을 필요로 합니다.
방법은 아래와 같습니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 2) 이미지 load cvtColor 함수 적용](https://blog.kakaocdn.net/dn/bHPZ85/btrPcWAfcg4/Cm7vlCXyDKctyNeHIDFU51/img.png)
output:
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 2) 이미지 load rgb이미지 output](https://blog.kakaocdn.net/dn/bBw7S4/btrPaLTyV5Q/kmUezKhNwCF5WeY3GHXyxK/img.png)
이러한 작업은 매번 하기 귀찮기 때문에 swapRB 인자에 True를 넣는 형태로 간단히 구현한 것입니다.
(cv2.dnn.blobFromImage함수에 대해 더 자세히 알고 싶은 분은 해당 글을 참고 바랍니다.)
3) 바운딩 박스 그리기
forward() 함수를 실행하면 output으로 4차원 행렬이 나옵니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 forward()함수 실행](https://blog.kakaocdn.net/dn/kMWoZ/btrPaIpmHSR/lGGTUDdLxWwD3xgtPymn61/img.png)
output:
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 4차원 행렬 output](https://blog.kakaocdn.net/dn/VFAus/btrO9zNFMis/KE3iKmXokF37KZY99gwnv1/img.png)
우리가 원하는 건 빨간색 사각형 부분입니다.
인덱싱을 통해 해당 부분만 읽어오도록 세팅을 해볼겁니다.
cv_out을 인덱싱하고 for 문을 돌리면 7개의 원소로 구성된 배열을 뽑아낼 수 있습니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 7개의 배열 추출](https://blog.kakaocdn.net/dn/biYfP7/btrPaHjH7jf/foa0SDAm2RNcT0kvcdNwN0/img.png)
배열의 첫 번째 인덱스는 class id를 의미하고, 두 번째 인덱스는 confidence score를 의미하는데요.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 배열 구성요소](https://blog.kakaocdn.net/dn/BiqMe/btrPcdIWSvR/F402Ivj4XMbUlSvuvdNEyK/img.png)
나머지 4개의 값은 바운딩 박스 좌표입니다.
좌상단 x, y좌표, 우하단 x, y좌표로 구성되어있습니다.
(바운딩 박스 그리는 것이 익숙하지 않은 분은 이 글을 읽고 와주시기 바랍니다.)
뽑은 값들은 인덱싱을 통해 더 세부적으로 값을 추출해줘야 합니다.
id값은 int형이어야 하니까 int로 타입을 변경해줍니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 인덱싱 및 타입변경](https://blog.kakaocdn.net/dn/bLrt4q/btrO9AeIfBI/UkmA1X5FqGTUBx0lpYBah1/img.png)
확신도가 높은 바운딩 박스만 그리기 위해 스코어가 0.5 이상인 것만 뽑겠다고 설정합니다.
(조건을 걸지 않으면 많은 바운딩 박스가 그려집니다. 그렇다면 그림을 그리는 의미가 없어질 테니까요.)
인덱싱을 통해 각각의 좌표값들을 할당해줍니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 각좌표값 추출](https://blog.kakaocdn.net/dn/cw2Y1P/btrPcdhTPqf/kFH80t2VF3auAgYFahXbS1/img.png)
끝인 것 같아 보이지만 파이썬 opencv에서 반환해준 좌표값은 값을 0~1 사이 값으로 스케일링한 값입니다.
다시 실제 이미지 크기로 원복 한 상태에서 크기를 산정해야 합니다.
해당 이미지의 크기를 구한 후
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 원본이미지 크기 추출](https://blog.kakaocdn.net/dn/c53uXP/btrO4pxIScR/3UU3cRJat3Qk2MJUKfdl60/img.png)
그 크기만큼 해당 좌표에 곱해줘야 합니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 원본크기로 복원](https://blog.kakaocdn.net/dn/bQ6SGr/btrPceOCp5N/uTPbVcN4KpBJkXFw50bpTk/img.png)
원본 이미지 자체에 바운딩박스를 그리면 원본 이미지가 훼손이 됩니다. 복사본을 생성하여 사용하는 걸 추천드립니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 복사이미지 생성](https://blog.kakaocdn.net/dn/owlDf/btrPbtrJRia/VqB5cxmRjAi2HrIYdFKMsk/img.png)
rectangle을 그려줍니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 rectangle그리기](https://blog.kakaocdn.net/dn/3dvVt/btrPbDubmGI/y535Q1HHl4hbbXyegmSXe0/img.png)
output:
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 바운딩박스 그려진 이미지](https://blog.kakaocdn.net/dn/mp4lG/btrPce2aGRP/ItSdQiKJxFVnC0eXLoQM3k/img.png)
아쉬운 점은 해당 객체가 어떤 라벨인지를 알 수 없다는 점인데요.
putText를 통하여 글자를 써줍니다.
(putText사용법이 낯선 분은 이 글을 참조하시기 바랍니다.)
현재 우리가 가지고 있는 정보는 class Id 밖에 없기 없습니다.
class id와 라벨 값이 매핑된 딕셔너리를 미리 준비합니다.
labels_to_names_0 = {0:'person',1:'bicycle',2:'car',3:'motorcycle',4:'airplane',5:'bus',6:'train',7:'truck',8:'boat',9:'traffic light',
10:'fire hydrant',11:'street sign',12:'stop sign',13:'parking meter',14:'bench',15:'bird',16:'cat',17:'dog',18:'horse',19:'sheep',
20:'cow',21:'elephant',22:'bear',23:'zebra',24:'giraffe',25:'hat',26:'backpack',27:'umbrella',28:'shoe',29:'eye glasses',
30:'handbag',31:'tie',32:'suitcase',33:'frisbee',34:'skis',35:'snowboard',36:'sports ball',37:'kite',38:'baseball bat',39:'baseball glove',
40:'skateboard',41:'surfboard',42:'tennis racket',43:'bottle',44:'plate',45:'wine glass',46:'cup',47:'fork',48:'knife',49:'spoon',
50:'bowl',51:'banana',52:'apple',53:'sandwich',54:'orange',55:'broccoli',56:'carrot',57:'hot dog',58:'pizza',59:'donut',
60:'cake',61:'chair',62:'couch',63:'potted plant',64:'bed',65:'mirror',66:'dining table',67:'window',68:'desk',69:'toilet',
70:'door',71:'tv',72:'laptop',73:'mouse',74:'remote',75:'keyboard',76:'cell phone',77:'microwave',78:'oven',79:'toaster',
80:'sink',81:'refrigerator',82:'blender',83:'book',84:'clock',85:'vase',86:'scissors',87:'teddy bear',88:'hair drier',89:'toothbrush',
90:'hair brush'}
class_id를 통해 각각의 라벨 값과 score를 caption변수에 담고, caption을 putText함수의 인자로 넣어줍니다.
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 putText함수실행](https://blog.kakaocdn.net/dn/bl73KA/btrPaHYkpbm/KFRHSvVgymmTReXbbwmwP0/img.png)
output:
![[파이썬 opencv] 오픈 cv에서 detection model 실행하는 방법 - 이 글을 읽기 전 선수 지식 포스팅 - 3) 바운딩 박스 그리기 최종결과](https://blog.kakaocdn.net/dn/dmo7ro/btrPbuEa8d2/3TmZwrMp74lR3NIP9FumQ0/img.png)
'머신러닝,딥러닝 > opencv' 카테고리의 다른 글
[파이썬 opencv] 오픈cv 를 통해 비디오(영상) 출력하는 방법 (0) | 2022.12.02 |
---|---|
[파이썬 opencv] 오픈 cv에서 yolov3 사용하는 방법 (2) | 2022.10.26 |
[오픈 cv] 트랙바란? 트랙바 사용방법(for opencv 초보자) (0) | 2022.09.14 |
[파이썬 opencv] 두 이미지 합치는 방법(with 크기 다른 이미지) (0) | 2022.09.13 |
[opencv] 그림 그리기 | 글자 쓰는 법 (+ 한글 사용 방법) (0) | 2022.09.06 |
댓글
꼬예님의
글이 좋았다면 응원을 보내주세요!
이 글이 도움이 됐다면, 응원 댓글을 써보세요. 블로거에게 지급되는 응원금은 새로운 창작의 큰 힘이 됩니다.
응원 댓글은 만 14세 이상 카카오계정 이용자라면 누구나 편하게 작성, 결제할 수 있습니다.
글 본문, 댓글 목록 등을 통해 응원한 팬과 응원 댓글, 응원금을 강조해 보여줍니다.
응원금은 앱에서는 인앱결제, 웹에서는 카카오페이 및 신용카드로 결제할 수 있습니다.