%颗粒圆度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);
% 获取标记物体最小外接矩形坐标点