在图像处理中,有时候我们会想要提取图像的骨架,这是就需要对图像进行细化,opencv中没有直接进行细化的算法,网上大部分的细化算法都是基于以前IplImage结构的,对于想要使用新的C++接口的Mat结构需要进行一定的修改,本文的细化方法是基于Mat数据结构的,使用的是OpenCV2.4.9版本。
参考自:http://blog.csdn.net/qianchenglenger/article/details/19332011
//提取图像的骨架
void ImgThin(cv::Mat src,int maxIterations=-1)
{
if (src.empty()) return;//图像为空,直接返回
cv::threshold(src, src, m_dThreshold, 1, CV_THRESH_BINARY);//转为0或1的图像
int ImgHeight = src.rows;
int ImgWidth = src.cols;
int count = 0; //记录迭代次数
while (true)
{
count++;
if (maxIterations != -1 && count > maxIterations) //限制次数并且迭代次数到达
break;
vector<pair<int, int> > mFlag; //用于标记需要删除的点
//对点标记
for (int i = 0; i < ImgHeight; ++i)
{
for (int j = 0; j < ImgWidth; ++j)
{
//如果满足四个条件,进行标记
// p9 p2 p3
// p8 p1 p4
// p7 p6 p5
int p1 = src.at<uchar>(i, j);
int p2 = (i == 0) ? 0 : src.at<uchar>(i - 1, j);
int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i - 1, j + 1);