MATLAB图像处理边缘检测

最近正好在做APMCM2019的A题,发现了matlab一些比较好用的函数,做一个学习笔记的作用如果大家有去了解这道题目的话,会发现它其实是需要你通过图像处理等方式,将114张SIO2融化的过程照片,去建模出SIO2晶体在融化过程中的一些规律比如:融化过程中质心的运动路径,融化过程中面积,周长,甚至是体积等随着时间变化的函数。

这道题目如果做过的话,会发现最坑的地方的就是图像的对比度,折磨了我蛮久的,发现了一些好用的工具和函数,写一篇文章记下来

看SIO2晶体那么一小块,和背景的对比度简直就是可怜

所以如何提取出那块SIO2晶体的主要流程就是:

1.剪裁图片只留下融化过程中sio2的运动路径所包含的图片的大小

2.图像灰度化

3.增强对比度

4.图像二值化

5.滤波降噪

6. 针对二值图像的形态学运算

7.边缘检测

1.剪裁图片只留下融化过程中sio2的运动路径所包含的图片的大小

img_name = [file_path,'0',int2str(j+496),'.bmp'];%文件名
        pitch=imread(img_name);
        pitch=imcrop(pitch,[690 430 330 350]);%剪裁图片大小

使用imcrop()这个函数,impcrop(图片,[x轴中心 y轴中心 截取长度 截取宽度])

2.图像灰度化

 pitch = rgb2gray(pitch);%灰度

调用rgb2gray函数即可,还有其他灰度化的函数也可以用,就不补充了

3.增强对比度

 pitch = histeq(pitch);%增强对比度
 pitch = imadjust(pitch);

这两个函数histeq()与imadjust()都是用于增强对比度,两个都是用于增强对比度的函数,只是内部的方法不一样,histeq的官方解释写的比较清晰,是使用直方图均衡增强对比度,imadjust则是调整图像强度值或颜色图,多在可以处理彩色图像的对比度。

 4.图像二值化

pitch = imbinarize(pitch0,0.8);%二值化图片

二值化我采用的是imbinarize()这个函数,后面的参数主要是给图片二值化设置阈值,范围[0,1],二值化主要是使灰度在0-255范围内设置阈值,最后归化为0与1,即黑或白,参数的调节很重要,会控制图片二值化的阈值,就是灰度到了多少才会区分黑与白的分水岭。

5.滤波降噪

 w = fspecial('gaussian',[2,2],0.02); %滤波降噪
 pitch=imfilter(pitch,w); %滤波降噪

滤波降噪采取的是高斯滤波,fspecial()创建预定义的二维滤波器,这个函数主要是生成二维滤波器的作用,下面的imfilter()主要作用就是将滤波器应用到图像中,高斯滤波主要是用于降低噪点等作用。

6. 针对二值图像的形态学运算

         pitch=bwmorph(pitch,'thicken',6);
         pitch=bwmorph(pitch,'majority',30);
         pitch=bwmorph(pitch,'spur',30);

bwmorph(BW,operation,n)这个函数还是蛮有意思的,对图像的处理功能还是相当丰富的·,matlab的中文说明写的是针对二值图像的形态学运算,个人通俗理解就是应用算法对图像进行处理,使得图像的边缘处理发生变化,比如骨架化,腐蚀等等,这个可以去matlab的mathwork网站查询,不明白的方法带入图片中试一试就知道是什么效果了,比如我这里就让图像更加圆滑,并且边缘的一些小白点也都让他合并在一起了,某种程度也算是降噪吧,但是这个函数的丰富程度远远不止降噪。

更多的operation见:针对二值图像的形态学运算 - MATLAB bwmorph - MathWorks 中国

 7.边缘检测

         bound = bwboundaries(pitch,8,'holes');%提取二氧化硅坐标

%         c=ones(1,30);
          s=ones(1,30);

        for n=1:n

         x = bound{n}(:,2);%提取x坐标
         y = bound{n}(:,1);%提取y坐标
     
         s(n)=polyarea(x,y);%计算面积
         V=polyshape(x,y);
         c(n)=perimeter(V);计算周长
   

其实前面的所有图像处理,都是为了边缘检测铺垫,边缘检测就是采用bwboundaries(pitch,8,'holes')这个函数,8主要是conn 指定跟踪父对象边界和子对象边界时要使用的连通性。‘holes’指的是是否检测图像内部的洞孔,如果填了'noholes',则代表只检测图像边缘。检测后的数据会记录成类似于bound{n}(y,x)这种类型,n代表的是,在这个图像中,检测到的第几个区域边界。

通过这个函数就可以把SIO2从图像中单独识别出来,进行后续的操作,比如计算面积等等。

完整代码

clear;clc;  
file_path =  '.\Attachment\';% 图像文件夹路径    
fprintf('正在读取的图像为:\n');  
j=input('选取第几张照片=');  
n=input('选取第几个识别物块=');  
  
        bw=0.9;  
  
  
        img_name = [file_path,'0',int2str(j+496),'.bmp'];%文件名  
        pitch=imread(img_name);  
        pitch=imcrop(pitch,[690 430 330 350]);%剪裁图片大小  
        pitch = rgb2gray(pitch);%灰度  
  
         pitch = histeq(pitch);%增强对比度  
         pitch = imadjust(pitch);  
         pitch = histeq(pitch);%增强对比度  
         pitch0 = imadjust(pitch);  
         pitch = imbinarize(pitch0,bw);%二值化图片  
  
         w = fspecial('gaussian',[2,2],0.02);%滤波降噪  
         pitch=imfilter(pitch,w);%滤波降噪  
  
%    pitch = edge(pitch,'sobel', 0.01);%提取边缘  
      pitch=bwmorph(pitch,'thicken',6);%提取边缘  
     pitch=bwmorph(pitch,'majority',30);%提取边缘  
     pitch=bwmorph(pitch,'spur',30);%提取边缘  
%    pitch=pitch-pitch0;  
  
  
         bound = bwboundaries(pitch,8,'holes');%提取二氧化硅坐标  
              c=ones(1,30);  
          s=ones(1,30);  
        for n=1:n  
         x = bound{n}(:,2);%提取x坐标  
         y = bound{n}(:,1);%提取y坐标  
  
         X=sum(x);%x的坐标和  
          x_average = X/length(x);%中心点x的坐标  
         Y=sum(y);%y的坐标和  
          y_average = Y/length(y);%中心点y的坐标  
       
         s(n)=polyarea(x,y);  
         S=max(s);  
         V=polyshape(x,y);  
         c(n)=perimeter(V);  
         C=max(c);  
         fprintf('第%d块,中心点=(%f,%f),面积=%f,周长=%f\n',n,x_average,y_average,S,C);  
  
         figure;%画图  
         subplot(1,3,1);  
         plot(x,y,'k')  
         subplot(1,3,2);  
         imshow(pitch);  
         subplot(1,3,3);  
         imshow(pitch0);  
        end  

猜你喜欢

转载自blog.csdn.net/weixin_52612260/article/details/122309693
今日推荐