最后再来看一种通过形态学腐蚀和开操作得到骨架的方法。
代码非常简单:
void gThin::cvmorphThin(cv::Mat& src, cv::Mat& dst) {
if(src.type()!=CV_8UC1) { printf("只能处理二值或灰度图像\n"); return; } //非原地操作时候,copy src到dst if(dst.data!=src.data) { src.copyTo(dst); }
cv::Mat skel(dst.size(), CV_8UC1, cv::Scalar(0)); cv::Mat temp(dst.size(), CV_8UC1);
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3)); bool done; do { cv::morphologyEx(dst, temp, cv::MORPH_OPEN, element); cv::bitwise_not(temp, temp); cv::bitwise_and(dst, temp, temp); cv::bitwise_or(skel, temp, skel); cv::erode(dst, dst, element);
double max; cv::minMaxLoc(dst, 0, &max); done = (max == 0); } while (!done);
dst = skel;
}
算法原理如下,就是通过十字型结构元素开操作的的补集和当前像素相与来作为骨架。当图像腐蚀为全0时候,就得到了整个图像的骨架。
img = ...;while (not_empty(img)){ skel = skel | (img & !open(img)); img = erosion(img);}
程序源代码:工程FirstOpenCV11