matlab 图形处理小记

%颗粒圆度yuandu


clear;close all;
%%
%读取源图像
I = imread('01.png');
figure;imshow(I),title('rgb');



%%
h = rgb2gray(I);
figure;imshow(h),title('gray');
%灰度图像

h = imcomplement(h);
%取反,0,1 convert
figure;imshow(h),title('h');
%%

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


bw = im2bw(h,graythresh(m));
%二值化 (自动阈值)
figure;imshow(bw),title('bw');  

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);
 %二值化 loop mode 阈值T1=80,

bw=imbinarize(I2,0.1);%手动阈值(0-1)二值化 
figure(2);
subplot(2,2,1),imshow(bw), title('bw');

t1=graythresh(h) 

t2=0.1

bw = im2bw(h,t1);

bw = im2bw(h,t2);
%二值化 
figure;imshow(h),title('bw'); 


%% 形态学优化
bw=bwareaopen(bw,30);
figure;imshow(bw),title('bwareaopen');   % 开
%去掉小目标(腐蚀=bwareaopen),像素数小于30的30根据具体应用中目标的大小调节),关键点理解图像连通域的含义。

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

bw = imfill(bw,'holes');
figure;imshow(bw);title('fill') 

%填补闭合图形,填充色为白色;在上一步先腐蚀膨胀之后,对连通域填孔(fill),使其变为实心体。
%%

[B,L] = bwboundaries(bw,'noholes');
%边界寻找 ,B是边界像素位置,cell组。L是标记矩阵,标识图像中目标个数

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

%所有目标边界白色显示

hold on
for k = 1:length(B)
  boundary = B{k};
  plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)
end

%%
%计算面积 regionprops
stats = regionprops(L,'Area','Centroid');

%threshold = 0.94;

for k = 1:length(B)  
  % 循环处理每个边界,length(B)是闭合图形的个数,即检测到的陶粒对象个数
  boundary = B{k}; 
  % 获取边界坐标
  delta_sq = diff(boundary).^2;  % 相邻两点坐标x、y差的平方
  perimeter = sum(sqrt(sum(delta_sq,2)));  差平方的和的开方(斜边)再求和
  % 计算周长,此法精度较高(可检验)

  area = stats(k).Area; 
  % 对标记为K的对象获取面积
  metric = 4*pi*area/perimeter^2;  
  % 圆度计算公式4*PI*A/P^2
  metric_string = sprintf('%2.2f',metric);
  % 结果显示

threshold = 0.94;
if metric > threshold  
    % 用一个黑色小圆圈'ko'标记圆度大于threshold = 0.94 的对象
    centroid = stats(k).Centroid;
    plot(centroid(1),centroid(2),'ko'); % '*'  'ro' 红色圆
end

  text(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','y',...
       'FontSize',14,'FontWeight','bold');  

% 在指定位置,标记圆度数值,颜色,字号,加粗
  title('圆度识别结果,越圆越接近1,');
 %标题显示

end


% run normal 标记连通域计算选定区域周长、面积、离心率(注释版)t1

clc;
close all;
clear all;

img=imread('11.bmp'); 
figure;
imshow(img);
%读取、显示原图像

grayimg = rgb2gray(img);
figure(2);
imshow(grayimg);
%灰度化

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);
 %二值化 loop mode 阈值T1=80, 

se=strel('disk',1);
BWimg = imclose(BWimg,se);
BWimg = imopen(BWimg,se);
figure(4);
subplot(2,2,4);imshow(BWimg);title('形态学操作后的图像');
%先闭运算 再开运算
%%


[mark_image,num] = bwlabel(BWimg,4); 
%统计标注连通域 bwlabel
%参考博客https://blog.csdn.net/wanrenwangxuejing/article/details/25108191
%bwlabel 寻找连通区域,    4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的;8的范围更大
%num 表示连通区域的个数,工作区可查看数量,图上可看到标签值
%L=mark_image是大小和BWing一样的图像数组,里面存放着对bwing图像的标签值(即判定为连通后,在L矩阵中标记出来标签值)
 %%


