圆度图像预处理、形态学优化、特征提取及显示(1)!!!

该代码段展示了使用MATLAB进行图像预处理,包括灰度转换、中值滤波、二值化以及形态学优化,以检测和计算图像中颗粒的圆度。通过边界提取、区域属性分析计算圆度指标,并根据阈值判断颗粒的圆度,将结果标注在图像上并输出至命令窗口和Excel文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

%颗粒圆度
%完成图像预处理%imread-rgb2gray-complement(0,1)-medfilt(GS)-imbinarize(graythresh)自动阈值控制边界轮廓,杂乱边界
%形态学优化    bwareaopen(bw,50); 
%特征提取及显示: 面积 周长 圆度 
clear;close all;
%% 预处理
I = imread('01.png');
figure;
subplot(231),imshow(I),title('rgb');
%读取源图像
h = rgb2gray(I);
subplot(232),imshow(h),title('gray');
%灰度图像

h = imcomplement(h);  %!!!
%subplot(233),imshow(h),title('h');
%取反,0,1 convert
h = medfilt2(h,[4,4]);
subplot(234),imshow(h),title('med');
%中值滤波

bw= im2bw(h,[0.90]);%graythresh(h)% []
subplot(235),imshow(h),title('graythresh');
%graythresh二值化
%bw = im2bw(h,0.1);
%subplot(236),imshow(bw),title('bw');
%自定义二值化

%% 形态学优化
bw=bwareaopen(bw,10);  %和yuandu_2 区别是:像素数小于50的去掉,
figure;
subplot(221),imshow(bw),title('bwareaopen');
%去掉像素数低的目标(腐蚀=bwareaopen),像素数小于30的(30根据具体应用中目标的大小调节),关键点理解图像连通域的含义。
se = strel('disk',2);
%结构元素半径为2的圆,
%二值图像去除小区域后,对大区域中的缝隙填充(膨胀close),同时平滑边界
%膨胀腐蚀所用圆单元,需要注意参数2需要调试,以满足不同场合应用。
bw = imclose(bw,se);
subplot(222),imshow(bw);title('close')
%close运算平滑轮廓
%bw = imfill(bw,'holes');
%subplot(223),imshow(bw);title('fill')
%imfill 填补闭合图形,填充色为白色;在上一步先腐蚀膨胀之后,对连通域填孔(fill),使其变为实心体。
%bw=edge(bw,'canny');
%subplot(224),imshow(bw), title('edge'); 
%canny 边缘提取

%%
[B,L] = bwboundaries(bw,'noholes');
%边界提取,返回一个含有k个cell数组(B是边界像素位置,)。L是标记矩阵[0,1],标识图像区域中全部目标点

figure;imshow(label2rgb(L, @jet, [.5 .5 .5])),title('boundary');
% 为每个闭合图形[0,1] L 设置颜色显示(@jet对不同目标显示不同颜色)

hold on% 图像保持
for k = 1:length(B) %K表示B单元数组中的第k个cell。即代表第k个边界区域。
  boundary = B{k};  %计算k个边界的所有点
  plot( boundary(:,2),boundary(:,1), 'r', 'LineWidth', 2)
   %(:,2) 第二列的所有元素,   plot 用红色 r 框来显示边界  线宽是2 
end   
%%
  stats = regionprops(L,'Area','Centroid');
%计算面积 regionprops  %求出标记矩阵L中,各个区域的面积Area和质心Centroid
for k = 1:length(B)  
  % 循环处理每个边界,length(B)是闭合图形的个数,即检测到的边界对象个数
  boundary = B{k}; 
  % 获取边界坐标
  delta_square = diff(boundary).^2; %x,y增量平方
  perimeter = sum(sqrt(sum(delta_square,2))); %sum(A,n)表示将矩阵A沿着第n个维度(列)求和。
  perimeter_string = sprintf('%2.3f', perimeter); % '%2.3f' 2个宽度,保留3位小数!!!
  % 计算周长
  area = stats(k).Area; 
  area_string = sprintf('%2.3f', area);
  % 对标记为K的对象获取面积
  metric = (4*pi*area)/((perimeter)^2);  
  % 圆度计算公式4*PI*A/P^2
  metric_string = sprintf('%f\n',metric);
  % 在工作空间显示结果 sprintf,区别 fprintf
  %%
  threshold = 0.4;
