基于细胞自动机Cellular Automata(CA)的区域生长

2024-01-08 01:30

本文主要是介绍基于细胞自动机Cellular Automata(CA)的区域生长,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本来没想研究这个,但Nvidia NPP的《NVIDIA 2D Image And Signal Performance Primitives》这个模块的NPP Image Processing部分的Filtering Functions中的computer vision部分有连通域标记以及分水岭分割现成的函数。但是当我google这个函数的内容时,却发现根本没普通人使用,只弹出nvidia官网对这个函数的介绍:

如果有很多人使用过NPP的这个函数,怎么可能就2条结果。我内心有点忐忑是不是这部分内容并不好用。

其中官网介绍这个分水岭分割是基于论文《Effiffifficient 2D and 3D Watershed on Graphics Processing Unit: Block-Asynchronous Approches Based on Cellular automata》然后我就查关于CA的内容,然后看到了有CA的区域生长,对于粘连目标,选每个目标的中心为种子点,分别区域生长是不是就把这个粘连目标分割开了。想这样做。

代码:https://github.com/KiriteeGak/region-growing-by-cellular-automata 其参考的论文是Vezhnevets, Vladimir, and Vadim Konouchine. "GrowCut: Interactive multi-label ND image segmentation by cellular automata." proc. of Graphicon. Vol. 1. 2005. 我的理解如下:

class RegionGrowing(object):def region_growing(self, image_array, file_path, cutoff_threshold, iterations):size = np.shape(image_array)#图像矩阵的数组image_array_map = {(r, c): pixel for r, each_row in enumerate(image_array) for c, pixel inenumerate(each_row)}#种子点状态初始化为1,其他设置为0??seeds_map = {(r, c): 1 for (r, c) in self._seed_points(file_path)}#默认要经过50次迭代for it in range(0, iterations):#先复制上一次的种子点的状态_update_seeds_map = seeds_map.copy()for pixel_coord, strength in seeds_map.iteritems():#更新每个点的邻域的值_temp_weights_neighbors_pixel = self._neighborhood_weighting(pixel_coord, image_array_map,seeds_map, cutoff_threshold, size)#更新种子点的坐标和值_update_seeds_map = self._update_weights(_temp_weights_neighbors_pixel, _update_seeds_map)#将更新后的种子点作为下一次迭代开始的种子点seeds_map = _update_seeds_mapself._save_image(self._make_binary_image(np.shape(image_array), seeds_map))@staticmethoddef _seed_points(file_path):fid = open(file_path, 'rb')return [list(map(lambda x: int(x.replace(' ', '')), line.strip().split(','))) for line in fid]@staticmethod#更新每个点的邻域的值后,更新种子点的统计(包括种子点坐标和值)def _update_weights(_temp_weights_neighbors_pixel, _update_seeds_map):for pixel_address, strength in _temp_weights_neighbors_pixel.iteritems():#如果原来的种子点统计内没有这个点,那要把这个点新加进去。if pixel_address not in _update_seeds_map:_update_seeds_map[pixel_address] = strength#如果原来的种子点内有这个点,已经是种子点,但原来这个种子点的值小于现在的值,那么这个将种子点统计内这个点的值进行更新elif pixel_address in _update_seeds_map and _update_seeds_map[pixel_address] < strength:_update_seeds_map[pixel_address] = strengthelse:passreturn _update_seeds_map#更新每个像素点的邻域点的值def _neighborhood_weighting(self, coord, image_map, seeds_map, threshold, canvas_size):#所有像素点还是种子点???应该是所有像素点的具体坐标[r,c],图像尺寸大小[max_r,max_c][[r, c], [max_r, max_c]] = [coord, canvas_size]_temp_weights = {}#计算所有像素点3X3邻域for i in range(-1, 2, 1):for j in range(-1, 2, 1):pixel_key = (r, c)#中心点不用计算,判断越界if [i, j] != [0, 0] and 0 <= r + i < max_r and 0 <= c + j < max_c:#如果这个中心点是种子点if pixel_key in seeds_map:#计算这个中心点与邻域的strengthtrans_strength = self._calculate_strength(image_map[pixel_key],image_map[(r + i, c + j)],seeds_map[pixel_key], threshold)else:##计算这个中心点与邻域的strengthtrans_strength = self._calculate_strength(image_map[pixel_key],image_map[(r + i, c + j)], 0,threshold)if trans_strength != 0:#对这个点的邻域进行更新_temp_weights[(r + i, c + j)] = trans_strengthreturn _temp_weights@staticmethod#中心点,待计算的邻域点,种子点,阈值默认是0.5def _calculate_strength(dat1, dat2, strength, threshold):if dat1 != 0 or dat2 != 0:strength_trans = strength * (1 - (abs(dat1 - dat2) / max(dat1, dat2)))if strength_trans >= threshold:return strength_transreturn 0

