Morphology & Connected Components 실습

Stella Kim·2021년 7월 17일
0

Image Processing

목록 보기
4/8
post-thumbnail

동전 검출하기

불균일한 조명에서 촬영한 영상에서 임계화 연산을 사용하여 동전 영역만을 분리하여 연결 요소를 생성한다.

해결 과정 및 주요 코드에 대한 설명

def findContours(img):
	kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))

	img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
	img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

	(contours, hierarchy) = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)

	for i in range(0, len(contours)):
		cntr = sorted(contours, key=cv2.contourArea, reverse=True)[i]
		cv2.drawContours(img, [cntr], 0, (255, 255, 255), -1)

	seed(9001)
	for i in range(0, len(contours)):
		cntr = sorted(contours, key=cv2.contourArea, reverse=True)[i]
		r = randint(0, 256)
		g = randint(0, 256)
		b = randint(0, 256)
		cv2.drawContours(img, [cntr], 0, (b, g, r), 1)
	return img, contours

여러 전처리 과정을 거친 후 실행되는 findContours 함수이다. 먼저, 구조적 요소를 생성해주는데, 크기는 (3, 3)으로 해주었다. 이후 모폴로지의 열림 연산을 먼저 실행해준 후, 닫힘 연산을 적용했다. cv2.findContours 부분에서는 외곽선 검색 모드는 연결요소의 가장 바깥쪽 외곽선만 추출할 수 있도록 cv2.RETR_EXTERNAL로 설정해주었고, 외곽선 근사화 방법은 기존 값인 cv2.CHAIN_APPROX_SIMPLE이 아닌 cv2.CHAIN_APPROX_TC89_L1로 해주었다. 이후 sorted 함수를 사용하여 생성해낸 contours를 drawContours를 사용하여 나타낼 수 있도록 하였다. 이때 내부를 모두 채울 수 있도록 thickness 값은 음수인 –1로 주었다.

ap = argparse.ArgumentParser()
ap.add_argument('-i', '--image', required = True, \
			help = 'Path to the input image')
args = vars(ap.parse_args())

filename = args['image']

i로 동전 영상의 경로를 입력받는다. 받아온 값은 filename 변수에 저장한다.

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
	gray = cv2.GaussianBlur(gray, (5, 5), 0)
	th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 31, 1)

첫 부분에 설명한 findContours를 호출하기 전 필요한 전처리 과정들을 나열했다. 먼저, 컬러 영상을 그레이 스케일 영상으로 변환하고 여기에 (5, 5) 커널 사이즈로 가우시안 블러링을 수행하였다. 이후 adaptiveThreshold를 사용해 적응적 임계화를 수행하고자 하였다. AdaptiveMethod의 경우, MEAN 방법과 GAUSSIAN 방법 모두 시도해보았을 때, MEAN의 성능이 더 좋다고 판단하여 이를 인자값으로 넘겨주었다. 여러 블록 사이즈를 시도해본 결과, 31일 때 모든 동전을 검출해낼 수 있었기에 31로 인자값을 설정해주었다. ThresholdType은 cv2.THRESH_BINARY_INV로 설정해주었다.

실행 결과

  • python extract_coins.py --image ../images/coins.jpg 으로 명령을 주었을 경우

    BGR 타입의 동전 영상을 입력으로 준 뒤, pyplot 라이브러리를 사용하여 원하는 대로 화면상으로 결과물을 출력할 수 있었다.

코드

자세한 코드는 Github에서 확인할 수 있다.

움직이는 객체 검출하기

객체의 색과는 무관하게 움직임을 판단하여 배경으로부터 움직이는 객체를 검출한 후 연결 요소를 생성한다.

해결 과정 및 주요 코드에 대한 설명

def movingObjectsDetect(img):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))

    img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
    img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

    (contours, hierarchy) = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    seed(9001)
    img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    for (i, c) in enumerate(contours):
        r = randint(0, 256)
        g = randint(0, 256)
        b = randint(0, 256)
        cv2.drawContours(img, [c], 0, (b, g, r), -1)

    return img

실습 5의 첫 번째 실습과 마찬가지로 먼저 구조적 요소를 생성해주는데, 크기는 (3, 3)으로 해주었다. 이후 모폴로지의 열림 연산을 먼저 실행해준 후, 닫힘 연산을 적용했다. cv2.findContours 부분에서는 외곽선 검색 모드는 연결요소의 가장 바깥쪽 외곽선만 추출할 수 있도록 cv2.RETR_EXTERNAL로 설정해주었고, 외곽선 근사화 방법은 cv2.CHAIN_APPROX_TC89_L1로 해주었다. 이후 object마다 무작위한 색으로 안을 채워서 외곽선을 그릴 수 있도록 random을 사용하여 임의의 r, g, b 값을 생성해 drawContours 해주었다.

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", required=False, \
                    help="path to the video file")
args = vars(ap.parse_args())

fvideo = args.get("video")

v로 영상의 경로를 입력받는다. 받아온 값은 fvideo 변수에 저장한다. 만약 아무런 값도 입력받지 않았을 경우에는 웹캡을 입력으로 하여 프로그램을 실행한다.

model = cv2.createBackgroundSubtractorMOG2(varThreshold=100)

while True:
    (retval, frame) = camera.read()
    fgmask  = model.apply(frame)

배경 모델을 생성하기 위하여 createBackgroundSubtractorMOG2 함수를 사용하였다. 선택적으로 3개의 인자값을 넣을 수 있는데, 일단은 varThreshold 값만 지정했고, 이는 100으로 설정하였다. 이후 생성한 배경 모델을 사용해서 이를 첫 부분에 설명한 movingObjectDetect의 입력 값으로 넣어 움직이는 객체를 검출할 수 있도록 하였다.

실행 결과

  • python extract_moving_objects.py --video ../videos/vtest.avi 으로 명령을 주었을 경우

    영상을 입력으로 주었을 때 객체마다 랜덤한 색깔로 무난히 검출됨을 확인할 수 있었다.

  • python extract_moving_objects.py 으로 명령을 주었을 경우

    웹캠을 입력값으로 설정하여 텀블러를 흔들어 본 결과 텀블러에 해당하는 객체는 연두색에 가까운 색으로 검출되었고, 이 외에 사람의 형체나 기타 자그마한 객체들도 다양한 색으로 검출되었다.

코드

자세한 코드는 Github에서 확인할 수 있다.

profile
취업 준비 용으로 사용했던 기술 블로그입니다. 이제는 업로드 거의 안 할지도..

0개의 댓글