原理
sobel算子可以通过杨辉三角来获取,两个方向上的sobel算子本质上就是用于差分处理和平滑处理的两个向量的乘积,在程序中,这两个向量可以通过循环卷积简单地获得,例如:
5*5的sobel算子可以通过以下方法获得:
conv([1,1],[1,1])=[1,2,1];
conv([1,2,1],[1,1])=[1,3,3,1];
conv([1,3,3,1],[1,1])=[1,4,6,4,1];
这个向量即我们所说的用于平滑处理的向量。
差分处理的向量也可以通过类似方法算得:
conv([-1,1],[1,1])=[-1,0,1];
conv([-1,0,1],[1,1])=[-1,-1,1,1];
conv([-1,-1,1,1],[1,1])=[-1,-2,0,2,1];
将其中一个向量转置后右乘另一个向量,可得到一个方向的sobel算子,将其转置即另一个方向的算子。将这得到的两个算子与图像卷积,求平方和的根即可得到对应图像的轮廓。
代码
以某姐的网图为例,完整代码如下:
soble_size=5;
diff_array=[-1,1];
smooth_array=[1,1];
for i=1:soble_size-2
diff_array=conv(diff_array,[1,1]);
smooth_array=conv(smooth_array,[1,1]);
end
slobe_vertical=diff_array'*smooth_array;
slobe_axial=smooth_array'*diff_array;
img=imread("E:\pic.png");
img=rgb2gray(img);
img_vertical=conv2(img,slobe_vertical);
img_vertical=img_vertical(1+floor((soble_size-1)/2):end-floor((soble_size-1)/2),...
1+floor((soble_size-1)/2):end-floor((soble_size-1)/2));
img_axial=conv2(img,slobe_axial);
img_axial=img_axial(1+floor((soble_size-1)/2):end-floor((soble_size-1)/2),...
1+floor((soble_size-1)/2):end-floor((soble_size-1)/2));
figure(1);imshow(img,[]);
figure(2);imshow(img_axial,[]);
figure(3);imshow(img_vertical,[]);
img_all_dim=sqrt(img_vertical.^2+img_axial.^2);
img_all_dim=img_all_dim-min(img_all_dim,[],"all");
img_all_dim=img_all_dim/max(img_all_dim,[],"all");
figure(4);imshow(img_all_dim,[]);
结果
原图:
轮廓1:
轮廓2:
提取的结果: