有一个需求需要要生成地貌一样的随机地形图,首先我通过在固定大小的矩形面板上生成多个大小不一的矩形,然后赋予每个矩形随机的高度,然后再进行滤波得到想要的地形图。
上一篇已经生成了随机的大小的矩形图,那么只需要赋予每个矩形图一定的高度,然后进行滤波。先贴代码。
function im2 = rectangle_depth(im,b,depth1)
%生成一个带有深度的小矩形
%im : 传入的图片
%b;b = [x y w h]从点(x,y)开始绘制一个宽w高h的矩形,对坐标轴数据单元指定值
%depth1:矩形的高度,也就是深度值
im2 = im;
if(b(1) == 0)
b(1) = 1;
end
if(b(2) == 0)
b(2) = 1;
end
for i = b(1):b(1) + b(3)
for j = b(2):b(2) + b(4)
im2(i,j) = im(i,j) + depth1;
if(im2(i,j) > 255)
im2(i,j) = 255;
end
end
end
end
结合上一个随机生成矩形的函数,如下:
function im = draw_rec_depth(im,depth,rec_num)
%生成一个有深度信息的矩形图,里面包含随机个带有深度信息的小矩形
% im:传入的矩形
% depth:矩形的深度值
% im2:返回带有深度的矩形图
t = 1;
% ah = 56;
% x = rand(1)*ah;
% y = rand(1)*ah;
% w = rand(1)*(112-x);
% h = rand(1)*(112-y);
x = 112 - 112*rand(1,1);
y = 112 - 112*rand(1,1);
w = rand(1)*(112-x)-1;
h = rand(1)*(112-y)-1;
b =[x y w h];
% rectangle('Position', b)
a{t} =b;
flag =1;
while flag ==1
% x = rand(1)*ah;
% y = rand(1)*ah;
% w = rand(1)*(112-x);
% h = rand(1)*(112-y);
x = 112 - 112*rand(1,1);
y = 112 - 112*rand(1,1);
w = rand(1)*(112-x)-1;
h = rand(1)*(112-y)-1;
b =[x y w h];
num = 0;
for j = 1:t
if ~rectint(b,a{j})%交集的面积为0
num = num +1;
end
end
if num == t
% hold on;
% rectangle('Position', b)
im = rectangle_depth(im,int8(b),depth(t));
t = t+1;
a{t} =b;
end
if t == rec_num
break
end
end
im=wiener2(im, [5 5]);%3x3自适应维纳滤波
im=medfilt2(im,[6,6]);
im = Butterworth_Filter(im);%巴特沃斯滤波
im=medfilt2(im,[6,6]);
% [msize,nsize] = size(im);
% xx = linspace(0,msize,nsize);
% yy =linspace(0,msize,nsize);
% figure,surf(xx,yy,im)%x2
end
效果图如下
再看看滤波之后
平滑滤波之后
其中还用到了一个巴斯沃特滤波器,详情可以查看这里。
下面是源代码
function I3 = Butterworth_Filter(I1)
f=double(I1);
g=fft2(f);%傅里叶变换
g=fftshift(g);%直流分量移到频谱中心
[M,N]=size(g);%计算图像的高和宽
d0=50;nn=3;%截止频率为50的二阶巴特沃斯低通滤波器
m=round(M/2);n=round(N/2);%数据取整
for i=1:M
for j=1:N
d=sqrt((i-m)^2+(j-n)^2);%计算频率平面原点到各点的距离
h=1/(1+0.414*(d/d0)^(2*nn));%传递公式
result(i,j)=h*g(i,j);%滤波公式
end
end
result=ifftshift(result);%直流分量移回到左上角
I2=ifft2(result);%傅里叶反变换
I3=uint8(real(I2));%取幅值并转换成8位无符号整数
end
下面是深度信息多次叠加后的效果,不断叠加的同时进行滤波。
还是挺好看的。当然你如果需要更个性化的地形图,可以的对生成矩形进行正则化啦。
再贴一下主函数的代码,自己mark一下。
clear all
clc
Original_image_dir = 'E:\学习\深度学习\活体检测\数据集\Captrue_Data\dataset\spoof\rec_filter_spoof\';%原始图片路径
num_round = 80;%矩形的个数范围
depth_round = 150;%深度范围
num_img = 10000;
% 矩形的个数 加2是为了放在下面的depth高度的维度为0,或者1时无法当成矩阵传递参数而depth(t)报索引超出维度
rec_num = 2 + int8(num_round - num_round*rand(1,4*num_img));
for mm = 1:num_img
im = zeros(112,112);
for m = 1:4
depth = uint8(depth_round - depth_round*rand(1,int8(rec_num(1,4*(mm-1)+m))));%矩形的高度
im = uint8(draw_rec_depth(im,depth,rec_num(1,4*(mm-1)+m)));
im=wiener2(im, [5 5]);%3x3自适应维纳滤波
im=medfilt2(im,[6,6]);
im = Butterworth_Filter(im);
im=medfilt2(im,[6,6]);
end
image_name4=strcat(Original_image_dir,num2str(mm),'.png');
imwrite(im,image_name4,'png');
mm
% [msize,nsize] = size(im);
% xx = linspace(0,msize,nsize);
% yy =linspace(0,msize,nsize);
% figure,surf(xx,yy,im)%x2
end