floodFill을 사용하여 매우 느린 순진한 세분화를 빠르게 재 작성하려고합니다. 색상을 표시하고 윤곽을 찾는 것이 어려워서 1 년 전에 meanShiftFiltering을 배제했습니다.meanShiftSegmentation() 출력에서 findContours()를 실행하는 방법은 무엇입니까?
현재 버전의 opencv에는 mean shift : gpu :: meanShiftSegmentation()을 사용하여 세그먼트에 레이블을 지정하는 빠른 새 기능이있는 것으로 보입니다. 그것은 다음과 같이 이미지를 생성합니다
meanShiftSegmentation() output http://www.ekran.org/tmp/segments.png
그래서이 나에게 윤곽을 생성 할 수있을 아주 가까이 보인다. 어떻게 세그먼트를 생성하기 위해 findContours를 실행할 수 있습니까?나에게 보이는 것처럼 이미지에서 레이블이있는 색을 추출한 다음 이미지의 픽셀 값이 각 레이블 색과 일치하는지 테스트하여 findContours에 적합한 부울 이미지를 만듭니다.
Mat image = imread("test.png");
...
// gpu operations on image resulting in gpuOpen
...
// Mean shift
TermCriteria iterations = TermCriteria(CV_TERMCRIT_ITER, 2, 0);
gpu::meanShiftSegmentation(gpuOpen, segments, 10, 20, 300, iterations);
// convert to greyscale (HSV image)
vector<Mat> channels;
split(segments, channels);
// get labels from histogram of image.
int size = 256;
labels = Mat(256, 1, CV_32SC1);
calcHist(&channels.at(2), 1, 0, Mat(), labels, 1, &size, 0);
// Loop through hist bins
for (int i=0; i<256; i++) {
float count = labels.at<float>(i);
// Does this bin represent a label in the image?
if (count > 0) {
// find areas of the image that match this label and findContours on the result.
Mat label = Mat(channels.at(2).rows, channels.at(2).cols, CV_8UC1, Scalar::all(i)); // image filled with label colour.
Mat boolImage = (channels.at(2) == label); // which pixels in labeled image are identical to this label?
vector<vector<Point>> labelContours;
findContours(boolImage, labelContours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
// Loop through contours.
for (int idx = 0; idx < labelContours.size(); idx++) {
// get bounds for this contour.
bounds = boundingRect(labelContours[idx]);
// create ROI for bounds to extract this region
Mat patchROI = image(bounds);
Mat maskROI = boolImage(bounds);
}
}
}
이것이 가장 좋은 방법인가 또는 라벨의 색상을 얻을 수있는 더 좋은 방법이있다 :이 (더 나은 방법이 있어야한다는 조금 느리지 만 날 파업) 내가 다음에 무슨 짓입니까? meanShiftSegmentation이이 정보를 제공하는 것이 논리적 인 것으로 보입니다. (색상 값 벡터 또는 각 레이블에 대한 마스크 벡터)
감사합니다.