2

我目前正在编写我自己的 Matlab 实现,该实现是 2003 年的一篇论文,在任意网格上的快速纹理合成。一切都很顺利,除了相似变换的旋转部分,这意味着在 3D 表面上创建一个矢量场。这是算法的一个非常重要的部分,因为它在整个 3D 表面上提供了更自然和连贯的纹理方面。

问题是,我只是不知道该怎么做。发现的关于这个主题的文献对我来说非常模糊,所以我现在正在寻找一种更实用(和程序化)的方式来执行此操作。

任何想法 ?

[编辑] 以防万一,我尝试了这段代码,它使用重心插值将纹理图像映射到 3D 网格。但是,在示例中,给定的纹理顶点索引是事先已知的,因此,据我所知,我仍然坚持纹理图像和 3D 网格之间的相似性变换的旋转部分。我仍然需要在表面周围创建一个矢量场

最后,这是我写的关于 Magda 和 Kriegman 算法的纹理预处理部分的代码:

%% Implementation inspired by the work of Magda & Kriegman(2003), "Fast Texture     Synthesis on Arbitrary Mesh"
function [TextonImage, LUT, TextonBucket] = GenerateTextons( SampleImage, gaussianSize, nbKmeansCenters )

% Create Gaussian kernel
h = fspecial( 'gaussian', gaussianSize );

% Generate feature vectors
FeatureVectors = ComputeFeatureVectors( h, SampleImage );

% Perform k-mean clustering, classify feature vectors (i.e. assign labels)
[IDX,C] = kmeans( FeatureVectors, nbKmeansCenters );

% Create texton texture
LUT = randi( 255, size( C, 1 ), 3 );
[TextonImage, TextonBucket] = CreateTextonTexture( C, SampleImage, LUT, h );

end


function Vectors = ComputeFeatureVectors( Kernel, Image )

offset = floor( size( Kernel, 1 ) / 2 );
vectorsSize = ( size( Image, 1 ) - 2 * offset ) * ( size( Image, 2 ) - 2 * offset );

Vectors = zeros( vectorsSize, size( Kernel, 1 ) * size( Kernel, 1 ) );
kk = 1;

for ii = ( 1 + offset ):( size( Image, 1 ) - offset )
    for jj = ( 1 + offset ):( size( Image, 2 ) - offset )
        temp = Kernel .* double( Image( ii - offset:ii + offset, jj - offset:jj + offset ) );
        Vectors( kk, : ) = reshape( temp, size( Kernel, 1 ) * size( Kernel, 1 ), 1 )';
        kk = kk + 1;
    end
end

end



function [ TextonImage, TextonBucket ] = CreateTextonTexture( Centroids, Image, LUT, Kernel )

offset = floor( size( Kernel, 1 ) / 2 );
TextonImage = zeros( size( Image, 1 ), size( Image, 2 ), 3 );
TextonBucket = struct;
IndexTable = zeros( size( Centroids, 1 ), 1 );

for ii = ( 1 + offset ):(size( Image, 1 ) - offset)
    for jj = ( 1 + offset ):(size( Image, 2 ) - offset)
        temp = Kernel .* double( Image( ii - offset:ii + offset, jj - offset:jj + offset ) );
        Vector = reshape( temp, size( Kernel, 1 ) * size( Kernel, 1 ), 1 )';

        minDist = 10000;
        Index = 0;

        for k=1:size( Centroids, 1 )
            % Calculate distance of test point to training point.
            d = sum( Vector - Centroids( k, : ) ) .^ 2;
            % if smaller...
            if d < minDist
                minDist = d;
                Index = k;
            end
        end

        TextonImage( ii, jj, : ) = LUT( Index, : );
        cellName = strcat('B',num2str(Index));
        IndexTable( Index ) = IndexTable( Index ) + 1;
        TextonBucket.(cellName){ IndexTable( Index ) } = [ jj, ii ];
    end
end

end

谢谢你。

4

0 回答 0