关于#matlab#的问题:平滑图中曲线并计算每个同心圆的直径(毫米做单位)

img

平滑图中曲线,并计算图中每个同心圆的直径(毫米做单位)。
这是等倾干涉环细化后的图像。

我用的图像

img

我目前的代码

0%-----------------------第一部分(读取)---------------------------------
%读取图片
A1=imread('51um.jpg');
%真彩转灰度
A2=rgb2gray(A1);
figure,imshow(A2),title('result');
%-----------------------第二部分(增强)---------------------------------
%直方图均衡化
B1=adapthisteq(A2); 
figure,imshow(B1),title('result');
%-----------------------第三部分(降噪)---------------------------------
%均值滤波
C1= filter2(fspecial('average',7),B1)/255;%-
C2 = medfilt2(C1);                                  
%中值滤波部分
C3=medfilt2(C2,[7,7]);    %--
%低通滤波
[f1,f2] = freqspace(size(C3),'meshgrid'); %生成频率序列矩阵
Hd = ones(size(C3));   
r = sqrt(f1.^2 + f2.^2); 
Hd(r>0.5) = 0;   %构造滤波器
Y=fft2(double(C3));   
Y=fftshift(Y);   
Ya=Y.*Hd;   %滤波
Ya=ifftshift(Ya);   
C4=ifft2(Ya);
figure,imshow(C4),title('result');
%最大类间方差法分割图像
level=graythresh(C4);
E1=imbinarize(C4,level);             
disp(strcat('graythresh 计算灰度阈值1:',num2str(uint8(level*255))));
figure,imshow(E1),title('result');
%闭运算
se2=strel('disk',7);
F1=imclose(E1,se2);    
%细化
F2=zs(F1);
figure,imshow(F2),title('result');
F3=bwmorph(F2,'spur',Inf);
F4=bwmorph(F3,'bridge');
figure,imshow(F4),title('result');

TechWhizKid参考GPT回答:

img


%-----------------------第一部分(读取)---------------------------------
%读取图片
A1=imread('A.png');
%真彩转灰度
A2=rgb2gray(A1);
figure,imshow(A2),title('result');

%-----------------------第二部分(增强)---------------------------------
%直方图均衡化
B1=adapthisteq(A2); 
figure,imshow(B1),title('result');

%-----------------------第三部分(降噪)---------------------------------
%均值滤波
C1= filter2(fspecial('average',7),B1)/255;%-
C2 = medfilt2(C1);                                  
%中值滤波部分
C3=medfilt2(C2,[7,7]);    %--
%低通滤波
[f1,f2] = freqspace(size(C3),'meshgrid'); %生成频率序列矩阵
Hd = ones(size(C3));   
r = sqrt(f1.^2 + f2.^2); 
Hd(r>0.5) = 0;   %构造滤波器
Y=fft2(double(C3));   
Y=fftshift(Y);   
Ya=Y.*Hd;   %滤波
Ya=ifftshift(Ya);   
C4=ifft2(Ya);
figure,imshow(C4),title('result');

%最大类间方差法分割图像
level=graythresh(C4);
E1=imbinarize(C4,level);             
disp(strcat('graythresh 计算灰度阈值1:',num2str(uint8(level*255))));
figure,imshow(E1),title('result');

%闭运算
se2=strel('disk',7);
F1=imclose(E1,se2);    

%细化
F2 = bwmorph(F1, 'thin', Inf);
figure,imshow(F2),title('result');
F3=bwmorph(F2,'spur',Inf);
F4=bwmorph(F3,'bridge');
figure,imshow(F4),title('result');


%-----------------------第四部分(计算同心圆直径)---------------------------------
% 对边缘检测结果进行填充,得到完整的同心圆
F5 = imfill(F4, 'holes');
figure,imshow(F5),title('Filled Image');

% 使用regionprops函数计算各区域的面积和边界矩形
props = regionprops(F5, 'Area', 'BoundingBox');
% 对每个区域计算直径
minArea = 100; % 设置面积最小值,过滤掉小于这个面积的圆

for k = 1 : length(props)
   % 计算区域面积
   area = props(k).Area;

   % 如果面积大于设定的最小值,才计算和打印直径
   if area > minArea
       % 计算区域对应的同心圆直径,假设每个像素对应1毫米
       diameter = sqrt(area / pi) * 2;  % 因为面积 = pi * (d / 2)^2

       fprintf('Region %d, Diameter = %f mm\n', k, diameter);
   end
end

plot函数用于绘制同心圆,scatter函数用于绘制五个点,sprintf函数用于在图像上显示每个同心圆的直径。
参考代码:

img = imread('your_image.jpg');  
gray_img = rgb2gray(img);  
bw_img = imbinarize(gray_img);  
[d, idx] = imfree(bw_img);  
imshow(bw_img);  
title('Centered Circles');  
for i = 1:size(d, 1)  
    for j = 1:size(d, 2)  
        if d(i, j) > 0  
            plot(round(i), round(j), 'ro');  
            hold on;  
            plot(d(i, j), d(i, j), 'r--');  
            scatter(round(i), round(j), 5);  
            axis equal;  
            text(round(i), round(j), sprintf('Radius: %.2f', d(i, j)));  
        end  
    end  