if metric > threshold  
     centroid = stats(k).Centroid;
    plot(centroid(1),centroid(2),'k*');
     % 用一个黑色 小圆圈'ko' 'k*' 'r*' 标记圆度大于threshold 的对象质心
end

  text(boundary(1,2)-30,boundary(1,1)+13,metric_string,...
     'Color','y','FontSize',12,'FontWeight','bold');
   text(boundary(1,2)+35,boundary(1,1)+26,strcat('Area:',area_string),...
     'Color','r','FontSize',12,'FontWeight','bold');
 text(boundary(1,2)+35,boundary(1,1)+56,strcat('Perimeter:',perimeter_string),...
     'Color','r','FontSize',12,'FontWeight','bold');
  title('圆度识别结果:越圆越接近1,');
 %设置图形显示 位置:相对左边界x,y  显示内容:metric_string/ strcat
 %颜色'Color'黄色'y' 字号 'FontSize',14,字形加粗'FontWeight','bold'
 
 fprintf('round_area = %f\n', area);   % 在命令窗口输出高精度\n结果
 fprintf('perimeter_string = %f\n', perimeter);
 fprintf('metric_string = %f\n', metric);
  xlswrite('test.xls',area) ; % ??? 输出到表格中 待修改
 end

%颗粒圆度
%完成图像预处理%imread-rgb2gray-complement(0,1)-medfilt(GS)-imbinarize(graythresh)自动阈值控制边界轮廓,杂乱边界
%形态学优化    bwareaopen(bw,50); 
%特征提取及显示: 面积 周长 圆度 
clear;close all;
%% 预处理
I = imread('01.png');
figure;
subplot(231),imshow(I),title('rgb');
%读取源图像

源图像: 目标识别区域和背景区域颜色应该相反,边界识别会更准确


h = rgb2gray(I);
subplot(232),imshow(h),title('gray');
%灰度图像gray(8bit)



%h=rgb2hsv(h);    (扩展:颜色空间)
%subplot(2,2,2),imshow(hsv);
%h=h(:,:,1);%显示 v分量 
%subplot(2,2,3),imshow(v);
% 转化 RGB 值为 HSV 颜色空间 


h = imcomplement(h);  %!!!    看是否需要
%subplot(233),imshow(h),title('h');
%取补,255(1) - convert  %黑白互补,灵活调整计算区域(白色),配合二值化操作,一般在二值化之前(会影响二值化的阈值),若在之后(非0即1)(一般是二值化结果特别好,取反可以直接获得二值化对立的结果)


h = medfilt2(h,[4,4]);
subplot(234),imshow(h),title('med');
%中值滤波

%sigma = 1;
%gausFilter=fspecial('gaussian',[5 5],sigma);
%h= imfilter(h, gausFilter, 'replicate');
%subplot(235),imshow(h),title('gaus');  %高斯滤波 和中值滤波可以合用,会稍微提高均匀度

%bw= im2bw(h,graythresh(h)]);  %graythresh(h)%
%subplot(235),imshow(h),title('graythresh');
%graythresh二值化   % 出现多个白色干扰区域,不利于精确提取,但可以参考
bw = im2bw(h,0.1);
subplot(236),imshow(bw),title('bw');
%自定义二值化       阈值选取是 保证图形识别精度的关键,调整阈值使小圆点刚刚消失(误差在百分位)    像素值大于阈值 变为白色
%level_1=graythresh(h);  % 可以获取全局阈值 作为参考值
%level_2=0.1
%bw = im2bw(h,
level_); %  此结构更灵活


BWimg = grayimg;    (扩展:循环处理二值化)
[width,height]=size(grayimg);
T1=80;
for i=1:width
    for j=1:height
        if(grayimg(i,j)<T1)
            BWimg(i,j)= 255;
        else 
            BWimg(i,j)= 0;
        end
    end
end
figure(3);
imshow(BWimg);
 %二值化
 



%bw = imcomplement(bw );  % 一般是二值化结果特别好,取反可以直接获得二值化对立的结果)
   %相当于取 二值化阈值的补(1-level_2)。

%% 形态学优化
bw=bwareaopen(bw,10);  %和yuandu_2 区别是:像素数小于50的去掉,
figure;
subplot(221),imshow(bw),title('bwareaopen');
%抹去目标外围小连通域(抹去小的白色圆点变为黑色)对目标一般无影响(腐蚀=bwareaopen??),像素数小于30的(30根据具体应用中目标的大小调节),关键点理解图像连通域的含义。阈值根据拟抹除连通域的最大值设定。只有连通域大于设定阈值的区域可以保留下来(变为白色)  通过区域大小标定白色区域,当有多个独立连通域时可与自动阈值graythresh(h) 搭配有奇效