%regionprops 介绍,参考 :https://blog.csdn.net/langb2014/article/details/49886787
%STATS = regionprops(L,properties)
%描述:测量标注矩阵L中每一个标注区域的一系列属性。L中不同的正整数元素对应不同的区域,
%例如:L中等于整数1的元素对应区域1;L中等于整数2的元素对应区域2;以此类推。
%返回值STATS是一个长度为max(L(:))的结构数组,结构数组的相应域定义了每一个区域相应属性下的度量
stats=regionprops(mark_image,'BoundingBox');
%使用外接矩形框选连通域, 

centroid = regionprops(mark_image,'Centroid');
%并使用形心确定连通域位置

figure;
imshow(mark_image);title('标记后的图像');
 %统计标注连通域,bwlabel 需用于 regionprops函数前 ,下一步标记数字
 
for i=1:num
    rectangle('position',stats(i).BoundingBox,'edgecolor','r');
    %参考https://blog.csdn.net/zr459927180/article/details/51152094
    %参数说明:position绘制的为二维图像(他是通过对角的两点确定矩形框)
    %edgecolor 指边缘图像,r表示变换为红色。
    %facecolor 指内部填充颜色。
    text(centroid(i,1).Centroid(1,1)-15,centroid(i,1).Centroid(1,2)-15, num2str(i),'Color', 'r') 
    %这个是为绘制出来的矩形框图逐个标记数字i=num,在上图直接标注
end

%%
copy_mark_image = mark_image; % 用复制的图像进行处理
image_part3 = (copy_mark_image == 3); %%这边进行区域的选择,例如只保留3
% image_part3 = (mark_image ~= 3); 
figure;
imshow(image_part3);
 
% total = bwarea(image_part3); % bwarea 面积误差
% fprintf('total = %f\n', total);
round_area = regionprops(image_part3,'Area');
fprintf('round_area = %f\n', round_area.Area);
 %求面积 打印

girth = regionprops(image_part3,'Perimeter');
%girth.Perimeter 这里不知道什么意思
fprintf('s.Perimeter = %f\n', girth.Perimeter);
%求周长 打印
 C=(4*pi* round_area.Area)/girth.Perimeter^2;
fprintf('c = %f\n', C);

%这边进行区域的选择,例如保留10
image_part10 = (mark_image == 10);    
figure;
imshow(image_part10);
 
%求红色椭圆10的离心率
oval = regionprops(image_part10,'Eccentricity');%离心率 0 < e < 1之间,e越小,越像圆。
% oval.Eccentricity
fprintf('oval.Eccentricity = %f\n', oval.Eccentricity);


% 单个图像的处理,轮廓面积周长像素获取(注释版)t3


% 精度不够
clc;clear all;close all;

I=imread('01.png');
figure;imshow(I);
I2=rgb2gray(I);
% 灰度化

[junk, threshold] = edge(I2,'sobel');
fudgeFactor=.5; 
BWs=edge(I2,'sobel',threshold*fudgeFactor);
figure;
subplot(221),imshow(BWs),title('边缘梯度二值掩膜');

se90=strel('line',3,90);
se0=strel('line',3,0);
BWsdil=imdilate(BWs,[se90 se0]);
subplot(222);imshow(BWsdil),title('膨胀梯度掩膜');

BWdfill=imfill(BWsdil,'holes');
subplot(223);imshow(BWdfill);title('填充空洞后的二值图像');

BWnobord=imclearborder(BWdfill,4);
subplot(224);imshow(BWnobord),title('清除边缘的二值图像');

k1=bwlabel(BWnobord);% bwlable 干嘛的
I5=~BWnobord;   % 颜色取反
figure;imshow(I5);
%%
%k1=bwlabel(BWnobord);% 颜色取反后的
a=max(max(k1));
[labeled,numObjects]=bwlabel(BWnobord,4);% 4连通
celldata=regionprops(labeled,'all');
% 图形信息在regionprops 返回值
for i=1:1:a
celldata(i).Area
celldata(i).Perimeter;
end
% 逐点统计regionprops返回值中面积、周长信息
allcellm=[celldata.Area];
% 从 regionprops 返回值中获取统计的面积像素
allcellz=[celldata.Perimeter];
% 从 regionprops 返回值中获取统计的周长像素
%%
m=sum(allcellm);
% 面积求和
z=sum(allcellz);
%周长求和
b=4*pi*m/z^2;


%计算颗粒圆形度stone0