然后准备按照这个理解实现C++版本,我的注释部分即每个像素点都要计算3X3邻域然后更新邻域的值,那岂不是一个邻域会被相邻的几个中心点更新很多次?这样不是很浪费时间吗??另外一点,我按照这个注释运行完C++结果,这是以[300,300]为种子点迭代50、100、200、300、400、450、480次的结果:

可以看到需要迭代很多次轮廓才是完全的。是不是因此网上给出的python代码才选了不止一个种子点,而是5个然后迭代几十次就够了!!!因为单一种子点耗时太长是吗。

论文中提到对于多个目标的分割也是可以应用的,但我看论文中多个目标时选的种子点更多,我觉得这个算法应用有点狭窄,最起码现在我有点不想使用了。

但是我还是要试试对于粘连轮廓分割怎样,是否可以达到分水岭的效果

这是我的待分割原图,其实分水岭的效果已经分割得可以。然后以下分别是迭代10、15、20次的结果

可以看到不适合我的应用,因为我的目标大小不一。

看来还是要去理解关于CA的分水岭算法那篇论文。这篇论文实在太难了.....

我刚刚找到Nvidia NPP提供的watershedSegment的API,它是基于CA分水岭实现的https://docs.nvidia.com/cuda/npp/group__image__filter__watershed__segmentation.html,https://github.com/NVIDIA/CUDALibrarySamples/tree/master/NPP/watershedSegmentation Nvidia官方上个月才更新。每次查这些资料的时候,总会对我们自己失望,在技术方面与国际接轨还是太慢了,知识的更新落后了很多。问一堆CUDA或图像相关的群里,或查国内一些网站,都有这个感觉。

NPP中关于分水岭与连通域标记都是需要CUDA11.0支持的,而我的电脑不是,所以我真的很想看明白那篇论文自己实现,再看看吧。

 

 

 

 

 

另外感觉这个博客平台越来越功利了,现在只为了赚钱而存在,不想在这里记录了,想转简书或博客园去。

这篇关于基于细胞自动机Cellular Automata(CA)的区域生长的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/581887

相关文章

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

POJ 1625 自动机

给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。 g++提交 int mat[108][108] ;int matn ;int N ;map<char ,int> to ;//ACconst int maxm = 108 ;const int kin

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

YOLOv8/v10+DeepSORT多目标车辆跟踪(车辆检测/跟踪/车辆计数/测速/禁停区域/绘制进出线/绘制禁停区域/车道车辆统计)

01:YOLOv8 + DeepSort 车辆跟踪 该项目利用YOLOv8作为目标检测模型,DeepSort用于多目标跟踪。YOLOv8负责从视频帧中检测出车辆的位置,而DeepSort则负责关联这些检测结果,从而实现车辆的持续跟踪。这种组合使得系统能够在视频流中准确地识别并跟随特定车辆。 02:YOLOv8 + DeepSort 车辆跟踪 + 任意绘制进出线 在此基础上增加了用户

JVM - Java内存区域

文章目录 目录 文章目录 运行时数据区域 程序计数器 栈 Java虚拟机栈 本地方法栈 栈帧的组成 局部变量表 操作数栈 帧数据 堆 方法区 直接内存 总结 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁时间,有的区域随着虚拟机进程的启动而一直存在,有的区域则是依赖

正规式与有限自动机例题

答案:D 知识点: 正规式 正规集 举例 ab 字符串ab构成的集合 {ab} a|b 字符串a,b构成的集合 {a,b} a^* 由0或者多个a构成的字符串集合 {空,a,aa,aaa,aaaa····} (a|b)^* 所有字符a和b构成的串的集合 {空,a,b,ab,aab,aba,aaab····} a(a|b)^* 以a为首字符的a,b字符串的集

Ai+若依(智能售货机运营管理系统---帝可得)-人员管理-点位管理-区域管理-合作商管理----【08篇---0001:上】

项目介绍 售货机简介 帝可得是一个基于物联网概念下的智能售货机运营管理系统 物联网 物联网(IoT:Internet of Things)简单来说,就是让各种物品通过互联网连接起来,实现信息的交换和通信。 这个概念听起来可能有点抽象,但我们可以把它想象成一个超级大的社交网络。不过,这个网络里的成员不是人类,而是各种物品。比如,你的冰箱、洗衣机、甚至是你的汽车,它们都可以通过互联网互

【最新华为OD机试E卷-支持在线评测】机器人活动区域(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-E/D卷的三语言AC题解 💻 ACM金牌🏅️团队| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线评测,专栏文章质量平均 94 分 最新华为OD机试目录: https://blog.

ACdream区域赛指导赛之手速赛系列(4)

点击打开题目链接 #include <iostream>#include <map>#include <cstdio>#include <string>using namespace std;int a[501];//题意是能不能把一组两个人分到两个不同的正营里面,关键利用map映射void init(){for(int i = 0; i <= 200; i++){a[i]