43、一种图像边缘粗糙度计算方法

一、简介

        本文主要介绍一种基于巴特沃斯滤波器的图像边缘粗糙度的刻画方法,可用于计算一个连通图,或者一条曲线的边缘粗糙度指标。(原理简单,但版权所有,不得随意抄袭,发论文)

二、问题引入

        问题:使用自己的方法求如下四张图片的边缘粗糙度?

三、Matlab代码

原理分析:

        步骤一、导入原图
        步骤二、图像二值化
        步骤三、求最大连通图
        步骤四、进行巴特沃斯滤波
        步骤五、求原图像边缘长度
        步骤六、求滤掉的面积
        步骤七、相除得到单位长度滤掉的面积 

%用单位长度上被平滑掉的面积刻画闭合图形的边缘粗糙度(尽量让图形布满视野)
%对于非连通图像,让图像的两端与图像的左右边界重合
clear;clc;
%原图处理
ImageSource = imread('E:\software\MatLab2020b\myWorkPlace\linex.png');%原图
Image_Binary = im2bw(ImageSource,graythresh(ImageSource));%二值图
Image_Max = BigestConnectedDomain(Image_Binary);%最大连通图
[height,width] = size(Image_Binary);%图片的尺寸
[ImageSourceEdge,count_o,border_o] = ImageExcision(ImageSource,Image_Max,1);
%布特沃兹滤波图
n = 3;
d = 0.025*height;
im_out_b = ButterworthFilter(Image_Max,'l',n,d); 
im_out_bw = im2bw(im_out_b,graythresh(im_out_b));
[ImageButterEdge,count_n,border_n] = ImageExcision(ImageSource,im_out_bw,1);
%显示图形
[n2,m2] = size(border_n);
ImageSourceMax = zeros(height,width,3,'uint8');
ImageButterMax = zeros(height,width,3,'uint8');
ImageSourceMax(:,:,1) = Image_Max.*255;
ImageButterMax(:,:,2) = im_out_bw.*255;
ImageAdd = ImageButterMax+ImageSourceMax;
figure(1);
subplot(2,2,1);imshow(ImageSource);title('原图');
subplot(2,2,2);imshow(Image_Binary);title('二值图');
subplot(2,2,3);imshow(Image_Max);title('最大连通图');
subplot(2,2,4);imshow(ImageSourceEdge);title('原始边缘标定');
figure(2);
subplot(2,2,1);imshow(im_out_b);title('巴特沃兹滤波');
subplot(2,2,2);imshow(ImageSourceMax);title('巴特沃兹滤波二值图');
subplot(2,2,3);imshow(ImageButterMax);title('滤波边缘标定');
subplot(2,2,4);imshow(ImageSourceMax+ImageButterMax);title('滤波前后叠加');
%求粗糙度
sumx = sum(sum(ImageAdd(:,:,1)==255&ImageAdd(:,:,2)==0&ImageAdd(:,:,3)==0))+sum(sum(ImageAdd(:,:,1)==0&ImageAdd(:,:,2)==255&ImageAdd(:,:,3)==0));
ronghness = sumx/n2;
fprintf("总面积 = %d,单位长度面积 = %f\n",sumx,ronghness);

%函数1、求最大连通图
function [output_image,area] = BigestConnectedDomain(image)
%本函数求二值化的图像的最大连通域
input_image = imfill(image,'hole');%填充连通域内孤立的孔洞
%获取连通域信息
[L,num] = bwlabel(input_image,4);
x = zeros(1,num);
for i = 1:num
    x(i) = sum(sum(L == i));
