Matlab空心散点检测的示例分析
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要介绍Matlab空心散点检测的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题描述有一张这样的图片,如何提取里面的红色圈圈坐标,并且连接这些坐标形成两个封
千家信息网最后更新 2025年11月07日Matlab空心散点检测的示例分析
这篇文章主要介绍Matlab空心散点检测的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
问题描述
有一张这样的图片,如何提取里面的红色圈圈坐标,并且连接这些坐标形成两个封闭的环路?
过程展示
图像导入
oriPic=imread('test1.png');subplot(2,2,1)imshow(oriPic)依据RGB值图像二值化
原理就是图中颜色种类比较少,只有红黑白,而红色和白色都是R通道数值较大,因此我们可以利用这一点进行图像分割
% 删除红色外的部分并构造二值图grayPic=rgb2gray(oriPic);grayPic(oriPic(:,:,1)<250)=255;grayPic(grayPic<250)=0;%subplot(2,2,2)figureimshow(grayPic)

图像腐蚀
对于白色来说是腐蚀,对于黑色来说是膨胀,这一步是为了让那些有缺口的小圆圈将缺口补起来
% 图像膨胀,使未连接边缘连接SE=[0 1 0;1 1 1;0 1 0];bwPic=imerode(grayPic,SE);figureimshow(bwPic)

