본문 바로가기

OpenCV

OpenCV 블롭 탐지 Python, C++

반응형

 

OpenCV의 Blob Detection(블롭 감지)은 이미지 내에서 **특정 속성(색상, 크기, 모양, 밝기 등)을 공유하는 연결된 픽셀들의 집합(블롭)**을 찾아내고 분리하는 컴퓨터 비전 기술입니다. 이 기술은 이미지에서 특정 객체를 식별하거나, 노이즈를 제거하고, 객체의 특징을 분석하는 등 다양한 응용 분야에 사용됩니다.  

 

주요 개념:
  • 블롭(Blob):
    이미지에서 연결된 픽셀들의 그룹으로, 동일한 또는 유사한 특징(예: 같은 색상, 비슷한 밝기 값)을 공유합니다. 
     
  • OpenCV:
    실시간 영상 처리에 중점을 둔 오픈 소스 컴퓨터 비전 라이브러리입니다. 
     
  • Threshoding(임계값 처리):
    블롭 감지의 첫 단계로, 이미지를 이진화하여 블롭을 더 쉽게 찾을 수 있도록 합니다. 
     
  • 연결된 픽셀 그룹화:
    이진화된 이미지에서 연결된 픽셀들을 하나의 블롭으로 묶습니다. 
     
  • 필터링:
    찾은 블롭들을 색상, 크기, 형태(원형도 등)와 같은 다양한 속성 기준으로 필터링하여 원하는 블롭만 추출합니다. 
     
사용되는 기술:
  • OpenCV는 SimpleBlobDetector라는 내장 함수를 제공하여 블롭을 효율적으로 감지합니다. 
     
  • 이 감지기는 이미지에서 정의된 속성에 따라 블롭을 식별하고, 해당 블롭의 중심 위치(x, y 좌표), 크기 등의 정보를 반환합니다. 
     
응용 분야:
  • 객체 추적:
    특정 색상의 공이나 물체를 감지하여 추적할 수 있습니다. 
     
  • 품질 검사:
    제품 이미지에서 불량이나 결함을 나타내는 블롭을 감지할 수 있습니다. 
     
  • 의료 영상 분석:
    세포나 핵과 같이 특정 형태의 구조물을 식별하는 데 활용될 수 있습니다

 

 

이 튜토리얼에서는 OpenCV를 사용하여 간단한 블롭 감지를 설명합니다.

 

블롭이란 무엇인가요?

 

블롭(Blob)은 이미지에서 공통적인 속성(예: 회색조 값)을 공유하는 연결된 픽셀들의 집합입니다. 위 이미지에서 어둡게 연결된 영역은 블롭이며, 블롭 감지는 이러한 영역을 식별하고 표시하는 것을 목표로 합니다.

 

 

 

 

 

 

SimpleBlobDetector 예제

 

OpenCV는 다양한 특성을 기반으로 블롭을 감지하고 필터링하는 편리한 방법을 제공합니다. 가장 간단한 예제부터 시작해 보겠습니다.

 

이 게시물은 OpenCV 4.2에서 테스트되었습니다.

 

파이썬

 

# Standard imports
import cv2
import numpy as np;
 
# Read image
im = cv2.imread("blob.jpg", cv2.IMREAD_GRAYSCALE)
 
# Set up the detector with default parameters.
detector = cv2.SimpleBlobDetector()
 
# Detect blobs.
keypoints = detector.detect(im)
 
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
 
# Show keypoints
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)

 

C++

 

using namespace cv;
// Read image
Mat im = imread( "blob.jpg", IMREAD_GRAYSCALE );
 
// Set up the detector with default parameters.
SimpleBlobDetector detector;
 
// Detect blobs.
std::vector<KeyPoint> keypoints;
detector.detect( im, keypoints);
 