end
%定位最大单连通域的位置
[~,n] = max(x);
%输出图像
output_image = (L == n);
%输出最大单连通域的面积
area = sum(sum(output_image));
end
%函数2、巴特沃斯滤波器
function [ output_image ] = ButterworthFilter( image ,mold,n,d)
%本函数为巴特沃斯滤波器,用于对图像进行巴特沃斯滤波
%   image参数为读入的图像矩阵;
%   mold参数为巴特沃斯滤波器的工作模式,有‘l’与‘h’可选,l为低通滤波,h为高通滤波;
%   n参数为巴特沃斯滤波器的阶数;
%   d参数为巴特沃斯滤波器的截止频率。
    hight=size(image,1);
    wide=size(image,2);

    fftim = fftshift(fft2(double(image)));
    [x,y]=meshgrid(floor(-wide/2):floor(wide/2)-1,floor(-hight/2):floor(hight/2)-1);

    B = sqrt(2) - 1; %定义巴特沃斯滤波器中的参数B
    D = sqrt(x.^2 + y.^2); %计算各点到图像中心的距离
    %定义滤波器函数
    if mold == 'l'
        hhp = 1 ./ (1 + B * ((D ./ d).^(2 * n)));
    elseif mold == 'h'
        hhp = 1 ./ (1 + B * ((d ./ D).^(2 * n)));
    end
    %将滤波器的矩阵维度与图像的矩阵维度匹配
    [~,~,page]= size(image);
    hhp1 = hhp;
    i = 1;
    while i < page
        hhp1 = cat(3,hhp1,hhp);
        i = i + 1;
    end 
    hhp = hhp1;
    %滤波
    out_spec_centre = fftim .* hhp;
    %象限转换
    out_spec = ifftshift(out_spec_centre);
    %反变换并取实部
    out = real(ifft2(out_spec));
    %归一化
    out = (out - min(out(:))) / (max(out(:)) - min(out(:)));
    %反归一化图像
    output_image = uint8(255*out);
end
%函数3、output_image:原图标记边缘,border_length:边缘点数,border_location:边缘点坐标
function [output_image,border_length,border_location] = ImageExcision(original_image,bw_image,color_type)
im = original_image;
[row,col] = size(bw_image);%row:高度,col宽度
%-------------------------------------------------------------------------%
count = 0;  %边界点的个数
b_loc = []; %所有边界点的坐标
for j = 2:row-1 %内部像素边界判断
    for k = 2:col-1
        if(bw_image(j,k)==1)
           if (bw_image(j-1,k)== 0 || bw_image(j+1,k)== 0 || bw_image(j,k-1)== 0 ||bw_image(j,k+1)== 0)
               if(color_type == 1) 
                   im(j,k,1) = 255;im(j,k,2) = 0;im(j,k,3) = 0;
               else
                  im(j,k,1) = 0;im(j,k,2) = 0;im(j,k,3) = 255;
               end
               b_loc = [b_loc;[j k]];
               count = count +1; 
           end
        end
    end
end
%-------------------------------------------------------------------------%
%图像边缘像素边界判断(四个角上的像素点除外)
%第一行与最后一行像素
for i = 2:col-1
    if(bw_image(1,i) == 1)
        if(bw_image(1,i+1) == 0 || bw_image(1,i-1) == 0 || bw_image(2,i) == 0)
            if(color_type == 1) 
                im(1,i,1) = 255;im(1,i,2) = 0;im(1,i,3) = 0;
            else
                im(1,i,1) = 0;im(1,i,2) = 0;im(1,i,3) = 255;
            end
            b_loc = [b_loc;[1 i]];
            count = count +1;
        end
    end
    if(bw_image(row,i) == 1)
        if(bw_image(row,i+1) == 0 || bw_image(row,i-1) == 0 || bw_image(row-1,i) == 0)
            if(color_type == 1) 
                im(row,i,1) = 255;im(row,i,2) = 0;im(row,i,3) = 0;
            else
                im(row,i,1) = 0;im(row,i,2) = 0;im(row,i,3) = 255;
            end
            b_loc = [b_loc;[row i]];
            count = count +1;
        end
    end
