通常DIC的数据集的制作是先的得到位移场,然后再将位移场插赋给散斑图像(即参考图),就可以得到变形图像。且位移场的变形方式有旋转、拉伸、剪切、缩放、高斯等。公式如下图
![](https://img-blog.csdnimg.cn/direct/fd286a1a92704615b563946b061c14a1.png)
接下来就是代码了。
%第一种插值方式是为了对输入图像进行 X 和 Y 方向上的插值,目的是根据给定的网格 (Xgrid 和 Ygrid) 对图像进行重采样。
%第二种插值方式是在应用位移矩阵到原始散斑图像上后,根据计算出的位移值在图像上进行插值,目的是对散斑图像进行变形。
%input_img= imread('C:\Users\Administrator\Desktop\test\test1\Sample3 Reference.tif');
% 生成随机参数
tx = rand() * 4 - 2; % rand x transation
ty = rand() * 4 - 2; % rand y translation
sx = rand() * 0.03 + 0.985; % scale x, stretch/compress x
sy = 2 - sx; % scale y, stretch/compress y
sh_x = (rand() - 0.5) * 0.1; % sheer x
sh_y = (rand() - 0.5) * 0.1; % sheer y
th = rand() * 2 * pi; % 这个是表示弧度 %当时是修改了
% 构建仿射变换矩阵
translation_matrix = [
1, 0, 0;
0, 1, 0;
tx, ty, 1
];
scale_matrix = [
sx, 0, 0;
0, sy, 0;
0, 0, 1
];
shear_matrix = [
1, sh_y, 0;
sh_x, 1, 0;
0, 0, 1
];
rotation_matrix = [
cos(th), -sin(th), 0;
sin(th), cos(th), 0;
0, 0, 1
];
% 计算仿射变换矩阵
transform_formulation = translation_matrix * scale_matrix * shear_matrix;
transform_formulation = transform_formulation';
% 生成网格
grid_lin = linspace(-255.5, 255.5, 512);
[x, y] = meshgrid(grid_lin, grid_lin);
% 进行仿射变换
transformed_coords = transform_formulation \ [x(:), y(:), ones(numel(x), 1)]';
transformx = reshape(transformed_coords(1, :), size(x));
transformy = reshape(transformed_coords(2, :), size(y));
% 计算位移场
disp_field_x = x - transformx;
disp_field_y = y - transformy;
% 生成随机参数和高斯噪声
para = rand(2, 6) * 4 - 2;
poisson = rand() * 0.3 + 0.05;
mu1 = (para(1, 1) / 2 + 1) / 2;
mu2 = (para(1, 3) / 2 + 1) / 2;
sig1 = para(1, 2) + 2 / 8 + 0.05;
sig2 = para(1, 4) + 2 / 8 + 0.05;
cov1 = sig1^2;
cov2 = sig2^2;
amp = para(1, 5) * 0.1 + 0.005 * sign(para(1, 5));
vo = para(1, 6) / 2;
% 生成高斯分布场
[Xgrid, Ygrid] = meshgrid(linspace(0, 1, 512));
Disp_gaus_1x = 0.6 * gauss2D(Xgrid, Ygrid, sig1, mu1, sig2, mu2, amp, vo);
Disp_gaus_1y = -0.6 * poisson * gauss2D(Xgrid, Ygrid, sig1, mu1, sig2, mu2, amp, vo);
mu1 = (para(2, 1) / 2 + 1) / 2;
mu2 = (para(2, 3) / 2 + 1) / 2;
sig1 = para(2, 2) + 2 / 8 + 0.05;
sig2 = para(2, 4) + 2 / 8 + 0.05;
cov1 = sig1^2;
cov2 = sig2^2;
amp = para(2, 5) * 0.1 + 0.005 * sign(para(2, 5));
vo = para(2, 6) / 2;
Disp_gaus_2x = -0.6 * poisson * gauss2D(Xgrid, Ygrid, sig1, mu1, sig2, mu2, amp, vo);
Disp_gaus_2y = 0.6 * gauss2D(Xgrid, Ygrid, sig1, mu1, sig2, mu2, amp, vo);
% 计算最终位移场
disp_field_x = disp_field_x - (Disp_gaus_1x + Disp_gaus_2x);
disp_field_y = disp_field_y - (Disp_gaus_1y + Disp_gaus_2y);
% 将 disp_field_x 和 disp_field_y 两个数组添加到列表中
% 将 disp_field_x 和 disp_field_y 两个数组合并成一个三维数组
disp_field_output2 = cat(3, disp_field_x, disp_field_y);
% 将合并后的数组进行转置,以满足 (2, 512, 512) 的格式
disp_field_output2 = permute(disp_field_output2, [3, 1, 2]);
% 创建网格
%[Xgrid, Ygrid] = meshgrid(0:511, 0:511);
% 计算位移后的网格坐标
%Xgrid_d = Xgrid - disp_field_x;
%Ygrid_d = Ygrid - disp_field_y;
% 创建变形后的图像矩阵
%warped =double(input_img);
% 创建一个与输入图像大小相同的零矩阵,用于存储经过 X 方向插值后的图像
%warped_in_x = zeros(size(input_img));
% 对 X 方向进行插值
%for ind = 1:size(warped, 1)
% 检查网格维度,确保至少有两个采样点
%if numel(unique(Xgrid(ind, :))) < 2
% 如果维度不够,添加额外的采样点
%Xgrid_temp = [Xgrid(ind, 1), Xgrid(ind, :), Xgrid(ind, end)];
%Ygrid_temp = [Ygrid(ind, 1), Ygrid(ind, :), Ygrid(ind, end)];
%warped_temp = [warped(ind, 1), warped(ind, :), warped(ind, end)];
%else
% Xgrid_temp = Xgrid(ind, :);
% Ygrid_temp = Ygrid(ind, :);
%warped_temp = warped(ind, :);
%end
% 调用 interp1 函数进行插值
%warped_in_x(ind, :) = interp1(Xgrid_temp, warped_temp, Xgrid_d(ind, :), 'spline');
%end
% 创建一个与输入图像大小相同的零矩阵,用于存储经过 Y 方向插值后的图像
%warped_in = zeros(size(input_img));
% 对 Y 方向进行插值
%for ind = 1:size(warped_in_x, 2)
% 检查网格维度,确保至少有两个采样点
%if numel(unique(Ygrid(:, ind))) < 2
% 如果维度不够,添加额外的采样点
%Xgrid_temp = [Xgrid(1, ind); Xgrid(:, ind); Xgrid(end, ind)];
%Ygrid_temp = [Ygrid(1, ind); Ygrid(:, ind); Ygrid(end, ind)];
% warped_temp = [warped_in_x(1, ind); warped_in_x(:, ind); warped_in_x(end, ind)];
%else
%Xgrid_temp = Xgrid(:, ind);
%Ygrid_temp = Ygrid(:, ind);
% warped_temp = warped_in_x(:, ind);
% end
% 调用 interp1 函数进行插值
% warped_in(:, ind) = interp1(Ygrid_temp, warped_temp, Ygrid_d(:, ind), 'spline');
%end
% 最终的变形后的图像矩阵
%warped2 = warped_in;
%定义一个高斯函数
function result = gauss2D(x, y, sig1, mu1, sig2, mu2, amp, vo)
xnumerator = (x - mu1) .^ 2;
xdenom = 2 * sig1 .^ 2;
xterm = xnumerator ./ xdenom;
ynumerator = (y - mu2) .^ 2;
ydenom = 2 * sig2 .^ 2;
yterm = ynumerator ./ ydenom;
result = amp * (exp(-(xterm + yterm))) + vo;
end
产生的位移场如图
然后再将位移场赋给散斑图,即可得到变形图。希望大家多多关注我,后面为大家更新内容。