一个简单的示例(来自MATLAB help for qtdecomp):
原始矩阵:
I =
>> S = qtdecomp(I,.05) %执行四叉分解,阈值为0.05,实际上的阈值是ceil(0.05*255)=13,因为I是uint8类的
S =
S是一个稀疏阵,全显示为:
>> disp(full(S));
过程:
①
含义:
显示四叉树分解的表示(来自MATLAB help,作了些注释):
I = imread('liftingbody.png');
S = qtdecomp(I,.27);%以阈值ceil(0.27*255)=69对图像I进行四叉分解
blocks = repmat(uint8(0),size(S));%得到一个和I同尺寸的黑色背景blocks
for dim = [512 256 128 64 32 16 8 4 2 1];
end
blocks(end,1:end) = 1;
blocks(1:end,end) = 1;
imshow(I), figure, imshow(blocks,[])
注:
①如果图像不是2的整数次幂,则函数qtdecomp会运行出错。需要将输入图像增大为一个方形,其维数是可包围图像的2的最小整数次幂。这样以确保分离为1是可能的。如,对于一幅 246x300的图像,需要将其扩展为512x512,
可使用如下方法:
>> I(512,512)=0;%原始图像位于I的左上角,扩展的区域全部为0,是不会影响分解结果的。
②分离结果看起来密密麻麻的,但实际上分离的等级数并不多,如512x512的图像最多才分离9次(512分离为4个
256x256算第一级,256再分离为4个128x128算第二级,……),因为每次细分的尺寸都是呈2的指数次减小,故等级数不多。
③find(S==dim)返回的是S中值为dim的linear indexing(线性索引)。含义:MATLAB中矩阵在内存中是以按列的
方式存取的,故对于矩阵A=[2 6 9; 4 2 8; 3 5 1],使用A(3,2)与A(6)有相同的效果——都是访问元素值5。如
此例中,dim=128时,find(S==dim)返回的是:
>> find(S==128)
ans =
即共有6个尺寸为128x128的分块,它们的位置分别在1、129、65537、131073、196609 、 196865。
这些数字叫做元素的“linear indices(线性顶点)”,根据这些顶点,可以很容易的推算出元素所在的行列位置
。如对于131073的元素而言,其所在的列位置为col=ceil(131073/512)=257,行位置为row=131073-(col-1)
*512=1,即S(1,257)=S(131073)。find的另一种形式可以直接获得行列位置:[row,col] = find(S==dim);
④J = qtsetblk(I, S, dim, vals) replaces each dim-by-dim block in the quadtree decomposition of I
with the corresponding dim-by-dim block in vals. S is the sparse matrix returned by qtdecomp; it
contains the quadtree structure. vals is a dim-by-dim-by-k array, where k is the number of dim-by-
dim blocks in the quadtree decomposition.
明确的说明了qtsetblk的功能:在图像I的四叉树分解S中,用vals定义的块代替dim对应的块。
每个块具有如下特征:
下图给出了S中尺寸为128、64和32的块被values定义的块替换后的效果:
⑤试着做下修改,就可在原图上显示网格:
I = imread('liftingbody.png');
S = qtdecomp(I,.27);
for dim = [512 256 128 64 32 16 8 4 2 1];
位置
end
I(end,1:end) = 0;
I(1:end,end) = 0;