实现了二值图像的Thin,Thicken和提取骨架的操作。
#include "opencv2/opencv.hpp"
#define HIT 1
#define MISS 0
using namespace cv;
using namespace std;
const int dir[9][2] = {
{-1,-1},{-1,0},{-1,1},{0,-1},{0,0},{0,1},{1,-1},{1,0},{1,1}};
//定义了skeleton和convex hull操作用到的各八个structuring element
//structuring element可根据不同需要改变,这里只是一种
#define ELE_STR_SIZE 3
#define SKELETON_STR_ELE_NUM 8
const unsigned char skeleton_str_ele[SKELETON_STR_ELE_NUM][ELE_STR_SIZE][ELE_STR_SIZE] = {
{
{0,0,0},
{2,1,2},
{1,1,1}
},
{
{2,0,0},
{1,1,0},
{2,1,2}
},
{
{1,2,0},
{1,1,0},
{1,2,0}
},
{
{2,1,2},
{1,1,0},
{2,0,0}
},
{
{1,1,1},
{2,1,2},
{0,0,0}
},
{
{2,1,2},
{0,1,1},
{0,0,2}
},
{
{0,2,1},
{0,1,1},
{0,2,1}
},
{
{0,0,2},
{0,1,1},
{2,1,2}
}
};
#define CONVEX_HULL_STR_ELE_NUM 8
const unsigned char convex_hull_str_ele[CONVEX_HULL_STR_ELE_NUM][ELE_STR_SIZE][ELE_STR_SIZE] = {
{
{1,1,2},
{1,0,2},
{1,2,0}
},
{
{2,1,1},
{2,0,1},
{0,2,1}
},
{
{1,1,1},
{2,0,1},
{0,2,2}
},
{
{0,2,2},
{2,0,1},
{1,1,1}
},
{
{0,2,1},
{2,0,1},
{2,1,1}
},
{
{1,2,0},
{1,0,2},
{1,1,2}
},
{
{2,2,0},
{1,0,2},
{1,1,1}
},
{
{1,1,1},
{1,0,2},
{2,2,0}
}
};
unsigned char hit_and_miss(unsigned char src[][ELE_STR_SIZE],const unsigned char str_ele[][ELE_STR_SIZE]){
//对一块区域的hit_and_miss判定
for (int i = 0;i < ELE_STR_SIZE;i++){
for (int j = 0;j < ELE_STR_SIZE;j++){
if (str_ele[i][j] == 0 || str_ele[i][j] == 1){
if (str_ele[i][j] != src[i][j]) return MISS;
}
}
}
return HIT;
}
void hit_and_miss(IplImage *src,IplImage **dst,const unsigned char str_ele[][ELE_STR_SIZE])
{
//对一个二值图像的hit_and_miss操作
unsigned char matrix[ELE_STR_SIZE][ELE_STR_SIZE];
int i1,j1,nx,ny;
CvSize size = cvGetSize(src);
if ((*dst) != NULL) cvReleaseImage(dst);
(*dst) = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
cvZero(*dst);
for (int i = 0;i<size.height;i++){
for (int j = 0;j<size.width;j++){
i1 = 0;
j1 = 0;
for (int k = 0;k < 9;k++){
//把自身及相邻共九个格子放入一个矩阵中
nx = i + dir[k][0];
ny = j + dir[k][1];
if (nx<0 || nx>=size.height ||