您现在的位置是:首页 > 正文

zhang-Suen图像骨架提取(原理和代码)

2024-02-01 02:36:22阅读 2

转自东方fan的博客,感谢!
该算法有四个条件,若满足,则该点置为0。

或:
在这里插入图片描述
其中(a)(b)的意思为:

  1. 中心像素P1周围的目标像素(二值中的1)的个数之和在2和6之间。
  2. 8邻域像素中,按顺时针方向,相邻两个像素出现0->1的次数。

代码:

void thinImage(Mat & srcImg) {
	vector<Point> deleteList;
	int neighbourhood[9];
	int nl = srcImg.rows;
	int nc = srcImg.cols;
	bool inOddIterations = true;
	while (true) {
		for (int j = 1; j < (nl - 1); j++) {
			uchar* data_last = srcImg.ptr<uchar>(j - 1);
			uchar* data = srcImg.ptr<uchar>(j);
			uchar* data_next = srcImg.ptr<uchar>(j + 1);
			for (int i = 1; i < (nc - 1); i++) {
				if (data[i] == 255) {
					int whitePointCount = 0;
					neighbourhood[0] = 1;
					if (data_last[i] == 255) neighbourhood[1] = 1;
					else  neighbourhood[1] = 0;
					if (data_last[i + 1] == 255) neighbourhood[2] = 1;
					else  neighbourhood[2] = 0;
					if (data[i + 1] == 255) neighbourhood[3] = 1;
					else  neighbourhood[3] = 0;
					if (data_next[i + 1] == 255) neighbourhood[4] = 1;
					else  neighbourhood[4] = 0;
					if (data_next[i] == 255) neighbourhood[5] = 1;
					else  neighbourhood[5] = 0;
					if (data_next[i - 1] == 255) neighbourhood[6] = 1;
					else  neighbourhood[6] = 0;
					if (data[i - 1] == 255) neighbourhood[7] = 1;
					else  neighbourhood[7] = 0;
					if (data_last[i - 1] == 255) neighbourhood[8] = 1;
					else  neighbourhood[8] = 0;
					for (int k = 1; k < 9; k++) {
						whitePointCount += neighbourhood[k];
					}
					if ((whitePointCount >= 2) && (whitePointCount <= 6)) {
						int ap = 0;
						if ((neighbourhood[1] == 0) && (neighbourhood[2] == 1)) ap++;
						if ((neighbourhood[2] == 0) && (neighbourhood[3] == 1)) ap++;
						if ((neighbourhood[3] == 0) && (neighbourhood[4] == 1)) ap++;
						if ((neighbourhood[4] == 0) && (neighbourhood[5] == 1)) ap++;
						if ((neighbourhood[5] == 0) && (neighbourhood[6] == 1)) ap++;
						if ((neighbourhood[6] == 0) && (neighbourhood[7] == 1)) ap++;
						if ((neighbourhood[7] == 0) && (neighbourhood[8] == 1)) ap++;
						if ((neighbourhood[8] == 0) && (neighbourhood[1] == 1)) ap++;
						if (ap == 1) {
							if (inOddIterations && (neighbourhood[3] * neighbourhood[5] * neighbourhood[7] == 0)
								&& (neighbourhood[1] * neighbourhood[3] * neighbourhood[5] == 0)) {
								deleteList.push_back(Point(i, j));
							}  //仅仅是位置命名的数字不一样,与上述条件吻合	
						else if (!inOddIterations && (neighbourhood[1] * neighbourhood[5] * neighbourhood[7] == 0)
								&& (neighbourhood[1] * neighbourhood[3] * neighbourhood[7] == 0)) {
								deleteList.push_back(Point(i, j));
							}
						}
					}
				}
			}
		}
		if (deleteList.size() == 0)
			break;
		for (size_t i = 0; i < deleteList.size(); i++) {
			Point tem;
			tem = deleteList[i];
			uchar* data = srcImg.ptr<uchar>(tem.y);
			data[tem.x] = 0;
		}
		deleteList.clear();
		inOddIterations = !inOddIterations;
	}
	vector<Point> (deleteList).swap(deleteList);
}

但代码中有一点不理解:布尔类型的inOddIterations变量的作用是什么,请路过的朋友留言告知一下,谢谢
在这里插入图片描述

网站文章

  • 【leetcode-python】541. 反转字符串 II

    给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。 如果剩余字符少于 k 个,则将剩余字符全部反转。 如果剩余字符小于 2k 但大于或等于 k ...

    2024-02-01 02:36:15
  • 3-Flutter常用组件--标题栏和状态栏

    3-Flutter常用组件--标题栏和状态栏

    文章目录1.BottomAppBar属性2.BottomNavigationBar属性BottomNavigationBarItem3.SliverAppBar属性1.FlexibleSpaceBar...

    2024-02-01 02:35:45
  • JS 常用数组

    JS 常用数组

    从 0 开始计算的索引,表示要开始改变数组的位置一个整数,表示数组中要从start开始删除的元素数量。(0代表不删除)item1itemN从start开始要加入到数组中的元素(如果不指定,那不增加元素)

    2024-02-01 02:35:38
  • 利用图神经网络进行药物再利用的计算方法(下)

    利用图神经网络进行药物再利用的计算方法(下)

    本研究提出了一种图神经网络药物再利用模型,我们称之为GDRnet,以有效地筛选大型批准药物数据库,并预测新疾病的可能治疗方法。我们将药物再利用作为一个多层异构网络中的链接预测问题,该网络约有140万条...

    2024-02-01 02:35:33
  • Java反射调用ashx

    Java反射调用ashx

    Java发送调用jar包的方法,转换为基类接口调用

    2024-02-01 02:35:05
  • mysql事务机制

    mysql事务机制

    一、事务的基本要素(ACID) 1、原子性(Atomicity) 2、一致性(Consistency) 3、隔离性(Isolation) 4、持久性(Durability) 二、事务的并发问题   1...

    2024-02-01 02:34:58
  • 字符串加空格

    题目描述给定一个字符串,在字符串的每个字符之间都加一个空格。输出修改后的新字符串。输入共一行,包含一个字符串。注意字符串中可能包含空格。数据范围1≤字符串长度≤100输出输出增加空格后的字符串。样例输...

    2024-02-01 02:34:52
  • 将训练好的 mmdetection 模型转为 tensorrt 模型

    mmdetection 是商汤科技(2018 COCO 目标检测挑战赛冠军)和香港中文大学开源的基于Pytorch实现的深度学习目标检测工具箱,性能强大,运算效率高,配置化编程,比较容易训练、测试。但...

    2024-02-01 02:34:23
  • 多样性数据源报表如何做?几行代码就能解决。

    多样性数据源报表如何做?几行代码就能解决。

    ​现代应用已经进入多数据源阶段了,不再是一个单一的数据库包打天下,一个应用中会涉及除关系数据库外各种数据源,如文本文件类数据、NOSQL、多维数据库、HTML Webservice等等,即使是关系数据...

    2024-02-01 02:34:17
  • C#读取CSV文件 热门推荐

    C#读取CSV文件功能属性标签反射部分Csv读取的class读取文件读取title(字段名!)读取数据(values)将读取的字段名(title)和数据集合(二维数组)序列化结束语 功能 读取CSV文...

    2024-02-01 02:34:10