当前位置:网站首页>【图像处理】基于中轴变换实现图像骨架提取附matlab代码
【图像处理】基于中轴变换实现图像骨架提取附matlab代码
2022-07-30 05:30: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代码问题可私信交流。
部分理论引用网络文献,若有侵权联系博主删除。
边栏推荐
- 光明区关于促进科技创新的若干措施(征求意见稿)
- RadonDB MySQL on K8s 2.1.2 发布!
- [GStreamer] 插件的名字要和GST_PLUGIN_DEFINE匹配
- 22-07-29 西安 分布式事务、Seata
- “幻核”跑路,数字藏品路在何方?
- 黄金圈法则:成功者必备的深度思考方法
- 力扣20-有效的括号——栈实现
- IIS网站出现401未授权访问
- Within the SQL connection table (link connections, left or right, cross connection, full outer join)
- MySql string splitting realizes the split function (field splitting, column switching, row switching)
猜你喜欢

从字节码角度带你彻底理解异常中catch,return和finally,再也不用死记硬背了

MySql字符串拆分实现split功能(字段分割转列、转行)

从字节码角度带你彻底理解i++与++i

mysql basics (4)

Thymeleaf简介

MYSQL-InnoDB的线程模型

腾讯面试居然跟我扯了半小时的CountDownLatch

互联网(软件)公司项目管理软件调研报告

How MySQL to prepare SQL pretreatment (solve the query IN SQL pretreatment can only query out the problem of a record)

上交所行情文件解析之mktdt04
随机推荐
Golang go-redis cluster模式下不断创建新连接,效率下降问题解决
mysql基础(4)
MySQL安装配置教程(超级详细)
idea 编译protobuf 文件的设置使用
MySQL基础(DDL、DML、DQL)
腾讯面试居然跟我扯了半小时的CountDownLatch
go版本升级
Docker-compose安装mysql
mysql basics (4)
JVM 垃圾回收 超详细学习笔记(二)
108. 将有序数组转换为二叉搜索树
2022鹏城杯web
RadonDB MySQL on K8s 2.1.4 发布!
Internet (software) company project management software research report
1475. 商品折扣后的最终价格
JVM之GC 调优基础知识(一)
容器化 | 构建 RadonDB MySQL 集群监控平台
"Hou Lang" programmer version, a speech dedicated to a new generation of programmers, He Bing's "Hou Lang" speech imitation show
MySQL - Function and Constraint Commands
坠落的蚂蚁(北京大学考研机试题)