% 定义函数,输入参数包括图像名称、图像宽高、网格大小、变换矩阵、变换类型、单应性矩阵、参考图像、目标图像、c1参数、mdlt参数、是否绘制网格、背景颜色
function [c1out, c1omask, T] = texture_mapping(in_name, imgw, imgh, img_grid_size, T, warp_type, H, ref, tar, c1para, mdltpara, drawmesh, bgcolor)
% 定义存储路径
mapping_location = 'texture_mapping/';
% 初始化输出变量和中间变量
img_n = numel(in_name); % 图像数量
c1out = cell(img_n, 1); % 输出图像
c1omask = cell(img_n, 1); % 输出掩码
inmesh_X0 = cell(img_n, 1); inmesh_Y0 = cell(img_n, 1); % 输入网格坐标
outmesh_X = cell(img_n, 1); outmesh_Y = cell(img_n, 1); % 输出网格坐标
curr_minx = zeros(img_n, 1); curr_miny = zeros(img_n, 1); % 当前图像网格的最小x、y坐标
curr_maxx = zeros(img_n, 1); curr_maxy = zeros(img_n, 1); % 当前图像网格的最大x、y坐标
% 循环处理每张图像
for i = 1 : img_n
% 计算输入网格坐标
meshW = ceil(imgw(i) / img_grid_size); % 网格宽度
meshH = ceil(imgh(i) / img_grid_size); % 网格高度
X0list = linspace(1, imgw(i), meshW); % X坐标列表
Y0list = linspace(1, imgh(i), meshH); % Y坐标列表
[inmesh_X0{i}, inmesh_Y0{i}] = meshgrid(X0list, Y0list); % 生成网格坐标
% 计算输出网格坐标
[outmesh_X{i}, outmesh_Y{i}] = mesh_warp(img_grid_size, imgw(i), imgh(i), warp_type, T, i, ref, tar, H, c1para, mdltpara);
% 计算当前图像网格的最小和最大坐标
curr_minx(i) = min(outmesh_X{i}(:)); curr_miny(i) = min(outmesh_Y{i}(:));
curr_maxx(i) = max(outmesh_X{i}(:)); curr_maxy(i) = max(outmesh_Y{i}(:));
end
% 计算所有图像网格的最小和最大坐标
all_minx = min(curr_minx); all_miny = min(curr_miny);
all_maxx = max(curr_maxx); all_maxy = max(curr_maxy);
% 改变坐标系,使得复合图像的左上角对应于(0,0),x轴向右,y轴向下
T1 = [1, 0, -all_minx; 0, -1, all_maxy; 0, 0, 1];
for i = 1 : img_n
[outmesh_X{i}, outmesh_Y{i}] = apply_transform(outmesh_X{i}, outmesh_Y{i}, T1);
% 重新计算最小和最大坐标
curr_minx(i) = min(outmesh_X{i}(:)); curr_miny(i) = min(outmesh_Y{i}(:));
curr_maxx(i) = max(outmesh_X{i}(:)); curr_maxy(i) = max(outmesh_Y{i}(:));
end
all_minx = min(curr_minx); all_miny = min(curr_miny);
all_maxx = max(curr_maxx); all_maxy = max(curr_maxy);
% 计算包围盒面积
bbarea = (all_maxx-all_minx)*(all_maxy-all_miny);
% 缩放以避免内存问题
max_size = 600*800;
scl = sqrt(max_size/bbarea);
T2 = [scl, 0, 0; 0, scl, 0; 0, 0, 1];
for i = 1 : img_n
outmesh_X{i} = outmesh_X{i} * scl;
outmesh_Y{i} = outmesh_Y{i} * scl;
% 重新计算最小和最大坐标
curr_minx(i) = min(outmesh_X{i}(:)); curr_miny(i) = min(outmesh_Y{i}(:));
curr_maxx(i) = max(outmesh_X{i}(:)); curr_maxy(i) = max(outmesh_Y{i}(:));
end
all_minx = min(curr_minx); all_miny = min(curr_miny);
all_maxx = max(curr_maxx); all_maxy = max(curr_maxy);
% 数值后处理(将近似零的值设为零)
for i = 1 : img_n
outmesh_X{i}( outmesh_X{i}<=(1e-7) ) = 0;
outmesh_Y{i}( outmesh_Y{i}<=(1e-7) ) = 0;
end
% 通过平移复合图像添加边框
tr_x = 5;
tr_y = 5;
T3 = [1, 0, tr_x; 0, 1, tr_y; 0, 0, 1];
for i = 1 : img_n
outmesh_X{i} = outmesh_X{i} + tr_x;
outmesh_Y{i} = outmesh_Y{i} + tr_y;
end
% 计算输出图像的宽高
outimg_w = ceil(all_maxx - all_minx) + 1 + 2*tr_x;
outimg_h = ceil(all_maxy - all_miny) + 1 + 2*tr_y;
% 调用opencv进行纹理映射
for i = 1 : img_n
% 将输入和输出网格坐标写入文件
write_matrix_to_file([inmesh_X0{i}; inmesh_Y0{i}], [mapping_location 'inmesh.txt']);
write_matrix_to_file([outmesh_X{i}; outmesh_Y{i}], [mapping_location 'outmesh.txt']);
% 调用外部程序进行纹理映射
eval(['cd ' mapping_location])
dos(sprintf('texture_mapping.exe ../%s %d %d %d %d %s %s %s %d %s', ...
in_name{i}, meshW, meshH, outimg_w, outimg_h, 'inmesh.txt', 'outmesh.txt', 'out.jpg', drawmesh, bgcolor));
% 读取输出图像和掩码
c1out{i} = im2double(imread('output.jpg'));
c1omask{i} = im2double(imread('out_mask.png'));
cd ../
end
% 最后的变换矩阵,包括缩放、平移和从MATLAB坐标到图像坐标的变换
T4 = [1, 0, 1; 0, 1, 1; 0, 0, 1]; % 平移1像素,因为MATLAB坐标从1开始
T = T4 * T3 * T2 * T1;
SPHP算法解读(三)-texture_mapping
最新推荐文章于 2024-06-22 12:11:10 发布