Program/OPEN_CV

[Open CV] 이진 영상 처리 _ 레이블링

사막여유 2022. 6. 9. 21:39
728x90

 

객체 단위 분석

 - 영상을 불러왔을 때 이진화하여 객체와 배경을 분리할 수 있다는 가정하에 원하는 모양과 크기를 구분하여
   추리고 싶을때 사용

 - ( 흰색 ) 객체를 분할하여 특징을 분석

 - 객체 위치 및 크기 정보, ROI 추출, 모양 분석등으로 사용됨

 

간략하게 설명하자면 

 

레이블링 ( Connected Component Labeling )

 - 서로 연결되어 있는 객체 픽셀에 고유한 번호를 지정 ( 레이블 맵 )

 - 영역 기반 모양 분석

 - 레이블맵 , 바운딩 박스, 픽셀 개수, 무게중심 좌표를 반환

 

외곽선 검출 ( Contour Tracing ) 

 - 각 객체의 외곽선 좌표를 모두 검출

 - 외곽선 기반 모양 분석

 - 다양한 외곽선 처리 함수에서 활용 가능 ( 근사화, 컨벡스헐 등 )
   * 컨벡스 헐 ( Convex Hull ) : 2차원 평면상에 점이 여러개가 있을 때 이 점들 중 일부를 골라서 만들 수 있는, 나머지 
                                                 점들을 모두 포함하는 블록다각형을 뜻함.

 

레이블링 ( Labeling ) 이란?

 - 동일 객체에 속한 모든 픽셀에 고유한 번호를 매기는 작업
    같은 객체에 속한 모든 픽셀에 같은 번호를 매김

 - 일반적으로 이진 영상에서 수행

 - OpenCV에는 3.x 버전부터 최신 논문 기반의 레이블링 알고리즘 함수를 제공
   3.x 버전 이전에는 외곽선검출을 통해서 객체단위 분석을 할 수 있었는데 현재는 레이블링 속도가
   외곽선 검출보다 더 빠르기 때문에 더 효율적이라고 볼 수 있다.

 - Connected component labeling 

픽셀의 연결 관계

 - 4-이웃 연결 관계 ( 4-neightbor connectivity )
   상하좌우의 관계로 연결되어있을때

 - 8-이웃 연결 관계 ( 8-neightbor connectivity )
   상하좌우 , 대각선 관계로 연결되어있을때 

 

 

실제 레이블링을 진행했을 때 의 결과영상을 보게 되면

 

실제 레이블링을 구현하려고하면 상당히 복잡하기때문에 직접 구현하는 것은 지양하는 것이 좋다.

 


레이블링 함수

cv2.connectedComponents ( image, labels, connectivity, ltype ) -> retval, lables

image : 8비트 1채널 영상

labels : 레이블 맵 행렬. 입력 영상과 같은 크기 ( numpy.ndarray )
            * 보통 이곳에 labels 는 넣지않고 출력으로 받음

connectivity : 4 또는8. 기본값은 8 ( 위 이웃 연결관계 )

ltype : labels 타입. cv2.CV_32S 또는 cv2.CV_16s. 기본값은 cv2.CV_32S.

retval : 객체 개수. N을 반환하면 [ 0, N-1] 의 레이블이 존재 하며, 0은 배경을 의미. ( 실제 흰색 객체 개수는 N-1개 )


cv2.connectedComponentsWithStats ( image, labels, stats, centroids, connectivity, ltype )
-> retval , labels, stats, centrodis

image : 8비트 1채널 영상

labels : 레이블 맵 행렬. 입력 영상과 같은 크기 ( numpy.ndarray )
            * 보통 이곳에 labels 는 넣지않고 출력으로 받음

stats : 각 객체의 바운딩 박스, 픽셀 개수 정보를 담은 행렬 ( 바운딩박스 : 어느위치에 어떤 크기로 존재하는지 )
           numpy.ndarray.shape = ( N, 5), dtype = numpy.int32.

centroids : 각 객체의 무게 중심 위치 정보를 담은 행렬
                  numpy.ndarray.shape = ( N, 2), dtype = numpy.float64

ltype : labels 타입. cv2.CV_32S 또는 cv2.CV_16s. 기본값은 cv2.CV_32S.


 

실제 2번째 함수인 connectedComponentsWithStats 를 많이 사용하는데 실제 객체가 어디에 있고 어떤 크기를 갖고 

있는지에 대한 정보를 반환해주기 때문이다.

위 함수의 결과를 보게되면 다음과 같은 결과를 얻을 수 있다.

 

 

stats 는 좌측 첫번째 좌표, w, h의 정보를 가진 바운딩 박스와 실제 픽셀이 얼마나 들어가있는지에 대한 면적 정보도같이 반환된다.그리고 centroids 는 객체의 x 또는 y 값 을 모두 더한 값의 평균이다.

 

 

키보드 이미지를 활용하여 객체를 찾아내 빨간 박스를 그리는 작업의 코딩이다.여기서 중요한 점은 x, y , w , h , area 의 정보를 한번에 추출하여 사용할 수 있다는 점과노이즈들을 제거하는 함수를 사용하지 않고 area 가 20픽셀보다 작으면 걸러낼 수 있어좀 더 효과적으로 사용할 수 있다는 것이다.실제 실행시켜 보게되면 

 

위와같은 영상을 얻을 수 있다.

 

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

https://bit.ly/3L3avNW

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

728x90