2012-04-20 10 views
7

현재 이미지 처리 프로젝트를 진행 중입니다. 저는 VC++에서 Opencv2.3.1을 사용하고 있습니다. 필자는 입력 이미지가 파란색으로 만 필터링되고 이진 이미지로 변환되도록 코드를 작성했습니다. 바이너리 이미지에는 원하지 않는 작은 오브젝트가 있습니다. 그 작은 객체를 제거하고 싶었 기 때문에 openCV의 cvFindContours() 메서드를 사용하여 이진 이미지의 윤곽선을 감지했습니다. 하지만 문제는 이미지 출력에서 ​​작은 객체를 제거 할 수 없다는 것입니다. cvContourArea() 기능을 사용했지만 제대로 작동하지 않았습니다 .. 침식 기능도 제대로 작동하지 않았습니다.Contours opencv : 이진 이미지에서 작은 윤곽을 제거하는 방법

그래서 누군가가 ..이 문제 좀 도와주세요

내가을 얻은 바이너리 이미지 :

enter image description here

내가이 가져올 결과/출력 이미지 :

enter image description here

답변

1

작은 등고선 영역으로 필터링이 제대로 작동하지 않습니까? 그것은 항상 나를 위해 일했습니다. 코드를 볼 수 있습니까?

또한 언급 된 바와 같이, 거의 보존하기 위해 부식과 확장을 모두 사용하는 것이 좋습니다. 소음이 적은 비트를 제거하려면 먼저 침식을 사용하고 구멍을 채우려면 먼저 팽창을 사용하십시오. 당신이 (findContours에 대한 documentation) 이미 알고 아니었다면

그리고 또 옆으로 새 C++ cv * 기능의 버전을 체크 아웃 할 수 있습니다. 제 의견으로는 사용하기가 훨씬 쉽습니다.

+0

제안 해 주셔서 감사합니다. 그러나 발견 된 각 얼룩/등고선의 영역을 찾는 코드를 작성하는 방법에 익숙하지 않습니다. 필자가 작성한 코드는 다음 링크에 있습니다. 제발 그것을 수정하고 회신 해주십시오. http://textuploader.com/?p=6&id=YwRl. –

+0

오! 방금 잊어 버린 cvutility 헤더와 cpp 파일은 다음 링크에서 찾을 수 있습니다. http : //textuploader.com/? p = 6 & id = Dtnvj http://textuploader.com/?p=6&id=TSlRQ 소스 디렉토리 및 포함 경로. –

+0

저는 C API에 익숙하지 않지만 첫 번째 컨투어의 면적을 계산하는 것처럼 보입니다. 윤곽선을 따라 반복하고 영역> 약간 임계 값으로 그려야합니다. 하나의 오브젝트를 찾으려는 경우 가장 큰 영역으로 윤곽선을 그려야합니다. – fferen

0

이전 및 이후 이미지로 판단 할 때 모든 흰색 영역 또는 얼룩의 영역을 결정한 다음 임계 영역 값을 적용해야합니다. 이렇게하면 모든 영역이 값보다 작아지고 두 번째 이미지에서 보이는 큰 흰색 영역 만 남게됩니다. cvFindContours 함수를 사용한 후에는 0 차 모멘트를 사용해보십시오. 이렇게하면 이미지의 얼룩 영역이 반환됩니다. 이 링크는 방금 설명한 내용을 구현하는 데 도움이 될 수 있습니다. 좋아 http://www.aishack.in/2010/07/tracking-colored-objects-in-opencv/

+0

제안에 감사드립니다. 그러나 Iam은 발견 된 각 얼룩이나 윤곽의 영역을 찾기 위해 코드를 작성하는 방법에 익숙하지 않습니다. –

+0

제안을 주셔서 감사합니다. 그러나 발견 된 각 얼룩/윤곽선의 영역을 찾는 코드를 작성하는 방법에 익숙하지 않습니다. 필자가 작성한 코드는 다음 링크에 있습니다. 제발 그것을 수정하고 회신 해주십시오. http://textuploader.com/?p=6&id=YwRl. –

+0

오! 방금 잊어 버린 cvutility 헤더와 cpp 파일은 다음 링크에서 찾을 수 있습니다. http : //textuploader.com/? p = 6 & id = Dtnvj http://textuploader.com/?p=6&id=TSlRQ 소스 디렉토리 및 포함 경로. –

10

, 나는 당신의 문제 최근 OpenCV의 도입 the bounding box demo 해결 될 수 있으리라 생각합니다. 당신은 아마다시피 가장 큰 사각형을 그림에 그려 내부

enter image description here

, 당신이에 관심이있는 개체가 있어야합니다. 다행히도이 코드는 그리 복잡하지 않으며 조사하고 실험함으로써 완전히 이해할 수 있습니다.

+0

thnx .. 나는 그것을 조사 할 것이다. –

7

다음은 작은 윤곽선을 제거하는 방법입니다. 기본 아이디어는 각 등고선의 길이/면적을 확인한 다음 벡터 컨테이너에서 더 작은 것을 삭제하는 것입니다.

일반적으로는, 사용자가 윤곽 세그먼트를 얻을 것이다 캐니() 전처리와이

Mat canny_output; //example from OpenCV Tutorial 
vector<vector<Point> > contours; 
vector<Vec4i> hierarchy; 
Canny(src_img, canny_output, thresh, thresh*2, 3);//with or without, explained later. 
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0)); 

같은 윤곽을 얻을 그러나, 각 세그먼트는 폐쇄 고리로서 경계점에 저장된다.이 경우,이 길이를 확인하고 검소한() 전처리없이

for (vector<vector<Point> >::iterator it = contours.begin(); it!=contours.end();) 
{ 
    if (it->size()<contour_length_threshold) 
     it=contours.erase(it); 
    else 
     ++it; 
} 

같은 작은 하나를 삭제할 수 있습니다, 당신은 객체의 윤곽을 얻을 것이다. 유사성은 또한

vector<Point> contour = contours[i]; 
double area0 = contourArea(contour); 

이 contourArea (도시 OpenCV의 튜토리얼) 비 제로 픽셀 수이기 때문에, 작은 물체를 제거하기 위해 임계 값을 정의하는 영역을 사용할 수 있습니다 당신이 형태 학적 사용할 수 있다고 생각

0

침식 및 팽창과 같은 연산자 (자세한 내용은 here을 참조하십시오.)

오른쪽에있는 원의 반지름 (제거하려는 것)에 가까운 커널 크기로 침식을 수행해야합니다. 을 사용하여 침식 단계에 의해 생성 된 갭을 채우기 위해 동일한 커널을 사용하여 팽창시켰다.

동일한 커널을 사용하여 팽창시킨 후의 팽창을 여는 (opening)이라고합니다.

코드 그것은 빠른 방법이 아니다이

int erosion_size = 30; // adjust with you application 
Mat erode_element = getStructuringElement(MORPH_ELLIPSE, 
         Size(2*erosion_size + 1, 2*erosion_size+1), 
         Point(erosion_size, erosion_size)); 
erode(binary_img, binary_img, erode_element); 
dilate(binary_img, binary_img, erode_element); 
0

같은되지만 경우에 유용 할 수있다. OpenCVV 3.0 - connectedComponentsWithStats에 새로운 기능이 있습니다. 이를 통해 연결된 구성 요소의 영역을 확보하고 불필요한 요소를 제거 할 수 있습니다. 따라서 솔리드 서클과 동일한 경계 상자를 사용하여 구멍이있는 원을 쉽게 제거 할 수 있습니다.

관련 문제