原理
Hilditch 算法是判断图像中的点属于边界点还是连通点,如为边界点则可以去掉此点。 应用过程为对一幅图像从左上角开始到右下角的每个像素进行迭代运算,每次迭代运算可以将图像最外面一 层像素剔去,层层剥离后最终剩下最中间的一条线,得到最终的骨架线,即细化后的图像。
在进行迭代运算时,当某个像素满足以下六个条件时即被标记删除。
(1)P为前景点;
(2)P0、P2、P4、P6不全为前景点,即P为边界点;
(3)P0~P7中至少有2个前景点,表示P不是端点或孤立点,端点和孤立点不能删除;
(4)P的八联通区域连接数为1,保证细化后的骨架线不会出现断裂的情况;
(5)若P2被标记删除,P2为0时,P的联通连接数为1,保证两个像素宽的水平条不会被腐蚀掉;
(6)若P4被标记删除,P4为0时,P的联通连接数为1,保证两个像素宽的垂直条不会被腐蚀掉。
以上判据就是:1.内部点不能删除、2.孤立点不能删除、3.端点不能删除、4.若P是边界点,去掉P后,连通分量不增加,则P可以删除。
对于联结数的理解
八联通联结数就是指在中心像素的 3*3 的邻域中,和中心像素连接的图像分量的个数;
为更方便理解,这里将把四联通与八联通进行对比
四连通区域或四邻域,是指对应像素位置的上、下、左、右,是紧邻的位置。共4个方向
八连通区域或八邻域,是指对应像素位置的上、下、左、右、左上、右上、左下、右下,共八个方向
以下面两幅图为例介绍联结数,同一颜色包含的图像为即为同一图像分量。
4连通联结数:(1)为2;(2)为2
八连通联结数:(1)为1;(2)为2
图(2)中P即使满足其他标记删除的条件,但是若删除P会导致线出现断裂的情况,所以P不能被标记删除,图(1)则不会。
代码实现
#include "stdafx.h"
#include "cv.hpp"
#include "opencv.hpp"
#include "core.hpp"
#include "highgui.hpp"
#include "imgproc.hpp"
#include <iostream>
#include <string>
#include <stack>
using namespace cv;
using namespace std;
typedef uchar BYTE;
//阈值分割,二值化图像
void thresholdImg(Mat inputImg, Mat outImg, BYTE thr, int w, int h)
{
for (int i = 0; i<h; ++i)
{
BYTE* pin = inputImg.ptr<BYTE>(i);
BYTE* pout = outImg.ptr<BYTE>(i);
for (int j = 0; j < w; ++j)
{
if (pin[j] >= thr)
pout[j] = 1;
else
pout[j] = 0;
}
}
}
//Hilditch图像细化算法
int DetectConnectivity(int* list)
{
int count <