기존의 음식 분류 프로젝트에서 주제를 제품 분류 프로젝트로 변경했다.

그런데 복잡한 패턴이 있는 장소에서는 CNN 결과가 매우 낮게 나오는 현상이 발생했다.

 

이 문제를 해결하기 위한 방법으로 

객체가 있는 곳을 제외하고 나머지 배경을 제거하는 방법을 사용해보기로 했다.

코드는 stack overflow에서 참고했다.


소스 코드

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
BLUR = 21
CANNY_THRESH_1 = 18
CANNY_THRESH_2 = 28
MASK_DILATE_ITER = 2
MASK_ERODE_ITER = 2
MASK_COLOR = (0,0,1.0# In BGR format
 
 
img = cv2.imread('test_image6.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
 
edges = cv2.Canny(gray, CANNY_THRESH_1, CANNY_THRESH_2)
edges = cv2.dilate(edges, None)
edges = cv2.erode(edges, None)
 
contour_info = []
contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
 
for c in contours:
    contour_info.append((
        c,
        cv2.isContourConvex(c),
        cv2.contourArea(c),
    ))
 
contour_info = sorted(contour_info, key=lambda c: c[2], reverse=True)
max_contour = contour_info[0]
 
mask = np.zeros(edges.shape)
cv2.fillConvexPoly(mask, max_contour[0], (255))
 
mask = cv2.dilate(mask, None, iterations=MASK_DILATE_ITER)
mask = cv2.erode(mask, None, iterations=MASK_ERODE_ITER)
mask = cv2.GaussianBlur(mask, (BLUR, BLUR), 0)
mask_stack = np.dstack([mask]*3)
 
mask_stack  = mask_stack.astype('float32'/ 255.0
img         = img.astype('float32'/ 255.0
 
masked = (mask_stack * img) + ((1-mask_stack) * MASK_COLOR)
masked = (masked * 255).astype('uint8')
 
dst = cv2.resize(masked, dsize=(640480), interpolation=cv2.INTER_AREA)
cs

 

경계선을 찾는 방식인 Canny Edge를 사용해서 경계선을 찾고,

빈 mask를 만들어 윤곽선의 바깥을 채우는 방식으로 동작하는 것 같다.

CANNY_THRESH_1과 CANNY_THRESH_2의 값을 바꿔 임계치를 조정할 수 있다.

 

결과

 

결과

간단한 이미지는 잘 해주는 것 같았는데,

제품같이 복잡한 이미지가 있는 경우에는 잘 제거해주지 못한다.

그리고 이미지마다 경계값이 조금씩 달라서 여러장을 일괄적으로 제거하기에는 무리가 있다.

+ Recent posts