Trash detection by Blob detection
개발 일지 2019. 10. 14. 00:32 |-Blob
Blob이란, Binary Large Object의 줄임말로, 같은 성질을 가지는 픽셀들이 연결되어있는 작은 집합이라고 할 수 있다.
사실 쓰레기 디텍션을 하기 위해서는 여러가지 방법이 있다.
1. SVM으로 여러 쓰레기를 학습시키기
-> 이 방법은 확실하지만, 달리는 차에서 쓰레기를 버리는 경우 쓰레기의 형태가 불분명하고 사용자마다 버리는 쓰레기가 천차만별이기 때문에 특정한 쓰레기를 버릴 것이라고 예측할 수는 없다. 또한 쓰레기 데이터셋이 그렇게 많지 않다.
2. 색깔로 쓰레기 디텍션 + 트래킹
-> 알다시피 쓰레기 색깔이 천차만별이라서 불가능하다.
3. Blob 검출
-> 쓰레기는 일정한 크기를 띌 것이고 쓰레기가 날라가는 모습을 blob으로 검출해보면 어떨까했다. 다만 담배꽁초처럼 매우 작은 쓰레기는 힘들 것이다
Blob검출은 매우 간단하다. OpenCV에 내장된 함수인 SimpleBlobDetector를 쓰면 된다.
그러나 도로 위는 다양한 환경/배경이기 때문에 잘 검출할 수 있게 전처리가 필요했다.
- Image preprocessing
1. Background Subtraction
배경제거는 매우 간단한 원리이다
말그대로 물체가 나타나기 전의 배경을 기억한 후에 현재 프레임에서 빼면된다.
그러면 배경만 사라지는 것이다
나는 MOG알고리즘을 이용한 createBackgroundSubtractorMOG2()라는 opencv 내장함수를 사용했다.
이 알고리즘은 Mixture Of Gaussian 기반이고, 각 픽셀에 적절한 가우시안 분포값을 선택한다는 것이다.
이 알고리즘의 특징은 조명 상태의 변화로 장면이 변하더라도 제대로 배경제거를 해준다고 한다.
그리고 그림자검출을 할지말지 선택할 수 있다(파라미터 detectShadow = True가 디폴트)
(우리 실험에서는 쓰레기의 크기가 워낙 작기때문에, 그림자를 제거하면 쓰레기의 크기도 줄어들수 있어서 일단 True로 하였다.)
이외에도 createBackgroundSubtractorGMG 가 있다.
2. Mathmatical Morphology : Erosion, Dilation, Opening, Closing
배경을 제거하고 나면 노이즈가 있을 수 있기 때문에 노이즈제거작업이 필요하다.
모폴로지 연산은 움직이는 객체 내부에서 움직이는 부분의 사전 정보를 사용하게 도와준다.
모폴로지 연산은 크게 두개의 인풋이 필요하다. 첫번째는 우리의 이미지, 두번째는 연산의 특성을 결정할 structuring element or kernel이다.
참고: https://docs.opencv.org/3.1.0/d9/d61/tutorial_py_morphological_ops.html
-erode(침식), dilate(팽창)
erode는 모래사장에서 모래가 물에 조금씩 쓸려가서 침식되는 듯한 모습에서 따온 것이다.
커널이 이미지를 통과하면서 커널 밑에 있는 모든 픽셀이 1일때만 1로 간주하고 그거 외에는 다 0으로 만든다.
dilate는 erode의 반대이다. 커널밑에 있는 픽셀 중 적어도 하나가 1이라면 1로 간주한다.
보통 노이즈 제거시에는 erosion->dilation순서로 진행한다. 그 이유는 먼저 작은 노이즈들을 erode하고 우리가 살리고 싶은 객체를 dilate시켜줘야 하기 때문이다.
-opening, closing
opening은 erosion -> dilation 순서로 실행한 것이다. 노이즈 제거 시 유용하다.
closing은 dilation-> erosion 순서로 실행한 것이다.
전경에서 작은 검은 구멍들이 있을때 없애주기에 좋다.
3. Thresholding
Thresholding이란, 말그대로 임계값 가지고 필터링을 하는 작업이다.
즉, 픽셀값이 어떤 임계값보다 크면 a Value로 표현하고, 작으면 another Value으로 표현한다.
이때 이미지는 grayscale이여야 한다.
cv2.threshold(img, 50, 255, cv2.THRESH_BINARY_INV)
내가 썼던 함수를 기반으로 파라미터를 설명하겠다.
먼저 grayscale의 이미지 img를 가지고,
50이라는 임계값을 기준으로
임계값보다 클 경우, 255(white)로 표현하게 한다. 즉 여기서는 하얀색으로 표현한다는 뜻.
그리고 마지막파라미터는
cv2.THRESH_BINARY, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO 등의 여러 옵션을 선택할 수 있는데
내가 선택한 옵션은 바로 흑백을 바꾸는 옵션이다.
이와 같은 옵션을 선택한 이유는 하얀색의 blob(=쓰레기)을 잡아내게 하기 위해서이다.
일단적인 THRESH_BINARY를 쓰면 검은색 blob을 잡아냄.
- Blob Detection
위에서 언급한 SimpleBlobDetector를 이용하여 블롭 검출을 함.
다만 쓰레기만 잡아내게 하기 위해서 parameter를 수정하였는데 그 내용은 다음과 같다.
params = cv2.SimpleBlobDetector_Params()
#블롭으로 간주할 색상의 범위 설정
params.minThreshold = 50;
params.maxThreshold = 255;
# 블롭의 크기로 필터링할것인지 설정, 블롭으로 간주하고 싶은 크기 지정.(쓰레기라서 좀 크게 잡음)
params.filterByArea = True
params.minArea = 300
params.maxArea = 1000
#Circularity(둥근정도) filter
params.filterByCircularity = False
#Convexity(오목한지의 정도) filter
params.filterByConvexity = False
#Inertia filter(폭이 좁고 길쭉한지의 정도?)
params.filterByInertia = False
이를 돌린 결과는 다음과 같다.
*tiny YOLO 사용, threshold = 1.0 -> 1.5로 바꿈(이유: too many detected rectangles)
rectangle color : blue -> white 바꿈 (이유: grayscale 및 binary image에서 잘보이게 하려고)
발전해야할 방향:
1. blob의 중심좌표와 rectangle의 좌표를 얻어내서 어떤 상황이 쓰레기가 차에서 튀어나오는 것인지 판단해야하는 알고리즘
2. 자동차의 rectangle이 카메라 진동때문에 있었다 없었다 하는데 이를 개선할 방법은?
3. 쓰레기가 만약 블롭으로 검출되지않을 여러 경우를 고려해봐야함.
'개발 일지' 카테고리의 다른 글
[Trash Detection] 쓰레기 인식 설계 (0) | 2019.11.05 |
---|---|
[Trash Detection] 쓰레기의 움직임을 이용한 쓰레기 인식 (0) | 2019.10.20 |
[Vehicle Detection] 알고리즘별 성능 비교 (0) | 2019.10.06 |
[Vehicle Detection] HOG Descriptor + SVM (0) | 2019.10.05 |
Car detection - YOLO (0) | 2019.10.05 |