Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 无FFT的二维离散余弦变换_Matlab_Fft_Dct - Fatal编程技术网

Matlab 无FFT的二维离散余弦变换

Matlab 无FFT的二维离散余弦变换,matlab,fft,dct,Matlab,Fft,Dct,我试图在Matlab中实现DCT(离散余弦变换),但没有使用快速傅里叶变换,只使用下一个公式: 我知道这可能是低效的,但通过这种方式,我将了解它的工作原理 首先,我将灰度图像划分为8x8块,然后将公式应用于每个块 for i=1:8:h for j=1:8:w dctMatrix(i:(i-1)+block,j:(j-1)+block) = dctII(img(i:(i-1)+block,j:(j-1)+block), block); end end 我的dc

我试图在Matlab中实现DCT(离散余弦变换),但没有使用快速傅里叶变换,只使用下一个公式:

我知道这可能是低效的,但通过这种方式,我将了解它的工作原理

首先,我将灰度图像划分为8x8块,然后将公式应用于每个块

for i=1:8:h
    for j=1:8:w
        dctMatrix(i:(i-1)+block,j:(j-1)+block) = dctII(img(i:(i-1)+block,j:(j-1)+block), block);
    end
end
我的dctII函数如下所示:

   function [newB] = dctII(segmento, b)
    [h w] = size(segmento);
    segmento = double(segmento);
    newB = zeros(b,b);
    for u=0:h-1
        for v=0:w-1
            if u == 0
                Cu = 1/sqrt(2);
            else
                Cu = 1;
            end
            if v == 0
                Cv = 1/sqrt(2);
            else
                Cv = 1;
            end
            sumRes = summation(segmento,u,v,b);
            dct = (1/4)*Cu*Cv*sumRes;
            segmento(u+1,v+1) = dct;
        end
    end
    newB = segmento;
end
我还创建了一个求和函数来保持可读性(至少对我来说)

问题是,我的算法的结果与Matlab预构建函数的结果相差甚远。也许我根本没有得到DCT算法。你知道我做错了什么吗?我知道所有这些嵌套循环都会严重降低性能,但我无法想象不使用FFT如何解决这个问题

非常感谢您的帮助。

已经解决

我的结果与Matlab预构建函数DCT2不同,因为该函数不考虑像我那样的8x8块划分,所以矩阵不相等。 我还对我的代码做了一些修改,我读到在处理像素值之前,需要将128减去每个值,以便在范围[-128127]内工作。这是我的代码:

function [newB] = dctII(segmento, b)
    [h w] = size(segmento);
    segmento = double(segmento) - 128;
    newB = zeros(b,b);
    for u=0:h-1
        for v=0:w-1
            if u == 0
                Cu = 1/sqrt(2);
            else
                Cu = 1;
            end
            if v == 0
                Cv = 1/sqrt(2);
            else
                Cv = 1;
            end
            sumRes = summation(segmento,u,v,b);
            dct = (1/4)*Cu*Cv*sumRes;
            newB(u+1,v+1) = dct;
        end
    end
end

function [sum] = summation(segmento,u,v,b)
    [h w] = size(segmento);
    sum = 0;
    for x=0:h-1
        for y=0:w-1
            sum = sum + (double(segmento(x+1,y+1))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));
        end
    end
end

虽然效率不高,但它是公式的实现。希望这有帮助

至少你可以在求和函数中把(2*b)放在括号里。你是对的,谢谢你注意到其中的分段是什么?为什么它说segmento未定义?它是8x8像素块,它不是未定义的,因为它是我函数的参数
function [newB] = dctII(segmento, b)
    [h w] = size(segmento);
    segmento = double(segmento) - 128;
    newB = zeros(b,b);
    for u=0:h-1
        for v=0:w-1
            if u == 0
                Cu = 1/sqrt(2);
            else
                Cu = 1;
            end
            if v == 0
                Cv = 1/sqrt(2);
            else
                Cv = 1;
            end
            sumRes = summation(segmento,u,v,b);
            dct = (1/4)*Cu*Cv*sumRes;
            newB(u+1,v+1) = dct;
        end
    end
end

function [sum] = summation(segmento,u,v,b)
    [h w] = size(segmento);
    sum = 0;
    for x=0:h-1
        for y=0:w-1
            sum = sum + (double(segmento(x+1,y+1))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));
        end
    end
end