end
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/1070838
  • 你也可以参考下这篇文章:一级倒立摆状态空间建模,离散化,Matlab仿真,添加高斯噪声并采用卡尔曼滤波去噪
  • 除此之外, 这篇博客: Matlab 绘制三维平面、二维曲线 以及 遇到的问题中的 一、绘制三维平面(一个因变量两个自变量) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 借鉴这篇文章,说的很详细。

     【MATLAB】MATLAB三维曲面绘制【详细教程】_风小新的博客-CSDN博客_matlab三维曲面图

    记录一下主要的思路:

     (1)给出两个自变量的范围,可以用linspace函数,也可以直接写i=0:0.1:1这样

    (2)这一步很关键,一定要用meshgrid()函数将两个自变量变为矩阵,要不然无法计算因变量

    (3)给因变量赋值,也就是用代码去表达公式

    (4)直接用mesh函数绘制就完事了

    (5)其他具有修饰性意义的功能,比如增加图例,增加x和y轴标注、平面颜色等等上网一搜就能搜到代码。

    给出我的例子(可直接运行):

    clear;clc; %清除前置数据
    %常量定义
    ab = 0.10; % αb
    bb = 0.20; % βb
    bs = 0.22; % βs
    tb = 0.35; % tb 
    ts = 0.30; % ts 
    cta = 1; %就是那个C塔
    
    %曲面数据处理
    i = linspace(0,1,50); %设置自变量i的范围 [0,1]
    f = linspace(0,1,50); %设置自变量f的范围[0,1]
    [I,F] = meshgrid(i,f); %将其i,f轴变为矩阵
    CS = 3/8 - I*ab + ab - (4*F+3*bs*bs+10*bs*bb+3*bb*bb)/(12*ts);% 公式
    
    
    
    %绘制
    Fig = mesh(I,F,CS); % 绘制三维曲面图
    hold on;
    axis([0,1,0,1]); %坐标范围设置,X轴和Y轴一定要和自变量i和f的范围保持一致!!!Z轴怎么好看怎么设置
    
    
    L(1) = xlabel('$i$','interpreter','latex','FontSize',15);
    L(2) = ylabel('$f$','interpreter','latex','FontSize',15);
    L(3) = zlabel('$\Delta CS`$','interpreter','latex','FontSize',15);
    % L(4) = title('$z = 1-\sqrt{x^{2}+(y-1)^{2}}$','interpreter','latex','FontWeight','bold');
    

    效果如下:

     

     

    如果需要在平面上绘制一条分界线(题目要求的是让因变量CS=零),需要用到plot3函数,增加功能后的完整代码如下:

    clear;clc; %清除前置数据
    %常量定义
    ab = 0.10; % αb
    bb = 0.20; % βb
    bs = 0.22; % βs
    tb = 0.35; % tb 
    ts = 0.30; % ts 
    cta = 1; %就是那个C塔
    
    %曲面数据处理
    i = linspace(0,1,50); %设置自变量i的范围 [0,1]
    f = linspace(0,1,50); %设置自变量f的范围[0,1]
    [I,F] = meshgrid(i,f); %将其i,f轴变为矩阵
    CS = 3/8 - I*ab + ab - (4*F+3*bs*bs+10*bs*bb+3*bb*bb)/(12*ts);% 公式
    
    
    %曲线数据处理
    f2 = linspace(0,1,50); 
    % 0 = 3/8 - i*ab + ab - (4*f+3*bs*bs+10*bs*bb+3*bb*bb)/(12*ts); 原式
    i2=(3/8  + ab - (4*f2+3*bs*bs+10*bs*bb+3*bb*bb)/(12*ts))/ab; %原式变形后
    cs2 = i2-i2;
    
    %绘制
    Fig = mesh(I,F,CS); % 绘制三维曲面图
    hold on;
    plot3(i2,f2,cs2,'k--'); % 绘制分割线
    hold on;
    % plot3(0.02,0.11,0.15,'r*'); % 可以绘制某个指定的点
    axis([0,1,0,1,-0.5,0.5]); %坐标范围设置,X轴和Y轴一定要和自变量i和f的范围保持一致!!!Z轴怎么好看怎么设置
    
    
    L(1) = xlabel('$i$','interpreter','latex','FontSize',15);
    L(2) = ylabel('$f$','interpreter','latex','FontSize',15);
    L(3) = zlabel('$\Delta CS`$','interpreter','latex','FontSize',15);
    % L(4) = title('$z = 1-\sqrt{x^{2}+(y-1)^{2}}$','interpreter','latex','FontWeight','bold');
    

  • 您还可以看一下 张建波老师的大学数学实验(MATLAB版)课程中的 二维图形的修饰小节, 巩固相关知识点

以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:

在Matlab中,可以这样实现平滑图中曲线并计算每个同心圆的直径:

  1. 读取图像并进行二值化,得到黑白图像。可以使用imread和im2bw函数:
matlab
I = imread('your_image.jpg');
BW = im2bw(I,0.5);  %二值化,threshold=0.5

  1. 使用bwmorph函数进行开运算和闭运算,平滑二值图像中的曲线。
matlab 
se = strel('disk',3);  %结构元素,disk型,半径3
BW1 = imopen(BW,se);  %开运算
BW2 = imclose(BW1,se); %闭运算

  1. 使用bwboundaries函数获取图像中的同心圆轮廓。
matlab
[B,L] = bwboundaries(BW2,'noholes');

  1. 计算每个同心圆轮廓的直径(perimeter/pi)并输出。
matlab
diameters = zeros(length(B),1);
for k = 1:length(B)
   diameters(k) = polyperim(B{k})/pi;  %周长/pi=直径 
end

for k = 1:length(diameters)
   fprintf('同心圆%d的直径=%.2fmm\n',k,diameters(k)); 
end

  1. 可选:在原图像I上绘制同心圆轮廓,用于验证结果。
matlab
figure; 
imshow(I); 
hold on;
for k = 1:length(B) 
    plot(B{k}(:,2), B{k}(:,1), 'r', 'LineWidth', 2); 
end

以上Matlab代码可以实现读取图像,平滑同心圆曲线,提取每个同心圆轮廓,并计算其直径。结果以毫米为单位输出。