General Object Detection Framework
- Region Proposal
- 이미지 안의 잠재적 객체 위치 식별
- 다양한 크기와 비율로 이미지 분할, 각 영역 평가
- 이 단계에서 R-CNN과 같은 방법 활용
- Feature Extraction and Network Predictions
- 영역 제안 후, 각 영역에서 특징 추출. 주로 CNN 사용
- 추출된 특징을 바탕으로 네트워크가 객체 클래스와 위치 예측
- Faster R-CNN, YOLO, SSD 등이 이 단계에서 사용
- Non-Maximum Suppression (NMS)
- 중복 영역 제안 중 최적 예측 선택
- 최대 점수 예측 유지, 중복 영역 제거
- 정확도 향상과 중복 감소에 중요
- Evaluation Metrics
- 객체 탐지 모델 성능 평가
- 정밀도, 재현율, F1 스코어 등을 주요 지표로 사용
- 클래스별 성능은 Average Precision(AP)으로 평가
Two-phase system: 특정 장소에 뭐가 있을것 같다 라고 먼저 생각 한 후에, Detect 한다. 즉, Region proposal 이후 Detectiong
Selective Search
- 이미지 내 객체 후보 영역 식별 방법
- 영역 제안에서 중요한 역할, 객체 탐지 성공률에 영향
Object-detector Evaluation Metrics
- Frames per Second (FPS)
- 탐지 속도 측정
- Mean Average Precision (mAP)
- 다양한 임계값에서 평균 정밀도 측정
- Intersection Over Union (IOU)
- 예측 및 실제 경계 상자의 겹침 정도 측정
R-CNN의 단점
- 객체 탐지 속도 느림
- 훈련 과정 여러 단계로 나뉨, SVM과 CNN 따로 훈련
- 훈련에 많은 시간과 공간 필요
Fast R-CNN
- Feature extractor 사용하여 특징 먼저 추출
- Selective Search 단점으로 속도 문제 지속
- RoI pooling 및 fully connected layers 통해 결과 도출
selective search를 먼저 한 후에 RoI 구함. 따라서 selective search 의 단점인 느림을 그대로 받음
Single-shot Detector (SSD)
- Selective Search 사용하지 않고, 객체 탐지 속도 향상에 초점
코드:
selective search를 이용하여 Object Detection을 위한 Region Proposal 영역을 도출
selectivesearch를 설치하고 이미지를 로드
1
!pip install selectivesearch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Collecting selectivesearch
Downloading selectivesearch-0.4.tar.gz (3.8 kB)
Preparing metadata (setup.py) ... [?25l[?25hdone
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from selectivesearch) (1.23.5)
Requirement already satisfied: scikit-image in /usr/local/lib/python3.10/dist-packages (from selectivesearch) (0.19.3)
Requirement already satisfied: scipy>=1.4.1 in /usr/local/lib/python3.10/dist-packages (from scikit-image->selectivesearch) (1.11.3)
Requirement already satisfied: networkx>=2.2 in /usr/local/lib/python3.10/dist-packages (from scikit-image->selectivesearch) (3.2.1)
Requirement already satisfied: pillow!=7.1.0,!=7.1.1,!=8.3.0,>=6.1.0 in /usr/local/lib/python3.10/dist-packages (from scikit-image->selectivesearch) (9.4.0)
Requirement already satisfied: imageio>=2.4.1 in /usr/local/lib/python3.10/dist-packages (from scikit-image->selectivesearch) (2.31.6)
Requirement already satisfied: tifffile>=2019.7.26 in /usr/local/lib/python3.10/dist-packages (from scikit-image->selectivesearch) (2023.9.26)
Requirement already satisfied: PyWavelets>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from scikit-image->selectivesearch) (1.4.1)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from scikit-image->selectivesearch) (23.2)
Building wheels for collected packages: selectivesearch
Building wheel for selectivesearch (setup.py) ... [?25l[?25hdone
Created wheel for selectivesearch: filename=selectivesearch-0.4-py3-none-any.whl size=4336 sha256=e6f172eb5b85bc058e17be8ebac6be3a86cf3dae8e9fe003c55568503d951cf9
Stored in directory: /root/.cache/pip/wheels/0e/49/95/01447a4e0f48a135ac91fbdb1dd2a1c0523e40e29957b383a3
Successfully built selectivesearch
Installing collected packages: selectivesearch
Successfully installed selectivesearch-0.4
1
2
!mkdir /content/data
!wget -O /content/data/audrey01.jpg https://raw.githubusercontent.com/chulminkw/DLCV/master/data/image/audrey01.jpg
1
2
3
4
5
6
7
8
9
10
--2023-11-19 20:07:49-- https://raw.githubusercontent.com/chulminkw/DLCV/master/data/image/audrey01.jpg
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 30102 (29K) [image/jpeg]
Saving to: ‘/content/data/audrey01.jpg’
/content/data/audre 100%[===================>] 29.40K --.-KB/s in 0.003s
2023-11-19 20:07:50 (8.75 MB/s) - ‘/content/data/audrey01.jpg’ saved [30102/30102]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import selectivesearch
import cv2
import matplotlib.pyplot as plt
import os
%matplotlib inline
### 오드리헵번 이미지를 cv2로 로드하고 matplotlib으로 시각화
img = cv2.imread('./data/audrey01.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
print('img shape:', img.shape)
plt.figure(figsize=(8, 8))
plt.imshow(img_rgb)
plt.show()
1
img shape: (450, 375, 3)
1
2
3
4
5
6
import selectivesearch
#selectivesearch.selective_search()는 이미지의 Region Proposal정보를 반환
_, regions = selectivesearch.selective_search(img_rgb, scale=100, min_size=2000)
print(type(regions), len(regions))
1
<class 'list'> 41
반환된 Region Proposal(후보 영역)에 대한 정보 보기.
반환된 regions 변수는 리스트 타입으로 세부 원소로 딕셔너리를 가지고 있음. 개별 딕셔너리내 KEY값별 의미
- rect 키값은 x,y 시작 좌표와 너비, 높이 값을 가지며 이 값이 Detected Object 후보를 나타내는 Bounding box임.
- size는 segment로 select된 Object의 크기
- labels는 해당 rect로 지정된 Bounding Box내에 있는 오브젝트들의 고유 ID
- 아래로 내려갈 수록 너비와 높이 값이 큰 Bounding box이며 하나의 Bounding box에 여러개의 오브젝트가 있을 확률이 커짐.
1
regions
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
[{'rect': (0, 0, 107, 167), 'size': 11166, 'labels': [0.0]},
{'rect': (15, 0, 129, 110), 'size': 8771, 'labels': [1.0]},
{'rect': (121, 0, 253, 133), 'size': 17442, 'labels': [2.0]},
{'rect': (134, 17, 73, 62), 'size': 2713, 'labels': [3.0]},
{'rect': (166, 23, 87, 176), 'size': 8639, 'labels': [4.0]},
{'rect': (136, 53, 88, 121), 'size': 4617, 'labels': [5.0]},
{'rect': (232, 79, 117, 147), 'size': 7701, 'labels': [6.0]},
{'rect': (50, 91, 133, 123), 'size': 7042, 'labels': [7.0]},
{'rect': (305, 97, 69, 283), 'size': 11373, 'labels': [8.0]},
{'rect': (0, 161, 70, 46), 'size': 2363, 'labels': [9.0]},
{'rect': (72, 171, 252, 222), 'size': 34467, 'labels': [10.0]},
{'rect': (0, 181, 118, 85), 'size': 5270, 'labels': [11.0]},
{'rect': (106, 210, 89, 101), 'size': 2868, 'labels': [12.0]},
{'rect': (302, 228, 66, 96), 'size': 2531, 'labels': [13.0]},
{'rect': (0, 253, 92, 134), 'size': 7207, 'labels': [14.0]},
{'rect': (153, 270, 173, 179), 'size': 10360, 'labels': [15.0]},
{'rect': (0, 305, 47, 139), 'size': 4994, 'labels': [16.0]},
{'rect': (104, 312, 80, 71), 'size': 3595, 'labels': [17.0]},
{'rect': (84, 360, 91, 67), 'size': 2762, 'labels': [18.0]},
{'rect': (0, 362, 171, 87), 'size': 7705, 'labels': [19.0]},
{'rect': (297, 364, 77, 85), 'size': 5164, 'labels': [20.0]},
{'rect': (0, 91, 183, 175), 'size': 12312, 'labels': [7.0, 11.0]},
{'rect': (136, 23, 117, 176), 'size': 13256, 'labels': [4.0, 5.0]},
{'rect': (72, 171, 254, 278), 'size': 44827, 'labels': [10.0, 15.0]},
{'rect': (134, 17, 119, 182), 'size': 15969, 'labels': [4.0, 5.0, 3.0]},
{'rect': (302, 97, 72, 283), 'size': 13904, 'labels': [8.0, 13.0]},
{'rect': (121, 0, 253, 226), 'size': 25143, 'labels': [2.0, 6.0]},
{'rect': (0, 91, 183, 175), 'size': 14675, 'labels': [7.0, 11.0, 9.0]},
{'rect': (0, 0, 144, 167), 'size': 19937, 'labels': [0.0, 1.0]},
{'rect': (0, 0, 253, 199),
'size': 35906,
'labels': [0.0, 1.0, 4.0, 5.0, 3.0]},
{'rect': (0, 253, 92, 191), 'size': 12201, 'labels': [14.0, 16.0]},
{'rect': (0, 91, 183, 353),
'size': 26876,
'labels': [14.0, 16.0, 7.0, 11.0, 9.0]},
{'rect': (0, 171, 326, 278), 'size': 52532, 'labels': [10.0, 15.0, 19.0]},
{'rect': (0, 97, 374, 352),
'size': 66436,
'labels': [10.0, 15.0, 19.0, 8.0, 13.0]},
{'rect': (84, 312, 100, 115), 'size': 6357, 'labels': [17.0, 18.0]},
{'rect': (0, 91, 184, 353),
'size': 33233,
'labels': [17.0, 18.0, 14.0, 16.0, 7.0, 11.0, 9.0]},
{'rect': (0, 91, 195, 353),
'size': 36101,
'labels': [17.0, 18.0, 14.0, 16.0, 7.0, 11.0, 9.0, 12.0]},
{'rect': (0, 0, 374, 444),
'size': 61244,
'labels': [17.0, 18.0, 14.0, 16.0, 7.0, 11.0, 9.0, 12.0, 2.0, 6.0]},
{'rect': (0, 0, 374, 449),
'size': 127680,
'labels': [17.0,
18.0,
14.0,
16.0,
7.0,
11.0,
9.0,
12.0,
2.0,
6.0,
10.0,
15.0,
19.0,
8.0,
13.0]},
{'rect': (0, 0, 374, 449),
'size': 132844,
'labels': [17.0,
18.0,
14.0,
16.0,
7.0,
11.0,
9.0,
12.0,
2.0,
6.0,
10.0,
15.0,
19.0,
8.0,
13.0,
20.0]},
{'rect': (0, 0, 374, 449),
'size': 168750,
'labels': [17.0,
18.0,
14.0,
16.0,
7.0,
11.0,
9.0,
12.0,
2.0,
6.0,
10.0,
15.0,
19.0,
8.0,
13.0,
20.0,
0.0,
1.0,
4.0,
5.0,
3.0]}]
1
2
3
# rect정보만 출력해서 보기
cand_rects = [cand['rect'] for cand in regions]
print(cand_rects)
1
[(0, 0, 107, 167), (15, 0, 129, 110), (121, 0, 253, 133), (134, 17, 73, 62), (166, 23, 87, 176), (136, 53, 88, 121), (232, 79, 117, 147), (50, 91, 133, 123), (305, 97, 69, 283), (0, 161, 70, 46), (72, 171, 252, 222), (0, 181, 118, 85), (106, 210, 89, 101), (302, 228, 66, 96), (0, 253, 92, 134), (153, 270, 173, 179), (0, 305, 47, 139), (104, 312, 80, 71), (84, 360, 91, 67), (0, 362, 171, 87), (297, 364, 77, 85), (0, 91, 183, 175), (136, 23, 117, 176), (72, 171, 254, 278), (134, 17, 119, 182), (302, 97, 72, 283), (121, 0, 253, 226), (0, 91, 183, 175), (0, 0, 144, 167), (0, 0, 253, 199), (0, 253, 92, 191), (0, 91, 183, 353), (0, 171, 326, 278), (0, 97, 374, 352), (84, 312, 100, 115), (0, 91, 184, 353), (0, 91, 195, 353), (0, 0, 374, 444), (0, 0, 374, 449), (0, 0, 374, 449), (0, 0, 374, 449)]
bounding box를 시각화 하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# opencv의 rectangle()을 이용하여 시각화
# rectangle()은 이미지와 좌상단 좌표, 우하단 좌표, box컬러색, 두께등을 인자로 입력하면 원본 이미지에 box를 그려줌.
green_rgb = (125, 255, 51)
img_rgb_copy = img_rgb.copy()
for rect in cand_rects:
left = rect[0]
top = rect[1]
# rect[2], rect[3]은 너비와 높이이므로 우하단 좌표를 구하기 위해 좌상단 좌표에 각각을 더함.
right = left + rect[2]
bottom = top + rect[3]
img_rgb_copy = cv2.rectangle(img_rgb_copy, (left, top), (right, bottom), color=green_rgb, thickness=2)
plt.figure(figsize=(8, 8))
plt.imshow(img_rgb_copy)
plt.show()
bounding box의 크기가 큰 후보만 추출
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cand_rects = [cand['rect'] for cand in regions if cand['size'] > 10000]
green_rgb = (125, 255, 51)
img_rgb_copy = img_rgb.copy()
for rect in cand_rects:
left = rect[0]
top = rect[1]
# rect[2], rect[3]은 너비와 높이이므로 우하단 좌표를 구하기 위해 좌상단 좌표에 각각을 더함.
right = left + rect[2]
bottom = top + rect[3]
img_rgb_copy = cv2.rectangle(img_rgb_copy, (left, top), (right, bottom), color=green_rgb, thickness=2)
plt.figure(figsize=(8, 8))
plt.imshow(img_rgb_copy)
plt.show()
IOU 구하기
입력인자로 후보 박스와 실제 박스를 받아서 IOU를 계산하는 함수 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
def compute_iou(cand_box, gt_box):
# Calculate intersection areas
x1 = np.maximum(cand_box[0], gt_box[0])
y1 = np.maximum(cand_box[1], gt_box[1])
x2 = np.minimum(cand_box[2], gt_box[2])
y2 = np.minimum(cand_box[3], gt_box[3])
intersection = np.maximum(x2 - x1, 0) * np.maximum(y2 - y1, 0)
cand_box_area = (cand_box[2] - cand_box[0]) * (cand_box[3] - cand_box[1])
gt_box_area = (gt_box[2] - gt_box[0]) * (gt_box[3] - gt_box[1])
union = cand_box_area + gt_box_area - intersection
iou = intersection / union
return iou
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# 실제 box(Ground Truth)의 좌표를 아래와 같다고 가정.
gt_box = [60, 15, 320, 420]
img = cv2.imread('./data/audrey01.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
red = (255, 0 , 0)
img_rgb = cv2.rectangle(img_rgb, (gt_box[0], gt_box[1]), (gt_box[2], gt_box[3]), color=red, thickness=2)
plt.figure(figsize=(8, 8))
plt.imshow(img_rgb)
plt.show()
1
2
3
4
5
6
7
8
import selectivesearch
#selectivesearch.selective_search()는 이미지의 Region Proposal정보를 반환
img = cv2.imread('./data/audrey01.jpg')
img_rgb2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
_, regions = selectivesearch.selective_search(img_rgb2, scale=100, min_size=2000)
print(type(regions), len(regions))
1
<class 'list'> 41
1
[cand['rect'] for cand in regions]
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
[(0, 0, 107, 167),
(15, 0, 129, 110),
(121, 0, 253, 133),
(134, 17, 73, 62),
(166, 23, 87, 176),
(136, 53, 88, 121),
(232, 79, 117, 147),
(50, 91, 133, 123),
(305, 97, 69, 283),
(0, 161, 70, 46),
(72, 171, 252, 222),
(0, 181, 118, 85),
(106, 210, 89, 101),
(302, 228, 66, 96),
(0, 253, 92, 134),
(153, 270, 173, 179),
(0, 305, 47, 139),
(104, 312, 80, 71),
(84, 360, 91, 67),
(0, 362, 171, 87),
(297, 364, 77, 85),
(0, 91, 183, 175),
(136, 23, 117, 176),
(72, 171, 254, 278),
(134, 17, 119, 182),
(302, 97, 72, 283),
(121, 0, 253, 226),
(0, 91, 183, 175),
(0, 0, 144, 167),
(0, 0, 253, 199),
(0, 253, 92, 191),
(0, 91, 183, 353),
(0, 171, 326, 278),
(0, 97, 374, 352),
(84, 312, 100, 115),
(0, 91, 184, 353),
(0, 91, 195, 353),
(0, 0, 374, 444),
(0, 0, 374, 449),
(0, 0, 374, 449),
(0, 0, 374, 449)]
1
2
3
4
5
6
7
8
cand_rects = [cand['rect'] for cand in regions]
for index, cand_box in enumerate(cand_rects):
cand_box = list(cand_box)
cand_box[2] += cand_box[0]
cand_box[3] += cand_box[1]
iou = compute_iou(cand_box, gt_box)
print('index:', index, "iou:", iou)
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
index: 0 iou: 0.06157293686705451
index: 1 iou: 0.07156308851224105
index: 2 iou: 0.2033654637255666
index: 3 iou: 0.04298195631528965
index: 4 iou: 0.14541310541310543
index: 5 iou: 0.10112060778727446
index: 6 iou: 0.11806905615946989
index: 7 iou: 0.1420163334272036
index: 8 iou: 0.035204259342190375
index: 9 iou: 0.004256894317971497
index: 10 iou: 0.5184766640298338
index: 11 iou: 0.04465579710144928
index: 12 iou: 0.0853656220322887
index: 13 iou: 0.015722240419259743
index: 14 iou: 0.037833068643021
index: 15 iou: 0.22523535071077264
index: 16 iou: 0.0
index: 17 iou: 0.053941120607787274
index: 18 iou: 0.05154006626579948
index: 19 iou: 0.05660327592118798
index: 20 iou: 0.01165009904393209
index: 21 iou: 0.18588082901554404
index: 22 iou: 0.19555555555555557
index: 23 iou: 0.5409250175192712
index: 24 iou: 0.205679012345679
index: 25 iou: 0.042245111210628454
index: 26 iou: 0.34848824374009246
index: 27 iou: 0.18588082901554404
index: 28 iou: 0.10952135872362326
index: 29 iou: 0.29560078245307364
index: 30 iou: 0.045470015655843715
index: 31 iou: 0.3126506582607083
index: 32 iou: 0.4934902582553282
index: 33 iou: 0.5490037131949166
index: 34 iou: 0.1018867924528302
index: 35 iou: 0.31513409961685823
index: 36 iou: 0.3423913043478261
index: 37 iou: 0.6341234282410753
index: 38 iou: 0.6270619201314865
index: 39 iou: 0.6270619201314865
index: 40 iou: 0.6270619201314865
1
2
3
cand_rects = [cand['rect'] for cand in regions if cand['size'] > 5000]
cand_rects.sort()
cand_rects
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
[(0, 0, 107, 167),
(0, 0, 144, 167),
(0, 0, 253, 199),
(0, 0, 374, 444),
(0, 0, 374, 449),
(0, 0, 374, 449),
(0, 0, 374, 449),
(0, 91, 183, 175),
(0, 91, 183, 175),
(0, 91, 183, 353),
(0, 91, 184, 353),
(0, 91, 195, 353),
(0, 97, 374, 352),
(0, 171, 326, 278),
(0, 181, 118, 85),
(0, 253, 92, 134),
(0, 253, 92, 191),
(0, 362, 171, 87),
(15, 0, 129, 110),
(50, 91, 133, 123),
(72, 171, 252, 222),
(72, 171, 254, 278),
(84, 312, 100, 115),
(121, 0, 253, 133),
(121, 0, 253, 226),
(134, 17, 119, 182),
(136, 23, 117, 176),
(153, 270, 173, 179),
(166, 23, 87, 176),
(232, 79, 117, 147),
(297, 364, 77, 85),
(302, 97, 72, 283),
(305, 97, 69, 283)]
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
img = cv2.imread('./data/audrey01.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
print('img shape:', img.shape)
green_rgb = (125, 255, 51)
cand_rects = [cand['rect'] for cand in regions if cand['size'] > 3000]
gt_box = [60, 15, 320, 420]
img_rgb = cv2.rectangle(img_rgb, (gt_box[0], gt_box[1]), (gt_box[2], gt_box[3]), color=red, thickness=2)
for index, cand_box in enumerate(cand_rects):
cand_box = list(cand_box)
cand_box[2] += cand_box[0]
cand_box[3] += cand_box[1]
iou = compute_iou(cand_box, gt_box)
if iou > 0.5:
print('index:', index, "iou:", iou, 'rectangle:',(cand_box[0], cand_box[1], cand_box[2], cand_box[3]) )
cv2.rectangle(img_rgb, (cand_box[0], cand_box[1]), (cand_box[2], cand_box[3]), color=green_rgb, thickness=1)
text = "{}: {:.2f}".format(index, iou)
cv2.putText(img_rgb, text, (cand_box[0]+ 100, cand_box[1]+10), cv2.FONT_HERSHEY_SIMPLEX, 0.4, color=green_rgb, thickness=1)
plt.figure(figsize=(12, 12))
plt.imshow(img_rgb)
plt.show()
1
2
3
4
5
6
7
8
img shape: (450, 375, 3)
index: 8 iou: 0.5184766640298338 rectangle: (72, 171, 324, 393)
index: 18 iou: 0.5409250175192712 rectangle: (72, 171, 326, 449)
index: 28 iou: 0.5490037131949166 rectangle: (0, 97, 374, 449)
index: 32 iou: 0.6341234282410753 rectangle: (0, 0, 374, 444)
index: 33 iou: 0.6270619201314865 rectangle: (0, 0, 374, 449)
index: 34 iou: 0.6270619201314865 rectangle: (0, 0, 374, 449)
index: 35 iou: 0.6270619201314865 rectangle: (0, 0, 374, 449)
R-CNN, Fast R-CNN, Faster R-CNN 비교
- R-CNN (Region-based CNN)
- 첫 번째 단계에서 Selective Search를 사용하여 잠재적인 객체 영역을 식별
- 각 영역에 대해 별도로 CNN을 통해 특징을 추출하고, 이후 SVM을 사용하여 객체를 분류
- 각 영역 제안에 대해 별도의 특징 추출이 필요하므로 속도가 느리다
- 훈련 과정이 여러 단계로 나뉘어 있어 시간과 자원이 많이 필요
- Fast R-CNN
- 전체 이미지에 대해 단 한 번의 특징 추출을 수행하고, RoI Pooling Layer를 사용하여 각 영역 제안에 대한 특징을 추출
- 더 빠른 처리 속도를 제공하며, 특징 추출 과정의 중복을 줄인다
- 하나의 네트워크에서 객체 분류와 경계 상자 회귀를 동시에 수행
- Selective Search를 사용하여 영역 제안을 생성하므로 여전히 일부 속도 제약 존재
- Faster R-CNN
- Fast R-CNN의 기본 구조를 유지하면서, Selective Search 대신 Region Proposal Network(RPN)을 도입하여 영역 제안을 자동화
- RPN은 객체의 위치와 크기에 대한 정보를 제공하여 영역 제안을 더 빠르고 정확하게 생성
- 전체 파이프라인이 하나의 네트워크로 통합되어 훈련과 추론이 더욱 효율적
- 객체 탐지 속도와 정확도 모두에서 크게 향상된 성능을 제공
selective search가 궁금하다면 https://github.com/AlpacaTechJP/selectivesearch/blob/develop/selectivesearch/selectivesearch.py