se = strel('disk',2);
%结构元素半径为2的圆,
%二值图像去除小区域后,对大区域中的缝隙填充(膨胀imclose),同时平滑边界
%膨胀腐蚀所用圆单元,需要注意参数2需要调试,以满足不同场合应用。
bw = imclose(bw,se);
subplot(222),imshow(bw);title('close')
%imclose运算平滑轮廓

%bw = imopen(bw,se);
%subplot(223),imshow(bw);title('open') 
%imopen运算 ???


%bw = imfill(bw,'holes');
%subplot(223),imshow(bw);title('fill')
%imfill 填补闭合图形,填充色为白色;在上一步先腐蚀膨胀之后,对连通域填孔(fill),使其变为实心体。用来获取外轮廓


%bw=edge(bw,'canny');
%subplot(224),imshow(bw), title('edge'); 
%canny 边缘提取

%% 特征提取
[B,L] = bwboundaries(bw,'noholes');
%边界提取(各部分白色区域的边界),返回一个含有N*M的 cell数组(B是边界像素位置,)。L是标记矩阵[0,1]矩阵,标识图像区域中全部目标

figure;imshow(label2rgb(L, @jet, [.5 .5 .5])),title('boundary');
% 为每个闭合图形[0,1] 矩阵 L 设置颜色显示(@jet对不同目标显示不同颜色)

hold on% 图像保持
for k = 1:length(B)    %K表示B单元数组中(1-N)个cell。即代表1-N个边界区域。
  boundary = B{k};    %计算第k个边界的所有点坐标
  plot( boundary(:,2),boundary(:,1), 'r', 'LineWidth', 2)
   %(:,2) 第二列的所有元素,   plot 用红色 r 框来显示边界  线宽是2 
end   
%%
  stats = regionprops(L,'Area','Centroid');
%计算面积 regionprops  %求出标记矩阵L中,各个区域的面积Area和质心Centroid


for k = 1:length(B)  
  % 循环处理每个边界,length(B)是闭合图形的个数,即检测到的边界对象个数
  boundary = B{k}; 
  % 获取边界坐标
  delta_square = diff(boundary).^2; %x,y增量平方
  perimeter = sum(sqrt(sum(delta_square,2))); %sum(A,n)表示将矩阵A沿着第n个维度(列)求和。
  perimeter_string = sprintf('%2.3f', perimeter); % '%2.3f' 2个宽度,保留3位小数!!!
  % 计算周长  此方法用公式计算的周长精度高,regionprops获取的周长偏大。


  area = stats(k).Area; 
  area_string = sprintf('%2.3f', area);
  % 对标记为K的对象获取面积
  metric = (4*pi*area)/((perimeter)^2);  
  % 圆度计算公式4*PI*A/P^2
  metric_string = sprintf('%f\n',metric);   
  % 在工作空间显示结果 sprintf,区别 fprintf

%字符串格式


  %%  结果输出
  threshold = 0.4;
if metric > threshold  
     centroid = stats(k).Centroid;
    plot(centroid(1),centroid(2),'k*');
     % 用'ko'(黑圈)'k*'(黑星) 'r*'(红星) w g b y r k 标记圆度大于threshold 的对象质心
end

  text(boundary(1,2)-30,boundary(1,1)+13,metric_string,...
     'Color','y','FontSize',12,'FontWeight','bold');
   text(boundary(1,2)+35,boundary(1,1)+26,strcat('Area:',area_string),...
     'Color','r','FontSize',12,'FontWeight','bold');
 text(boundary(1,2)+35,boundary(1,1)+56,strcat('Perimeter:',perimeter_string),...
     'Color','r','FontSize',12,'FontWeight','bold');
  title('圆度识别结果:越圆越接近1,');
 %text 设置图上显示 位置:相对左边界x,y  显示数值内容:metric_string 或者(strcat(‘显示字符串:’,数值),)
 %颜色'Color'黄色'y' 字号 'FontSize',12,字形加粗'FontWeight','bold'
 
 fprintf('round_area = %f\n', area);   % 在命令窗口输出高精度\n结果
 fprintf('perimeter_string = %f\n', perimeter);
 fprintf('metric_string = %f\n', metric);
 %% xlswrite('test.xls',area) ; % ??? 输出到表格中 待修改
 end

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值