C++에서 OpenCV 이미지 분할 과 분수령 알고리즘 실현

분수령 알고리즘 은 이미지 구역 분할 법 으로 분할 하 는 과정 에서 근접 픽 셀 간 의 유사 성 을 중요 한 참고 근거 로 삼 아 공간 위치 에서 비슷 하고 그 레이스 케 일 값 이 비슷 한 픽 셀 점 을 서로 연결 시 켜 폐쇄 적 인 윤곽 을 구성 하고 폐쇄 성 은 분수령 알고리즘 의 중요 한 특징 이다.
API 소개

void watershed( InputArray image, InputOutputArray markers );
매개 변수 설명:
이미지:8bit 3 채널 컬러 이미지 매트릭스 시퀀스 여야 합 니 다4.567917.markers:분수령 함수 watershed 를 실행 하기 전에 두 번 째 매개 변수 markers 를 처리 해 야 합 니 다.서로 다른 지역 의 윤곽 을 포함 하고 모든 윤곽 은 자신의 유일한 번호 가 있 습 니 다.윤곽 의 포 지 셔 닝 은 Opencv 에서 find Contours 방법 으로 이 루어 질 수 있 습 니 다.이것 은 분수령 을 실행 하기 전의 요구 입 니 다.알고리즘 은 markers 가 들 어 오 는 윤곽 에 따라 피 드(즉,주 수 점)로 이미지 의 다른 픽 셀 점 을 분수령 알고리즘 규칙 에 따라 판단 하고 각 픽 셀 점 의 구역 귀속 을 구분 하여 이미지 의 모든 픽 셀 점 을 처리 할 때 까지 합 니 다.한편,지역 과 지역 간 의 경계 에 있 는 값 은'-1'로 설정 되 어 구분 된다우 리 는 거리 변환 과 분수령 을 어떻게 사용 하여 서로 접촉 하 는 물 체 를 분할 하 는 예 를 들 것 이다.
아래 의 동전 그림 을 고려 해 보 세 요.이 동전 들 은 서로 접촉 합 니 다.설령 네가 그것 을 한도 값 화 하 더 라 도 그것 은 서로 만 질 것 이다.
CSDN图标
우 리 는 동전 의 대략적인 추정 치 를 찾 는 것 부터 시작 했다.이 를 위해 대진 의 이치 화 를 이용 할 수 있다.

#include<iostream>
#include<opencv2\opencv.hpp>

using namespace std;
using namespace cv;

int main() {
	Mat gray, thresh;
	Mat img = imread("coins.jpg");
	cvtColor(img, gray, COLOR_BGR2GRAY);
	threshold(gray, thresh, 0, 255, THRESH_BINARY_INV+CV_THRESH_OTSU);

	imshow("Otst    ", thresh);
	waitKey(0);
	return 0;
}
한도 값 후의 그림 은 다음 과 같다.
CSDN图标
지금 은 그림 속 의 작은 흰색 소음 을 제거 해 야 한다.이 를 위해,우 리 는 형태 로 조작 할 수 있다.물체 의 어떤 작은 구멍 도 제거 하기 위해 서 우 리 는 형태 폐 조작 을 사용 할 수 있다.그래서 지금 우리 가 확정 할 수 있 는 것 은 물체 중심 에 가 까 운 구역 은 전망 이 고 물체 와 멀리 떨 어 진 구역 은 배경 이다.우리 만 확실 하지 않 은 구역 은 동전 의 경계 구역 이다.
그래서 우 리 는 우리 가 동전 의 구역 이 확실 하 다 는 것 을 추출 해 야 한다.침식 경계 픽 셀 제거.그래서 얼마 가 남 았 든 지 간 에 우 리 는 동전 이 확실 하 다.물체 가 서로 접촉 하지 않 으 면 된다.그러나 서로 접촉 하기 때문에 또 다른 좋 은 선택 은 거리 변환 을 찾 아 적당 한 한도 값 을 적용 하 는 것 이다.이제 우 리 는 동전 이 아니 라 고 확신 하 는 지역 을 찾 아야 한다.이 를 위해,우 리 는 결 과 를 확장 했다.팽창 은 물체 의 경 계 를 배경 으로 늘린다.이러한 방식 을 통 해 우 리 는 결과 의 모든 배경 구역 이 진정한 배경 이라는 것 을 확보 할 수 있다.왜냐하면 경계 구역 이기 때문이다.
CSDN图标
나머지 구역 은 우리 가 모 르 는 것 이다.동전 이 든 배경 이 든.분수령 알고리즘 은 그것 을 찾 을 수 있 을 것 이다.이 지역 들 은 보통 동전 의 경계,즉 전망 과 배경 이 만 나 는 곳(심지어 두 개의 서로 다른 동전 이 만 나 는 곳)을 둘러싸 고 있다.우 리 는 그것 을 경계 라 고 부른다.sure 로fg 면적 빼 기 surebg 면적 가능.