close all;
clear all;
clc;%清除所有内存变量、图形窗口
I=imread('01.png');
%将图像文件 1.jpg 的图像像素数据读入矩阵 I 
figure(1);
subplot(2,3,1),imshow(I),title('rgb');

I1=rgb2hsv(I);  
subplot(2,3,2),imshow(I1),title('rgb2hsv');
V=I1(:,:,1);   
subplot(2,3,3),imshow(V);title('hsv2V分量')
%%转化 RGB 值为 HSV /gray 颜色空间 
%%显示 v 分量 

I2=rgb2gray(I);  
subplot(2,3,4),imshow(I2),title('rgb2gray');
%h=imcomplement(I2);
%subplot(2,3,5),imshow(h);
%求补运算 

% h=medfilt2(I2,[4,4]); 
% 中值滤波 

bw=imbinarize(I2,0.001);%graythresh二值化 
figure(2);
subplot(2,2,1),imshow(bw), title('bw');

%计算将灰度图像转化为二值图像所需的门限imbinarize/im2bw
%bw1=imfill(bw,'holes');
%区域填充 imfill
%subplot(2,2,2),imshow(bw1), title('fill'); 

bw2=imclose(bw,strel('disk',1));
%采用半径为 1 的圆disk作为结构元素strel(越小重合度越高),进行闭合运算 imclose
subplot(2,2,3),imshow(bw2), title('imclose'); 

bw3=edge(bw2,'canny');
subplot(2,2,4),imshow(bw3), title('canny_edge'); 
%canny 边缘提取

%%
[B,L] = bwboundaries(bw,'noholes');
%边界寻找 ,B是边界像素位置,cell组。L是标记矩阵,标识图像中目标个数
figure;imshow(label2rgb(L, @jet, [.5 .5 .5])),title('bound');
% 为每个闭合图形设置颜色显示; @jet对不同目标显示不同颜色

hold on %保持图形,在其上操作
for k = 1:length(B)
  boundary = B{k};
  plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)
end   % plot 用白色w 显示边界  线宽2
%%
[x,y]=size(bw3);
BW=bwperim(bw3,8);
%检测目标的边缘跟踪,用于计算周长 
M1=0; 
M2=0;
Ny=0;
%记录垂直方向边界连续像素点的个数 
for i=1:x
for j=1:y
if(BW(i,j)>0) 
  M2=j;
     if((M2-M1)==1)
    %判断是否为垂直方向连续的边界像素点 
    Ny=Ny+1;
      end
 M1=M2;
 end
end
end
M1=0;
M2=0;
Nx=0;
%记录水平方向连续边界像素点的个数 
for j=1:y
for i=1:x
if(BW(i,j)>0) 
M2=i;
if((M2-M1)==1)%判断是否为水平方向连续的边界像素点
    Nx=Nx+1; 
end
M1=M2;
end
end
end

SN=sum(sum(BW));%计算周长像素点的总数 
Nd=SN-Nx-Ny;    %计算奇数码的链码数目
L=sqrt(2)*Nd+Nx+Ny;
P = sprintf('%2.2f',L/2);
%计算、打印周长 
[l,num]=bwlabel(bw3);
stats=regionprops(l,'Area');
A=stats.Area;
area_string = sprintf('%2.2f', A);
%计算目标区域面积 
C=(4*pi*A)/((L/2)^2);
%计算圆形度 L 为周长,A 为面积,C 为圆形度
  metric_string = sprintf('%2.2f',C);
  text(boundary(1,2)+20,boundary(1,1)+13,strcat('Area:',area_string),...
     'Color','y','FontSize',14,'FontWeight','bold');
  text(boundary(1,2)+190,boundary(1,1)+13,strcat('metric:',metric_string),...
     'Color','R','FontSize',14,'FontWeight','bold');
 text(boundary(1,2)+300,boundary(1,1)+13,strcat('P:',P),...
     'Color','B','FontSize',14,'FontWeight','bold');
 


%% 检测出圆形物体

%功能:检测圆形物体
%输入:读入检测的图像;修改近似为圆形的度量值(0,1)之间
%输出:标记图像中圆形物体

%% 第一步,图像二值化

%读取图像
I_rgb=imread('1.png');

figure,imshow(I_rgb);
%真彩图转化为灰度图

