Matlab空心散点检测的示例分析
发表于:2025-02-22 作者:千家信息网编辑
千家信息网最后更新 2025年02月22日,这篇文章主要介绍Matlab空心散点检测的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题描述有一张这样的图片,如何提取里面的红色圈圈坐标,并且连接这些坐标形成两个封
千家信息网最后更新 2025年02月22日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安全错误
数据库的锁怎样保障安全
网络安全三大协议
桂阳附近安卓软件开发
软件开发技术服务质量要求
石景山区网络技术服务采购
jsp 数据库 表单
远程新华网络技术公司
上海软件开发解决方案应用
网络安全7手抄报内容
数据库的3种基本运算
黄石软件开发公司排名
新乡趣游网络技术有限公司
如何防止网络安全被黑
任何个人有权举报危害网络安全
网络服务器系统管理实训报告
诺顿网络安全特警强制
公司邮件服务器怎么查
做软件开发要学什么编程
网络安全蓝色背景图片
战舰世界的服务器
数据库分析师待遇
建立学校网络安全工作台账
需要多长时间部署云服务器
电脑正版mc怎么进服务器
应用软件开发竞争性谈判文件
计算机网络技术指什么
下载什么数据库方便
天地图一键制图功能数据库
如何在手机上建立我的世界服务器
常见网络安全问题
网络安全职业体系标准