一个提取缝隙的图像处理算法
主要针对:各种情况下的图像种类:正常、遮挡、阴影、光照不均、背景偏暗
——————
算法如下:
close all; clear;clc;
%%彩色图像转换为灰度图像
%读取图片
I=imread('D:\personl\matlab\测试图像\裂缝1.jpg');
figure;
subplot(4,4,1);imshow(I);
title('原始图像');
%转灰度图
I1=rgb2gray(I);
subplot(4,4,2);imshow(I1);
title('灰度图像');
%%图像增强
%高斯低通滤波器
d0=50; %阈值
image=I1;
[M ,N]=size(image);
img_f = fft2(double(image));%傅里叶变换得到频谱
img_f=fftshift(img_f); %移到中间
m_mid=floor(M/2);%中心点坐标
n_mid=floor(N/2);
h = zeros(M,N);%高斯低通滤波器构造
for i = 1:M
for j = 1:N
d = ((i-m_mid)^2+(j-n_mid)^2);
h(i,j) = exp(-(d)/(2*(d0^2)));
end
end
img_lpf = h.*img_f;
img_lpf=ifftshift(img_lpf); %中心平移回原来状态
img_lpf=uint8(real(ifft2(img_lpf))); %反傅里叶变换,取实数部分
subplot(4,4,3);imshow(image);title('灰度图');
subplot(4,4,4);imshow(img_lpf);title('高斯低通滤波d=50');
%%图像增强
%计算最佳区间
M=stretchlim(img_lpf);
%%区域增强
I2=imadjust(img_lpf,M,[0,1]);
subplot(4,4,5);imshow(I2);
title('区域增强');
%%矫正不均匀亮度
se=strel('disk',5);
H = fspecial('gaussian',2,2);
M = imfilter(I2,H,'replicate');
I3=imbothat(M,se);
subplot(4,4,6);imshow(I3);
title('校正亮度不均匀');
I31=medfilt2(I3,[5,5]);%中值滤波
%%图像再增强
%计算最佳区间
O=stretchlim(I31);
%%区域增强
I4=imadjust(I31,O,[0,1]);
subplot(4,4,7);imshow(I4);
title('区域再增强');
%%阴影处条纹提取
%将0~0.2灰阶拉伸到0~1,提取阴影处的裂缝轮廓
J= fspecial('gaussian',2,2);
K= imfilter(I1,J,'replicate');
I5=imadjust(K,[0,0.2],[0,1]);
%%灰阶反转
I6=imcomplement(I5);
P=stretchlim(I6);
I7=imadjust(I6,P,[0,1]);
%I71=bwareaopen(I7,20,8);
subplot(4,4,8);imshow(10*I7);
title('阴影处条纹提取');
%阴影处条纹提取与增强图像叠加
I8=I4+10*I7;
subplot(4,4,9);imshow(I8);
title('阴影处图像增强叠加');
%%裂缝区域重构
L=stretchlim(I8);
I9=imadjust(I8,L,[0,1]);
I10=im2bw(I9,100/255);
subplot(4,4,10),imshow(I10);
title('大阈值');
I11=im2bw(I9,30/255);
subplot(4,4,11),imshow(I10);
title('小阈值');
%%去除图像边框
I12=imreconstruct(I11,I10);
[m,n]=size(I);
recImg(1,1:n)=0;
recImg(m,1:n)=0;
recImg(1:m,1)=0;
recImg(1:m,n)=0;
subplot(4,4,12),imshow(I12);
title('去除图像边框干扰');
I13=imclose(I12,strel('square',1));%用边长为2的方形结构元素做闭运算
I14=imopen(I13,strel('square',4));%用边长为5的方形结构元素做开运算
subplot(4,4,13),imshow(I14);
title('闭开运算');
%将目标图像中面积小于100的部分去掉,删除二值图像I6中面积小于100的对象
J=bwareaopen(I14,100,4);
subplot(4,4,14);imshow(J);
title('最终选择');
%高通滤波去噪
sigma=1;%滤波器的标准差
parameters=double(3*sigma*2+1); % 模板尺寸
M=fspecial('gaussian', parameters, sigma);%滤波算子 %gaussian低通滤波器
BW=imfilter(J,M,'replicate');
figure('name','图像处理');
subplot(1,3,1);
imshow(BW),title('去噪后图像');
%骨化
BW1=bwmorph(BW,'skel',20);
subplot(1,3,2);
imshow(BW1),title('骨化图像');
%去毛刺(消除噪声)
%BW2=bwmorph(BW1,'spur',10);
%subplot(1,3,3);
%imshow(BW2),title('去毛刺');
%% 计算交并比
% IOU
% 加载图像
SEG = BW1;
GT = imread('D:\personl\matlab\真值图像\裂缝1.jpg');
% binarize(0~255 to 0~1)
GT = imbinarize(GT);
iou = Cal_IOU(SEG, GT);
% 计算IOU
function iou = Cal_IOU(SEG, GT)
[rows, cols] = size(SEG);
% 统计标签GT、分割结果SEG中像素值为1的像素个数
% 初始化
label_area = 0; % 标签图像的面积(即总像素个数)
seg_area = 0; % 分割结果的面积
intersection_area = 0; % 相交区域面积
combine_area = 0; % 两个区域联合面积
% 计算各部分的面积
for i = 1: rows
for j = 1: cols
% 均被分为前景
if GT(i, j)==1 && SEG(i, j)==1
intersection_area = intersection_area + 1;
label_area = label_area + 1;
seg_area = seg_area + 1;
% 误分割为背景(false negtive)
elseif GT(i, j)==1 && SEG(i, j)~=1
label_area = label_area + 1;
% 误分割为前景(false positive)
elseif GT(i, j)~=1 && SEG(i, j)==1
seg_area = seg_area + 1;
end
end
end
% fprintf("intersection_area = %f\n",intersection_area);
% fprintf("label_area = %f\n",label_area);
% fprintf("seg_area = %f\n",seg_area);
combine_area = combine_area + label_area + seg_area - intersection_area;
% fprintf("combine_area = %f\n",combine_area);
% 计算iou
iou = double(intersection_area) / double(combine_area);
fprintf('IOU = %f\n', iou);
figure;
subplot(1,2,1)
imshow(SEG);title('SEG')
subplot(1,2,2)
imshow(GT);title('GT')
end