SPHP算法解读(三)-texture_mapping

% 定义函数,输入参数包括图像名称、图像宽高、网格大小、变换矩阵、变换类型、单应性矩阵、参考图像、目标图像、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;
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值