코드를 수행하면 모든 흰색 반점에 대한의 구형 (모양)을 경계 찾아 주셔서 감사합니다.
비고 : 흰 반점이 실제로 흰색 (즉, 회색 음영 이미지에서 255 값을 가짐)이라고 생각할 수 있다면이 스 니펫을 사용할 수 있습니다. 잠깐의 매개 변수를 트래버스 (Traverse) 함수로 전달하지 않도록 클래스에 두는 것을 고려하십시오. 그것은 작동하지만. 이 아이디어는 DFS를 기반으로합니다. gryscaled 이미지와 별개로, 우리는 어떤 픽셀이 어느 블롭에 속하는지 (동일한 블롭에 속한 모든 픽셀이 동일한 블롭에 속함) 할당하고 기억할 수있는 행렬을 가지고 있습니다.
void Traverse(int xs, int ys, cv::Mat &ids,cv::Mat &image, int blobID, cv::Point &leftTop, cv::Point &rightBottom) {
std::stack<cv::Point> S;
S.push(cv::Point(xs,ys));
while (!S.empty()) {
cv::Point u = S.top();
S.pop();
int x = u.x;
int y = u.y;
if (image.at<unsigned char>(y,x) == 0 || ids.at<unsigned char>(y,x) > 0)
continue;
ids.at<unsigned char>(y,x) = blobID;
if (x < leftTop.x)
leftTop.x = x;
if (x > rightBottom.x)
rightBottom.x = x;
if (y < leftTop.y)
leftTop.y = y;
if (y > rightBottom.y)
rightBottom.y = y;
if (x > 0)
S.push(cv::Point(x-1,y));
if (x < ids.cols-1)
S.push(cv::Point(x+1,y));
if (y > 0)
S.push(cv::Point(x,y-1));
if (y < ids.rows-1)
S.push(cv::Point(x,y+1));
}
}
int FindBlobs(cv::Mat &image, std::vector<cv::Rect> &out, float minArea) {
cv::Mat ids = cv::Mat::zeros(image.rows, image.cols,CV_8UC1);
cv::Mat thresholded;
cv::cvtColor(image, thresholded, CV_RGB2GRAY);
const int thresholdLevel = 130;
cv::threshold(thresholded, thresholded, thresholdLevel, 255, CV_THRESH_BINARY);
int blobId = 1;
for (int x = 0;x<ids.cols;x++)
for (int y=0;y<ids.rows;y++){
if (thresholded.at<unsigned char>(y,x) > 0 && ids.at<unsigned char>(y,x) == 0) {
cv::Point leftTop(ids.cols-1, ids.rows-1), rightBottom(0,0);
Traverse(x,y,ids, thresholded,blobId++, leftTop, rightBottom);
cv::Rect r(leftTop, rightBottom);
if (r.area() > minArea)
out.push_back(r);
}
}
return blobId;
}
EDIT
: 난, 버그 수정 임계치 레벨을 낮출 현재 출력 이하 주어진다. 나는 그것이 좋은 출발점이라고 생각한다.
EDIT2 : 나는 Traverse()
에 재귀 제거. 더 큰 이미지 재귀 Stackoverflow가 발생했습니다.
정말 그렇게하지 않을 것입니다. http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#inrange –
@DavidKernin : 대단히 감사합니다! 나는 안으로 깊숙이 들어갈 것이다 – AsfK
인터넷 검색 시도 "얼룩 분석"http://en.wikipedia.org/wiki/Blob_detection –