I_gray=rgb2gray(I_rgb);

% figure,imshow(I_gray);

%

%灰度图转化为二值图像,需要注意的是二值化阈值大小在[0,1]之间

%本文阈值level可以用Otsu方法获取,全局阈值。采用函数graythresh

level=graythresh(I_gray);

I_bw=im2bw(I_gray,level);

% figure,imshow(I_bw);

%% 第二步,找到物体边界。关键点是:图像“缝隙”和“孔洞”的概念和填补方法

%去掉小目标,像素数小于30的,关键点理解图像连通域的含义。
%这个30根据具体应用中目标的大小调节

bw1=bwareaopen(I_bw,30);

% figure,imshow(bw1);

%二值图像去除小区域后,对大区域中的缝隙填充,同时平滑边界

%膨胀腐蚀所用圆单元,需要注意参数3需要调试,以满足不同场合应用。

se=strel('disk',3);

bw2=imclose(bw1,se);

% figure,imshow(bw2);

%在上一步先腐蚀膨胀之后,对连通域填孔,使其变为实心体。

bw3=imfill(bw2,'holes');

% figure,imshow(bw3);

[B,L]=bwboundaries(bw3,'noholes');
%显示图像的边界,B是边界像素位置,cell组。L是标记矩阵,标识图像中目标个数

L_bw=label2rgb(L,@jet,[.5,.5,.5]);
%L_bw对不同目标显示不同颜色,目标边界白色显示
figure,imshow(L_bw);

hold on

for k=1:length(B)

B_object=B{k};

plot(B_object(:,2),B_object(:,1),'w','Linewidth',2);%白色显示边界

end

%% 第三步,找出圆形目标

%求出标记矩阵L中,各个区域的面积和质心

property=regionprops(L,'Area','Centroid');

%判断图像中每个目标是否近似为圆形

for k2=1:length(B);

B_object2=B{k2};

delta=diff(B_object2).^2;

%周长

perimeter=sum(sqrt(sum(delta,2)));

%面积

area=property(k2).Area;

area_str=sprintf('%2.2f',area);

%近似为圆形度量值test,越接近1标识越近似圆

test=(4*pi*area)/(perimeter^2);

test_str=sprintf('%2.2f',test);

if test>0.9  %重要!假若度量值大于0.9,就认为是圆形,加入这条if只显示满足条件的圆形

%标记圆心

centroid=property(k2).Centroid;

plot(centroid(1),centroid(2),'*','Color','k');

%数值显示

text(B_object2(1,2)-85,B_object2(1,1)+13,strcat('近似比:',test_str));

text(B_object2(1,2)-85,B_object2(1,1)-3,strcat('面积:',area_str));

end

end

title('大于度量值0.9可以认为是圆形,该度量值可以自由设定');
%————————————————
%版权声明:本文为CSDN博主「weixin_39736047」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
%原文链接:https://blog.csdn.net/weixin_39736047/article/details/111737074


close all
coin_width=1.000;
coin_height=1.000;
I=imread('01.png');
figure(1),imshow(I);title('原图像');

%转换为灰度图像
I1=rgb2gray(I);
%figure(2);imshow(I1);title('灰度图像');

I1=imbinarize(I1,0.9);% 二值化0()1
sigma = 1;
gausFilter=fspecial('gaussian',[5 5],sigma);
I2= imfilter(I1, gausFilter, 'replicate');
figure(2);imshow(I2);title('高斯滤波后图像');

I3=edge(I2,'Canny',0.1);
figure(3),imshow(I3);title(' Canny边缘检测图像');% 检测所有的白色区域的边缘

 % 孔洞填充 imfill,内部均被255色填充 只保留最外侧轮廓
% I41=imfill(I3,'holes');            
% figure(4),imshow(I41);title('孔洞填充图像'); 

% 只提取最外围边缘,与imfill合用精度更高。
I4=bwperim(I41);                   
figure(5),imshow(I4); title('边缘提取图像');

% 去除面积小于150px物体,去除小区域干扰
I5=bwareaopen(I4,150);    
figure(6),imshow(I5);

[labelpic,num] = bwlabel(I5,8);  % 标记8连通域
[r, c]=find(labelpic==1);
% 获取标记物体最小外接矩形坐标点

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值