Mat opening; Mat sure_bg;
Mat sure_fg; Mat unknow;
Mat dist_transform;
double maxValue;
// noise removal
Mat kernel = Mat::ones(3, 3, CV_8U);
morphologyEx(thresh, opening, MORPH_OPEN, kernel);

// sure background area
dilate(opening, sure_bg, kernel, Point(-1, -1), 3);

// Finding sure foreground area
distanceTransform(opening, dist_transform, DIST_L2, 5);
minMaxLoc(dist_transform, 0, &maxValue, 0, 0);
threshold(dist_transform, sure_fg, 0.7*maxValue, 255, 0);

// Finding unknown region
sure_fg.convertTo(sure_fg, CV_8U);
subtract(sure_bg, sure_fg, unknow);
결 과 를 보다.한도 값 그림 에서 우 리 는 일부 지역 의 동전 을 얻 었 습 니 다.우 리 는 이 동전 들 이 독립 적 이라는 것 을 확인 합 니 다.(어떤 경우 에는 전망 분할 에 만 관심 이 있 고 서로 접촉 하 는 대상 의 분할 에 관심 이 없 을 수도 있다.이런 상황 에서 너 는 거리 변환 을 사용 할 필요 가 없다.침식 만 하면 충분 하 다.침식 은 전경 구역 을 추출 하 는 또 다른 방법 일 뿐 입 니 다.)
CSDN图标   CSDN图标
지금 우 리 는 어떤 것 이 동전 구역 이 고 어떤 것 이 배경 인지 등 을 확정 할 수 있다.따라서 저 희 는 marker 를 만 들 었 습 니 다.우리 가 확정 한 구역(전망 이 든 배경 이 든)은 모든 정수 로 표시 되 지만,서로 다른 정 수 는 0 으로 유지 된다.이 를 위해,우 리 는 connected Components()를 사용 했다.그림 의 배경 을 0 으로 표시 한 다음 1 부터 의 정수 로 다른 대상 을 표시 합 니 다.
그러나 background 를 0 으로 표시 하면 watershed 는 알 수 없 는 영역 이 라 고 생각 할 것 이라는 것 을 알 고 있 습 니 다.그래서 우 리 는 서로 다른 정수 로 그것 을 표시 해 야 한다.반면,우 리 는 알 수 없 는 영역 을 0 으로 정의 합 니 다.

// Marker labelling
Mat markers;
connectedComponents(sure_fg, markers);

// Add one to all labels so that sure background is not 0, but 1
markers = markers + 1;

// Now, mark the region of unknown with zero
markers.setTo(0, unknow);
이제 우리 의 태그 그림 이 준비 되 었 습 니 다.마지막 단계 에 이 르 러 분수령 을 응용 하 다.그리고 태그 그림 을 수정 합 니 다.경계 구역 은-1 로 표 시 됩 니 다.

Mat marker;
Mat mask;
watershed(img, markers);
compare(markers, -1, mask, CMP_EQ);
img.setTo(Scalar(0, 0, 255), mask);
아래 의 결 과 를 참조 하 다.일부 동전 에 대해 서 는 접촉 하 는 구역 이 정확하게 분할 되 었 고,다른 동전 에 대해 서 는 분할 되 지 않 았 다.
CSDN图标 CSDN图标
C++에서 OpenCV 이미지 분할 과 분수령 알고리즘 을 실현 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 OpenCV 이미지 분할 과 분수령 알고리즘 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기