Matlab空心散点检测的示例分析
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍Matlab空心散点检测的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题描述有一张这样的图片,如何提取里面的红色圈圈坐标,并且连接这些坐标形成两个封
千家信息网最后更新 2026年11月01日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安全错误
数据库的锁怎样保障安全
河南云网互联网络科技有限公司
互联网科技公司税收优惠
朗新科技与工业互联网
青岛互联网科技公司
艾特科技互联网
善班互联网科技有限公司
苏州大垚互联网科技
科技互联网创业计划书
天扬科技互联网广告
互联网科技大会案例
顶级互联网科技成果有哪些
互联网企业和科技型企业
速维有品互联网信息科技(苏州)有限公司
洛阳昕诺飞互联网科技有限公司
广州新华互联网科技学校电竞方面
广州富喜互联网络科技
科技和互联网行业的特点
北京军民互联网科技公司
互联网领先科技成果宣传视频
互联网科技自媒体灵感
天扬科技互联网广告
互联网科技项目计划书材料类
中国互联网十大科技股排名
国大互联网教育科技有限公司工作
天津腾达互联网科技有限公司
中国互联网公司排名锤子科技
恒生互联网科技业指数调整周期
互联网公司属于科技吗
北京品多多互联网科技有限公司
瑞安市蟠桃会互联网科技有限公司