当前位置:网站首页>[Image processing] Image skeleton extraction based on central axis transformation with matlab code
[Image processing] Image skeleton extraction based on central axis transformation with matlab code
2022-07-30 05:55:00 【matlab_dingdang】
1 内容介绍
介绍了一种中轴变换算法.该算法修正了现存算法的缺点,可以快速去除二值图像中的冗余信息,准确抽取图像的单像素骨架,保留基本特征,特别是斜线和圆形焊盘特征.大量实验表明,该方法降低图像的复杂度,仅保留图像形状的拓扑信息,为后续处理提供理想的图像,提高整个系统的性能.
2 完整代码
% 中轴算法 Medial Axis Transfrom%% by HPC_ZY 20190802clear; close all; clcload data%% matlab% 求骨架ticskeleton = bwmorph(im,'skeleton',Inf);t1 = toc;% 去毛刺ticskeleton1 = bwmorph(skeleton,'spur',16);t2 = toc;figureshowres(im,skeleton,t1,1,2,1,'matlab库')showres(im,skeleton1,t2,1,2,2,'matlab库(消除毛刺)')%% 迭代删除% 迭代删除法ticskeleton1 = method1(im);t1 = toc;% 迭代删除法(查找表)ticskeleton2 = method2(im);t2 = toc;% 迭代删除法(简化)ticskeleton3 = method3(im);t3 = toc;figureshowres(im,skeleton1,t1,1,3,1,'迭代删除法')showres(im,skeleton2,t2,1,3,2,'迭代删除法(查找表)')showres(im,skeleton3,t3,1,3,3,'迭代删除法(简化)')%% ------------function--------------% 迭代删除法function skeleton = method1(bw)bw = double(bw); % 转为非逻辑类型,方便后面求和[M,N] = size(bw);skeleton = bw;deleCount = 1; % 用于记录一次迭代删除的像素个数while deleCount>0% 删(右,下)deleCount = 0;label = zeros(M,N,'logical');for i = 2:M-1for j = 2:N-1if skeleton(i,j) % 如果该点为1,判断周围像素p = [skeleton(i-1,j),skeleton(i-1,j+1),skeleton(i,j+1),skeleton(i+1,j+1),...skeleton(i+1,j),skeleton(i+1,j-1),skeleton(i,j-1),skeleton(i-1,j-1)];Np = sum(p);Tp = length(find(([p(2:end),p(1)]-p) == 1));if Np>1 && Np<7 && Tp==1 && p(1)*p(3)*p(5)==0 && p(7)*p(3)*p(5)==0deleCount = deleCount+1;label(i,j) = 1;endendendendskeleton(label) = 0;% 删(左,上)label = zeros(M,N,'logical');for i = 2:M-1for j = 2:N-1if skeleton(i,j) % 如果该点为1,判断周围像素p = [skeleton(i-1,j),skeleton(i-1,j+1),skeleton(i,j+1),skeleton(i+1,j+1),...skeleton(i+1,j),skeleton(i+1,j-1),skeleton(i,j-1),skeleton(i-1,j-1)];Np = sum(p);Tp = length(find(([p(2:end),p(1)]-p) == 1));if Np>1 && Np<7 && Tp==1 && p(1)*p(3)*p(7)==0 && p(1)*p(5)*p(7)==0deleCount = deleCount+1;label(i,j) = 1;endendendendskeleton(label) = 0;endend% 迭代删除法(查找表)function skeleton = method2(bw)bw = double(bw);[M,N] = size(bw);skeleton = bw;% 生成查找表[List1,List2] = getList1();[x,y] = find(bw);a = min(x);b = max(x);c = min(y);d = max(y);deleCount = 1;mat = [1,2,4,8,16,32,64,128];while deleCount>0deleCount = 0;% 删(右,下)label1 = zeros(M,N,'logical');for i = a:bfor j = c:dif skeleton(i,j)p = [skeleton(i-1,j),skeleton(i-1,j+1),skeleton(i,j+1),skeleton(i+1,j+1),...skeleton(i+1,j),skeleton(i+1,j-1),skeleton(i,j-1),skeleton(i-1,j-1)];idx = sum(p.*mat)+1;if List1(idx)label1(i,j) = true;deleCount = deleCount+1;endendendendskeleton(label1) = 0;% 删(左,上)label2 = zeros(M,N,'logical');for i = a:bfor j = c:dif skeleton(i,j)p = [skeleton(i-1,j),skeleton(i-1,j+1),skeleton(i,j+1),skeleton(i+1,j+1),...skeleton(i+1,j),skeleton(i+1,j-1),skeleton(i,j-1),skeleton(i-1,j-1)];idx = sum(p.*mat)+1;if List2(idx)label2(i,j) = true;deleCount = deleCount+1;endendendendskeleton(label2) = 0;endend% 迭代删除法(简化)function skeleton = method3(bw)bw = double(bw);[M,N] = size(bw);skeleton = bw;% 生成查找表List = getList2();% 收缩搜索范围[x,y] = find(bw);a = min(x);b = max(x);c = min(y);d = max(y);% 开始迭代deleCount = 1;mat = [1,2,4,8,16,32,64,128];while deleCount>0deleCount = 0;label = zeros(M,N,'logical');for i = a:bfor j = c:dif skeleton(i,j)p = [skeleton(i-1,j),skeleton(i-1,j+1),skeleton(i,j+1),skeleton(i+1,j+1),...skeleton(i+1,j),skeleton(i+1,j-1),skeleton(i,j-1),skeleton(i-1,j-1)];idx = sum(p.*mat)+1;if List(idx)label(i,j) = true;deleCount = deleCount+1;endendendendskeleton(label) = 0;endend% 生成查找表function [List1,List2] = getList1()List1 = zeros(256,1,'logical');List2 = zeros(256,1,'logical');for n = 0:255p = bitget(n,1:8);Np = sum(p);Tp = length(find(([p(2:end),p(1)]-p) == 1));if Np>1 && Np<7 && Tp==1% 右,下if p(1)*p(3)*p(5)==0 && p(7)*p(3)*p(5)==0List1(n+1) = true;end% 左,上if p(1)*p(3)*p(7)==0 && p(1)*p(5)*p(7)==0List2(n+1) = true;endendendend% 生成查找表(简化)function List = getList2()List = zeros(256,1,'logical');for n = 0:255p = bitget(n,1:8);Np = sum(p);Tp = length(find(([p(2:end),p(1)]-p) == 1));if Np>1 && Np<7 && Tp==1if (p(1)*p(3)*p(5)==0 && p(7)*p(3)*p(5)==0)||...(p(1)*p(3)*p(7)==0 && p(1)*p(5)*p(7)==0)List(n+1) = true;endendendend% 显示结果function showres(im,skeleton,t,i,j,k,titlename)subplot(i,j,k),imshow(im)hold on[x,y] = find(skeleton);plot(y,x,'r.')title(['\fontsize{16}',titlename])xlabel(['\fontsize{16}耗时(秒):',num2str(t)])end
3 运行结果