// Draw detected blobs as red circles.
// DrawMatchesFlags::DRAW_RICH_KEYPOINTS flag ensures the size of the circle corresponds to the size of blob
Mat im_with_keypoints;
drawKeypoints( im, keypoints, im_with_keypoints, Scalar(0,0,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS );
 
// Show blobs
imshow("keypoints", im_with_keypoints );
waitKey(0);

 

블롭 감지는 어떻게 작동하나요?

 

이름에서 알 수 있듯이 SimpleBlobDetector는 아래에 설명된 간단한 알고리즘을 기반으로 합니다. 이 알고리즘은 매개변수(아래 굵게 표시)에 의해 제어되며 다음 단계로 구성됩니다. 매개변수 설정 방법을 알아보려면 아래로 스크롤하세요.

 

  1. 임계값 설정: minThreshold 부터 시작하여 임계값을 설정하여 소스 이미지를 여러 개의 이진 이미지로 변환합니다. 이 임계값은 maxThreshold 까지 thresholdStep 만큼 증가합니다 . 따라서 첫 번째 임계값은 minThreshold, 두 번째 임계값은 minThreshold + thresholdStep, 세 번째 임계값은 minThreshold + 2 x thresholdStep 등이 됩니다.
  2. 그룹화: 각 이진 이미지에서 연결된 흰색 픽셀은 그룹화됩니다. 이를 이진 블롭(binary blob)이라고 부르겠습니다.
  3. 병합 : 이진 이미지의 이진 블롭 중심을 계산하고, minDistBetweenBlobs 보다 가까운 블롭을 병합합니다.
  4. 중심 및 반지름 계산: 새로 병합된 블롭의 중심과 반지름을 계산하여 반환합니다.

 

색상, 크기 및 모양으로 Blob 필터링

 

SimpleBlobDetector의 매개변수를 설정하여 원하는 Blob 유형을 필터링할 수 있습니다.

 

1. 색상별: [참고: 이 기능은 작동하지 않는 것 같습니다. 코드를 확인했는데, 논리적 오류가 있는 것 같습니다.]

 

먼저, filterByColor = 1로 설정해야 합니다 . blobColor = 0으로 설정하면 더 어두운 얼룩이 선택되고, blobColor = 255로 설정하면 더 밝은 얼룩이 선택됩니다. 크기 기준: filterByArea 매개변수를 1로 설정하고 minArea 및 maxArea 에 적절한 값을 설정하여 크기를 기준으로 얼룩을 필터링할 수 있습니다 . 예를 들어 minArea = 100으로 설정하면 100픽셀 미만의 모든 얼룩이 필터링됩니다. 모양 기준: 이제 모양에는 세 가지 매개변수가 있습니다.

 

2. 원형성 :

 

이 함수는 블롭이 원에 얼마나 가까운지를 측정합니다. 예를 들어, 정육각형은 정사각형보다 원형도가 높습니다. 원형도를 기준으로 필터링하려면 filterByCircularity = 1로 설정합니다. 그런 다음 minCircularity 와 maxCircularity 에 적절한 값을 설정합니다 . 원형도는 다음과 같이 정의됩니다 .

 

 

즉, 원의 원형도는 1이고, 정사각형의 원형도는 0.785입니다.

 

3. 볼록성 :

 

그림은 천 마디 말보다 가치가 있습니다. 볼록성은 (블롭의 면적/볼록 껍질의 면적)으로 정의됩니다. 볼록 껍질은 모양을 완전히 감싸는 가장 조밀한 볼록 모양입니다. 볼록성을 기준으로 필터링하려면 filterByConvexity = 1 로 설정 한 다음 , 0 ≤ minConvexity ≤ 1, maxConvexity (≤ 1) 을 설정합니다.

 

4. 관성비 :

 

겁먹지 마세요. 수학자들은 매우 간단한 것을 설명할 때 종종 혼란스러운 용어를 사용합니다. 여러분이 알아야 할 것은 이것이 도형의 길이를 측정한다는 것입니다. 예를 들어 원의 경우 이 값은 1, 타원의 경우 0과 1 사이, 직선의 경우 0입니다. 관성비로 필터링하려면 filterByInertia = 1로 설정하고 , 0 ≤ minInertiaRatio ≤ 1, maxInertiaRatio (≤ 1)을 적절히 설정합니다.

 

SimpleBlobDetector 매개변수를 어떻게 설정하나요?

 

SimpleBlobDetector의 매개변수 설정은 쉽습니다. 다음은 예시입니다.

 

파이썬

 

# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()
 
# Change thresholds
params.minThreshold = 10;
params.maxThreshold = 200;
 
# Filter by Area.
params.filterByArea = True
params.minArea = 1500
 
# Filter by Circularity
params.filterByCircularity = True
params.minCircularity = 0.1
 
# Filter by Convexity
params.filterByConvexity = True
params.minConvexity = 0.87
 
# Filter by Inertia
params.filterByInertia = True
params.minInertiaRatio = 0.01
 
# Create a detector with the parameters
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
 detector = cv2.SimpleBlobDetector(params)
else : 
 detector = cv2.SimpleBlobDetector_create(params)

 

C++

 

 

OOpenCV 2에서 SimpleBlobDetector의 매개변수 설정은 OpenCV 3과 약간 다릅니다. 아래 코드에서는 매크로 CV_MAJOR_VERSION을 사용하여 OpenCV의 버전을 감지합니다. OpenCV 3에서는 스마트 포인터를 생성하기 위해 SimpleBlobDetector::create 메서드를 사용합니다. 사용법은 아래 코드에 나와 있습니다.

 

 

// Setup SimpleBlobDetector parameters.
SimpleBlobDetector::Params params;
 
// Change thresholds
params.minThreshold = 10;
params.maxThreshold = 200;
 
// Filter by Area.
params.filterByArea = true;
params.minArea = 1500;
 
// Filter by Circularity
params.filterByCircularity = true;
params.minCircularity = 0.1;
 
// Filter by Convexity
params.filterByConvexity = true;
params.minConvexity = 0.87;
 
// Filter by Inertia
params.filterByInertia = true;
params.minInertiaRatio = 0.01;
 
#if CV_MAJOR_VERSION < 3   // If you are using OpenCV 2
 
  // Set up detector with params
  SimpleBlobDetector detector(params);
 
  // You can use the detector this way
  // detector.detect( im, keypoints);
 
#else
 
  // Set up detector with params
  Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
 
  // SimpleBlobDetector::create creates a smart pointer. 
  // So you need to use arrow ( ->) instead of dot ( . )
  // detector->detect( im, keypoints);
 
#endif

 

 

 

테스트 영역, 임계값, 원형성, 관성, 볼록성(다양한 필터 매개변수)을 시각화한 이미지입니다.

 

 

 

반응형

캐어랩 고객 지원

취업, 창업의 막막함, 외주 관리, 제품 부재!

당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약, 아이디어는 있지만 구현할 기술이 없는 막막함.

우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.

이제 고민을 멈추고, 캐어랩을 만나세요!

코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.

제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!

귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.

지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.

카카오 채널 추가하기

카톡 채팅방에서 무엇이든 물어보세요

귀사가 성공하기까지의 긴 고난의 시간을 캐어랩과 함께 하세요.

캐어랩 온라인 채널 바로가기

캐어랩