图像边缘清理
就是把和边缘连接的不被黑色包围的区域变成黑色:
% 边缘清理:保留圆圈联通区域bwPic=imclearborder(bwPic);%subplot(2,2,3)figureimshow(bwPic)
联通区域查找与坐标均值计算
现在每一个白点都是一个坐标区域,我们检测所有联通区域并计算各个区域的重心即可:
% 获取每一个联通区域[LPic,labelNum]=bwlabel(bwPic);% 计算每一个联通区域 坐标均值pointSet=zeros(labelNum,2);for i=1:labelNum [X,Y]=find(LPic==i); Xmean=mean(X); Ymean=mean(Y); pointSet(i,:)=[Xmean,Ymean];end% 画个图展示一下%subplot(2,2,4)figureimshow(bwPic)hold onscatter(pointSet(:,2),pointSet(:,1),'r','LineWidth',1)
可以看出定位结果还是非常准确的:
圈查找
就以一个点开始不断找最近的点呗,没啥好说的:
n=1;while ~isempty(pointSet) circleSetInd=1; for j=1:length(pointSet) disSet=sqrt(sum((pointSet-pointSet(circleSetInd(end),:)).^2,2)); [~,ind]=sort(disSet); ind=ind(1:5); [~,~,t_ind]=intersect(circleSetInd,ind); ind(t_ind)=[]; if ~isempty(ind) circleSetInd=[circleSetInd;ind(1)]; else circleSet{n}=pointSet(circleSetInd,:); pointSet(circleSetInd,:)=[]; n=n+1; break end endendfigureimshow(oriPic)hold onfor i=1:n-1plot(circleSet{i}(:,2),circleSet{i}(:,1),'LineWidth',2)end这效果就很美滋滋:
完整代码
function redPntoriPic=imread('test1.png');%subplot(2,2,1)figureimshow(oriPic)% 删除红色外的部分并构造二值图grayPic=rgb2gray(oriPic);grayPic(oriPic(:,:,1)<250)=255;grayPic(grayPic<250)=0;%subplot(2,2,2)figureimshow(grayPic)% 图像膨胀,使未连接边缘连接SE=[0 1 0;1 1 1;0 1 0];bwPic=imerode(grayPic,SE);figureimshow(bwPic)% 边缘清理:保留圆圈联通区域bwPic=imclearborder(bwPic);%subplot(2,2,3)figureimshow(bwPic)% 获取每一个联通区域[LPic,labelNum]=bwlabel(bwPic);% 计算每一个联通区域 坐标均值pointSet=zeros(labelNum,2);for i=1:labelNum [X,Y]=find(LPic==i); Xmean=mean(X); Ymean=mean(Y); pointSet(i,:)=[Xmean,Ymean];end%subplot(2,2,4)figureimshow(bwPic)hold onscatter(pointSet(:,2),pointSet(:,1),'r','LineWidth',1)n=1;while ~isempty(pointSet) circleSetInd=1; for j=1:length(pointSet) disSet=sqrt(sum((pointSet-pointSet(circleSetInd(end),:)).^2,2)); [~,ind]=sort(disSet); ind=ind(1:5); [~,~,t_ind]=intersect(circleSetInd,ind); ind(t_ind)=[]; if ~isempty(ind) circleSetInd=[circleSetInd;ind(1)]; else circleSet{n}=pointSet(circleSetInd,:); pointSet(circleSetInd,:)=[]; n=n+1; break end endendfigureimshow(oriPic)hold onfor i=1:n-1plot(circleSet{i}(:,2),circleSet{i}(:,1),'LineWidth',2)endend其它形状空心散点检测
来波正方形试试:
可以看出效果还是很棒的,当然大家可以根据实际情况自行更改图像腐蚀模板形状,如果散点是其它颜色请自行更改第一步的图像分割条件。
后注:
若是因为点较为密集而导致圈形路径内部白色区域没被清除,可能会将内部区域也算作散点造成错误,解决方法是计算每个联通区域面积并剔除远远大于区域面积中位数的联通区域:
问题出现原因的图片描述:
如图所示种间那一大片区域也被算作散点
更改后代码如下:
function redPntoriPic=imread('test2.png');figureimshow(oriPic)% 删除红色外的部分并构造二值图grayPic=rgb2gray(oriPic);grayPic(oriPic(:,:,1)<250)=255;grayPic(grayPic<250)=0;figureimshow(grayPic)% 图像膨胀,使未连接边缘连接SE=[0 1 0;1 1 1;0 1 0];bwPic=imerode(grayPic,SE);figureimshow(bwPic)% 边缘清理:保留圆圈联通区域bwPic=imclearborder(bwPic);figureimshow(bwPic)% 获取每一个联通区域[LPic,labelNum]=bwlabel(bwPic);% 筛掉超大区域pointSizeSet=zeros(1,labelNum);for i=1:labelNum pointSizeSet(i)=sum(sum(LPic==i));end[~,ind]=find(pointSizeSet>10*median(pointSizeSet));% 计算每一个联通区域 坐标均值pointSet=zeros(labelNum,2);for i=1:labelNum [X,Y]=find(LPic==i); Xmean=mean(X); Ymean=mean(Y); pointSet(i,:)=[Xmean,Ymean];endpointSet(ind,:)=[];figureimshow(bwPic)hold onscatter(pointSet(:,2),pointSet(:,1),'r','LineWidth',1)n=1;while ~isempty(pointSet) circleSetInd=1; for j=1:length(pointSet) disSet=sqrt(sum((pointSet-pointSet(circleSetInd(end),:)).^2,2)); [~,ind]=sort(disSet); ind=ind(1:min(5,length(ind))); [~,~,t_ind]=intersect(circleSetInd,ind); ind(t_ind)=[]; if ~isempty(ind) circleSetInd=[circleSetInd;ind(1)]; else circleSet{n}=pointSet(circleSetInd,:); pointSet(circleSetInd,:)=[]; n=n+1; break end endendfigureimshow(oriPic)hold onfor i=1:n-1plot(circleSet{i}(:,2),circleSet{i}(:,1),'LineWidth',2)endend注:
2016版本及以前可能这句:
disSet=sqrt(sum((pointSet-pointSet(circleSetInd(end),:)).^2,2));
会出现数组大小不匹配问题,可以将其改为:
tempMat=repmat(pointSet(circleSetInd(end),:),[size(pointSet,1),1]);disSet=sqrt(sum((pointSet-tempMat).^2,2));
以上是"Matlab空心散点检测的示例分析"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
区域
图像
坐标
边缘
红色
检测
均值
圆圈
白色
部分
问题
黑色
示例
分析
内容
图片
就是
形状
效果
篇文章
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
虹口区机电软件开发销售价格
华为v5服务器发布
徐州电商app软件开发
网络安全宣传 发言稿
网络安全管理标准制定
怎么打开数据库资源管理器
sql创建一个图书管理数据库
csgo平台服务器位置
操作系统怎么删除数据库
云开发 数据库 删查
美国信息网络安全会议新闻
时间服务器地址离线也可以用吗
渠道安全属于网络安全吗
芜湖星空网络技术有限公司
二本网络安全排行榜
南宫软件开发怎样收费
网络安全 sql注入
湘潭县网络安全检查
服务器 蓝屏 安全模式
服务器如何卸载jdk
数据库在每个表中录入数据
mysql数据库监听作用
4路服务器增加内存怎么加
sql数据库软件价格
梦幻西游甲组服务器
二手服务器回收
服务器100m
数控设备软件开发
服务器如何卸载jdk
数据库技术与应用读书笔记