4 参考文献
[1]史聪伟, 赵杰煜, 常俊生. 基于中轴变换的骨架特征提取算法[J]. 计算机工程, 2019, 45(7):9.
博主简介:擅长智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,相关matlab代码问题可私信交流.
部分理论引用网络文献,若有侵权联系博主删除.
边栏推荐
- JVM 类加载机制 超详细学习笔记(三)
- MySQL - Function and Constraint Commands
- Thymeleaf简介
- curl (7) Failed connect to localhost8080; Connection refused
- This article will take you through js to deal with the addition, deletion, modification and inspection of tree structure data
- MySQL Basics (DDL, DML, DQL)
- 即刻报名|如何降低云上数据分析成本?
- 程序员赚钱实操,手把手教你做付费课程,自媒体,付费文章及付费技术课赚钱
- 微信小程序开发学习
- 【LeetCode】Day107-除自身以外数组的乘积
猜你喜欢
随机推荐
mysql cannot connect remotely Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (10060 "Unknown error")
排列数字(DAY90)dfs
1475. 商品折扣后的最终价格
Within the SQL connection table (link connections, left or right, cross connection, full outer join)
Concurrent Programming Review
力扣20-有效的括号——栈实现
翻译 | 解读首部 Kubernetes 纪录片
从字节码角度带你彻底理解异常中catch,return和finally,再也不用死记硬背了
容器化 | 构建 RadonDB MySQL 集群监控平台
是时候不得不学英语了,技多不压身,给自己多条路
从底层结构开始学习FPGA(6)----分布式RAM(DRAM,Distributed RAM)
Redis基础学习
行业案例|数字化经营底座助力寿险行业转型
给小白的 PostgreSQL 容器化部署教程(上)
108. 将有序数组转换为二叉搜索树
坠落的蚂蚁(北京大学考研机试题)
Codeforces Round #809 (Div. 2) A~D
Different lower_case_table_names settings for server (‘1‘) and data dictionary (‘0‘) 解决方案
五一去见了一些身价数千万的成功人士,我一些新的思路和启示
Nacos 原理








![[GO语言基础] 一.为什么我要学习Golang以及GO语言入门普及](/img/ac/80ab67505f7df52d92a206bc3dd50e.png)