end
%第一列与最后一列像素
for i = 2:row-1
    if(bw_image(i,1) == 1)
        if (bw_image(i+1,1) == 0 || bw_image(i-1,1) == 0 || bw_image(i,2) == 0)
            if(color_type == 1) 
                im(i,1,1) = 255;im(i,1,2) = 0;im(i,1,3) = 0;
            else
                im(i,1,1) = 0;im(i,1,2) = 0;im(i,1,3) = 255;
            end
            b_loc = [b_loc;[i 1]];
            count = count +1;
        end
    end
    if(bw_image(i,col) == 1)
        if (bw_image(i+1,col) == 0 || bw_image(i-1,col) == 0 || bw_image(i,col-1) == 0)
            if(color_type == 1) 
                im(i,col,1) = 255;im(i,col,2) = 0;im(i,col,3) = 0;
            else
                im(i,col,1) = 0;im(i,col,2) = 0;im(i,col,3) = 255;
            end
            b_loc = [b_loc;[i col]];
            count = count +1;
        end
    end
end
%-------------------------------------------------------------------------%
%四个角上的像素点判断
if(bw_image(1,1)==1)%左上点
    if (bw_image(1,2) == 0 || bw_image(2,1) == 0)
        im(i,col,1) = 255;im(i,col,2) = 0;im(i,col,3) = 0;
        if(color_type == 1) 
            im(i,col,1) = 255;im(i,col,2) = 0;im(i,col,3) = 0;
        else
            im(i,col,1) = 0;im(i,col,2) = 0;im(i,col,3) = 255;
        end       
        b_loc = [b_loc;[1 1]];
        count = count +1;
    end
end         
if(bw_image(row,1)==1)%左下点
    if(bw_image(row,2) == 0 || bw_image(row-1,1) == 0)        
        if(color_type == 1) 
            im(i,col,1) = 255;im(i,col,2) = 0;im(i,col,3) = 0;
        else
            im(i,col,1) = 0;im(i,col,2) = 0;im(i,col,3) = 255;
        end  
        b_loc = [b_loc;[row 1]];
        count = count +1;
    end
end
        
if(bw_image(1,col) == 1)%右上点
    if(bw_image(1,col-1) == 0 || bw_image(2,col) == 0)
        if(color_type == 1) 
            im(i,col,1) = 255;im(i,col,2) = 0;im(i,col,3) = 0;
        else
            im(i,col,1) = 0;im(i,col,2) = 0;im(i,col,3) = 255;
        end  
        b_loc = [b_loc;[1 col]];
        count = count +1;
    end
end     
if(bw_image(row,col)==1) %右下点
    if(bw_image(row,col-1) == 0 || bw_image(row-1,col) == 0)
        if(color_type == 1) 
            im(i,col,1) = 255;im(i,col,2) = 0;im(i,col,3) = 0;
        else
            im(i,col,1) = 0;im(i,col,2) = 0;im(i,col,3) = 255;
        end  
        b_loc = [b_loc;[row col]];
        count = count +1;
    end
end
output_image = im;
border_length = count/2;
border_location = b_loc; %所有边界点坐标
end
function ret=fun_edgex(Input_image) %zhoujinhao add (提取图像的边缘)
    ret_img = Input_image;
    [height,width]=size(Input_image);
    for i_x = 1:(height)
        for j_x = 1:(width) %扫描每一个像素
            if (i_x>1&&i_x<height&&j_x>1&&j_x<width)
                if Input_image(i_x,j_x)==1
                    ret_img(i_x,j_x)=~(Input_image(i_x-1,j_x)&&Input_image(i_x+1,j_x)&&Input_image(i_x,j_x-1)&&Input_image(i_x,j_x+1));
                end
            end
        end
    end
    ret = ret_img;
end

四、结果展示

图片一、云:总面积 = 6412,单位长度面积 = 2.800000(边缘粗糙度)

图片二、圆:总面积 = 88,单位长度面积 = 0.162362(边缘粗糙度)

图片三、折线:总面积 = 570,单位长度面积 = 1.113281(边缘粗糙度)

图片四、直线:总面积 = 0,单位长度面积 = 0.000000(边缘粗糙度)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值