图像处理-余弦变换

摘要:
将DCT应用于图像压缩16*16进行分区DCT变换,然后根据不同的模板存储和重建数据。DCT在JPEG压缩编码中的应用DCT,也称为离散余弦变换,是一种仅使用余弦函数来表示信号的块变换方法,与傅里叶变换密切相关。

什么是DCT?

一维DCT变换

一维DCT变换时二维DCT变换的基础,所以我们先来讨论下一维DCT变换。一维DCT变换共有8种形式,其中最常用的是第二种形式,由于其运算简单、适用范围广。我们在这里只讨论这种形式,其表达式如下:

其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵。
图像处理-余弦变换第1张

其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵。

二维DCT变换

二维DCT变换其实是在一维DCT变换的基础上在做了一次DCT变换,其公式如下:

图像处理-余弦变换第2张

由公式我们可以看出,上面只讨论了二维图像数据为方阵的情况,在实际应用中,如果不是方阵的数据一般都是补齐之后再做变换的,重构之后可以去掉补齐的部分,得到原始的图像信息,这个尝试一下,应该比较容易理解。

另外,由于DCT变换高度的对称性,在使用Matlab进行相关的运算时,我们可以使用更简单的矩阵处理方式:
图像处理-余弦变换第3张

二维DCT逆变换

在图像的接收端,根据DCT变化的可逆性,我们可以通过DCT反变换恢复出原始的图像信息,其公式如下:

图像处理-余弦变换第4张

同样的道理,我们利用之前的矩阵运算公司可以推导出DCT反变换相应的矩阵形式

图像处理-余弦变换第5张

对二维图像进行离散余弦变换

由以上对二维离散余弦变换的定义及公式(7)可知,求二维图像的离散余弦变换要进行以下步骤:

  • 1.获得图像的二维数据矩阵f(x,y);
  • 2.求离散余弦变换的系数矩阵[A];
  • 3.求系数矩阵对应的转置矩阵[A]T;
  • 4.根据公式(7)[F(u,v)]=[A][f(x,y)][A]T 计算离散余弦变换;

优点

1、DCT变换较DFT变换具有更好的频域能量聚集度(说人话就是能够把图像更重要的信息聚集在一块),那么对于那些不重要的频域区域和系数就能够直接裁剪掉(有点像淘金,你把石头里重要的金子都弄到一块,剩下没啥用的石子不就可以扔了么),因此,DCT变换非常适合于图像压缩算法的处理,例如现在大名鼎鼎的jpeg就是使用了DCT作为图像压缩算法

2、DCT变换是可分离的变换,其变换核为余弦函数。DCT除了具有一般的正交变换性质外, 它的变换阵的基向量能很好地描述人类语音信号和图像信号的相关特征。因此,在对语音信号、图像信号的变换中,DCT变换被认为是一种准最佳变换。

二维DFT与二维DCT的频谱特征分析

1、细节(高频分量)较少的图像实验:

图像处理-余弦变换第6张

Conclusion:
对于比较平滑的图像/数据,DFT变换数据集中在中间(低频信号区),DCT变换数据集中在左上角,几乎无法看出DCT的优势在哪里。
2、细节丰富的图像实验

图像处理-余弦变换第7张

Conclusion:
DCT变化后的数据很发散,DCT变化后的数据仍然比较集中。如果同样从频率谱恢复原始图像,那么选用DCT更合理,因为DCT只需要存储更少的数据点。正是这个原因,是的DCT广泛地应用于图像压缩。

应用

DCT应用于图像压缩

图像处理-余弦变换第8张

16*16 进行分区做DCT变换,然后按照不同的模板进行数据存留与重建。我们会发现,如果保存的数据过少,会有块效应现象发生。

图像处理-余弦变换第9张

64*64的分区设置,块效应更明显。此时就要在每个分区内多采集点数据。

DCT在JPEG压缩编码中的应用

DCT又称离散余弦变换,是一种块变换方式,只使用余弦函数来表达信号,与傅里叶变换紧密相关。常用于图像数据的压缩,通过将图像分成大小相等(一般为8*8)的块,利用DCT对其进行变换,得到更加简洁的数据。因为图像像素间存在较大的空间相关性,DCT可以大大减小这些相关性,使图像能量集中在左上角区域,从而利于数据压缩。变换后得到的数据称为DCT系数。这一过程是无损的。

根据人类视觉系统理论,人眼对图像平滑区域的变换比较敏感,而对纹理区域的变换不太敏感,经过离散余弦变换之后,图像信息集中在少数低频系数上,而纹理和边缘信息则在中低频系数中,所以低频系数的改变对图像视觉 上的影响远大于高频系数。

DCT变换将图像信号从空间域变换到频域,是JPEG(有损图像数字压缩技术)的核心步骤。

在 JPEG压缩中,为了在图像画面降质不明显的前提下获得较高的压缩比,保留的恰是对人眼视觉重要的低频系数,而将大部分高频系数变成了零, 因此 JPEG压缩对低频系数不敏感,而对高频系数敏感, 将信息数据嵌入在高频部分可能在有损压缩中丢 失, 作为一种权衡,可以将信息嵌入在图像的中频系数之间

图像经过DCT变换后,空域中的总能量在变换域中得到保持,但像素之 间的相关性下降,能量将会重新分布,由空域中所表现出的能量发散形式变换为频域能量相对集中的形式,并集中在变换域的低频系数上。


图像处理-余弦变换第10张

JPEG算法的主要计算步骤:

  • 正向离散余弦变换(FDCT)
  • 量化(quantization)
  • Z字形编码(zigzag scan)
  • 使用差分脉冲编码调制(differential pulse code modulation,DPCM)对直流系数(DC)进行编码 
  • 使用行程长度编码(run-length encoding,RLE)对交流系数(AC)进行编码
  • 熵编码(entropy coding)

DCT在数字水印中的应用

数字水印技术是将特定的信息嵌入到数字信息的内容中,要求嵌入的信息不能被轻易的去除,在一定的条件下可以被提取出来,以确认作者的版权。
水印嵌入框图:
图像处理-余弦变换第11张

水印检测框图:

图像处理-余弦变换第12张

实验

matlab基础

图像处理-余弦变换第13张

DCT变换1

%读入测试图像 
mypicture=imread('input.jpg');%显示读入的图像 %为了防止后一个显示的图像覆盖前一个显示结果,每次显示时调用figure生成一个新窗口 	
figure(),imshow(mypicture),title('原输入图像');

图像处理-余弦变换第14张

             图一

转为灰度图:

grayImage=rgb2gray(mypicture);%如果读入的是彩色图像则转化为灰度图像(灰度图像省略这一步) 
figure(),imshow(grayImage),title('原输入彩色图像转化为灰度图像'); 

图像处理-余弦变换第15张

             图二

对图像DCT转换:

%对图像DCT变换  
dctgrayImage=dct2(grayImage);
figure(), imshow(log(abs(dctgrayImage)),[]),title('DCT变换灰度图像'), colormap(gray(4)), colorbar;

图像处理-余弦变换第16张

          图三

对灰度矩阵进行量化:

%对灰度矩阵进行量化
dctgrayImage(abs(dctgrayImage)<0.1)=0; 

DCT逆变换:

%DCT逆变换  
I=idct2(dctgrayImage)/255;  
figure(), imshow(I), title('经过DCT变换,然后逆变换的灰度图像');

图像处理-余弦变换第17张

             图四

对比变换傅里叶变换前后的图像 :

%对比变换傅里叶变换前后的图像  
figure(), subplot(121), imshow(grayImage), title('原灰度图像'), 
subplot(122), imshow(I), title('DCT逆变换图像');

图像处理-余弦变换第18张

                图五

结果分析:对原始图像进行离散余弦变换,如图3所示,由结果可知,变换后DCT系数能量主要集中在左上角,其余大部分系数接近于零,这说明DCT具有适用于图像压缩的特性。将变换后的DCT系数进行门限操作,将小于一定值得系数归零,这就是图像压缩中的量化过程,然后进行逆DCT运算,得到压缩后的图像,如图4。由图5比较变换前后的图像,肉眼很难分辨出有什么区别,可见压缩的效果比较理想

DCT变换2

image=imread('input.jpg');
figure;
subplot(2,4,1),imshow(image),title("原图");

grayI=rgb2gray(image);
subplot(2,4,2),imshow(grayI),title("灰度图");

DCTI=dct2(grayI);
subplot(2,4,3),imshow(DCTI),title("DCT变换");

ADCTI=abs(DCT1);
subplot(2,4,4),imshow(ADCTI),title("取绝对值");

top=max(ADCTI(:));
subplot(2,4,5),imshow(top),title("取最大值");

bottom=min(ADCTI(:));
subplot(2,4,6),imshow(bottom),title("取最小值");

ADCTI=(ADCTI-bottom)/(top-bottom)*100;
subplot(2,4,7),imshow(ADCTI),title("量化后");

IDCTI=idct2(DCTI)/255;
subplot(2,4,8),imshow(IDCTI),title("DCT逆变换");

图像处理-余弦变换第19张

所以,能量主要分布在左上角低频分量处

DCT图像压缩

打开一幅图像,对其进行DCT变换,将高频置零并进行反变换

image=imread('input.jpg');
figure;
subplot(2,2,1),imshow(image),title("原图");

grayI=rgb2gray(image);
subplot(2,2,2),imshow(grayI),title("灰度图");

DCTI=dct2(grayI);
subplot(2,2,3),imshow(DCTI),title("DCT变换");

[h,w]=size(DCTI);
cf=60;
FDCTI=zeros(h,w);
FDCTI(1:cf,1:cf)=DCTI(1:cf,1:cf);
gratOut=uint8(abs(idct2(FDCTI)));
subplot(2,2,4),imshow(gratOut),title("压缩重建后");

图像处理-余弦变换第20张

彩色图像转灰度图

彩图转灰度图有两种方法:

1、使用rgb2gray()

将RGB三个分量的数值相等,输出后就是灰度图

2、使用ycbcr()

将Y分量提取出,YCBCR格式中的Y分量表示是图像中的亮度和浓度,所以只需输出Y分量,得到的就是图像的灰度图

具体来讲:

YCbCr是通过有序的三元组来表示的,三元由Y(Luminance)、Cb(Chrominance-Blue)和Cr(Chrominance-Red)组成,其中Y表示颜色的明亮度和浓度,而Cb和Cr则分别表示颜色的蓝色浓度偏移量和红色浓度偏移量。人的肉眼对由YCbCr色彩空间编码的视频中的Y分量更敏感,而Cb和Cr的微小变化不会引起视觉上的不同,根据该原理,通过对Cb和Cr进行子采样来减小图像的数据量,使得图像对存储需求和传输带宽的要求大大降低,从而达到在完成图像压缩的同时也保证了视觉上几乎没有损失的效果,进而使得图像的传输速度更快,存储更加方便。我们要的到灰度图像,首先要将采集到的彩色图像转化为YCbCr。

 图像处理-余弦变换第21张

这是OV7725的手册中给出的RGB888 to YCbCr的算法公式。简单明了,将一副图片的RGB分量提取出来,然后用上面的公式进行运算,得到YcbCr分量,然后在合成显示即可。这样显示出来的是YcbCr色彩空间的图片,我们只取Y分量作为新的图片的三个分量合成,得到的即是这幅彩色图片的灰度图。

%将一幅640*480的彩色图片转换成显示成灰度显示?
clc;
clear all;
close all;

RGB_data = imread('input.jpg');%图像读入

R_data =    RGB_data(:,:,1);
G_data =    RGB_data(:,:,2);
B_data =    RGB_data(:,:,3);
figure;
subplot(1,2,1),imshow(RGB_data),title("原图");

[ROW,COL, DIM] = size(RGB_data); %提取图片的行列数

Y_data = zeros(ROW,COL);
Cb_data = zeros(ROW,COL);
Cr_data = zeros(ROW,COL);
Gray_data = RGB_data;
%YCbCr_data = RGB_data;

for r = 1:ROW
    for c = 1:COL
        Y_data(r, c) = 0.299*R_data(r, c) + 0.587*G_data(r, c) + 0.114*B_data(r, c);
        Cb_data(r, c) = -0.172*R_data(r, c) - 0.339*G_data(r, c) + 0.511*B_data(r, c) + 128;
        Cr_data(r, c) = 0.511*R_data(r, c) - 0.428*G_data(r, c) - 0.083*B_data(r, c) + 128;
    end
end

Gray_data(:,:,1)=Y_data;
Gray_data(:,:,2)=Y_data;
Gray_data(:,:,3)=Y_data;
subplot(1,2,2),imshow(Gray_data),title("YCBCR转灰度图");

图像处理-余弦变换第22张

DCT分块变换

1、使用dct2()

% 读取灰度图像
img = imread('huidu.jpg');
% dct2 是2维dct变换函数,得到一个与图像大小相同的二维矩阵
dct_mtx = dct2(img);
% idct2 是逆2维dct变换函数,得到原图像矩阵
img_idct = idct2(dct_mtx)/255; 
figure;
subplot(1,3,1),imshow(img),title("原图");
subplot(1,3,2),imshow(dct_mtx),title("DCT变换");
subplot(1,3,3),imshow(img_idct),title("DCT还原");

2、使用dctmtx()

io = double(imread("huidu.jpg"));
T = dctmtx(8);
% 对载体图像进行DCT变换
DCT_org = blkproc(io,[8 8], 'P1*x*P2',T, T'); 
% 对DCT 矩阵进行逆变换
DCT_reverse = blkproc(DCT_org,[8 8], 'P1*x*P2',T', T); 
figure;
subplot(1,3,1),imshow(io),title("原图");
subplot(1,3,2),imshow(DCT_org),title("DCT分块变换");
subplot(1,3,3),imshow(DCT_reverse),title("DCT分块还原");

DCT可逆信息隐藏

原理:利用DCT变换的矩阵进行操作,有很多种方法,这里举出其中一种方法【原始图像有损,提取信息无损】

隐藏方法:主要是利用载体中两个特定数的相对大小来表示隐藏信息。发送方和接收方事先约定好嵌入过程中所使用的两个DCT系数的位置(为了隐藏的健壮性和不可觉察性,这两个 DCT 系数应该在 DCT 的中频系数中选择)。例如,设定(u,v) 和 (m,n) 为所选定的两个系数的坐标。嵌入过程为:如果Bi(u,v)> Bi(m,n) ,就代表隐藏信息“1”,如果 Bi(u,v)< Bi(m,n) 就代表 隐 藏 信 息“0”。

如 果 需 要 隐 藏 的 信 息 位 为 1,但 是Bi(u,v)<Bi(m,n) 那么就把这两个系数交换,最后发送方通过二维逆DCT变换将图像转化为空间域进行传输。

提取方法:接收方接收到图像后,对图像进行二维DCT变换,通过比较每一块中约定位置的DCT系数的相对大小,得到隐藏信息的比特串,从而提取出秘密信息。

% DCT 变换信息隐藏
io = imread("huidu.jpg");
figure;
subplot(1,3,1),imshow(io),title("原图");

io = double(io);
% 待嵌入的秘密信息msg
msg = [1,0,1,1];
% 用于计数,嵌入完成后停止操作。
count = length(msg);
org_msg = [1,0,1,1];
T = dctmtx(8); %图像分块8*8
DCTrgb = blkproc(io,[8 8], 'P1*x*P2',T, T'); % 对载体图像进行DCT变换
subplot(1,3,2),imshow(DCTrgb),title("DCT分块变换");

[row,col]=size(DCTrgb);
row=floor(row/8);
col=floor(col/8);
alpha=0.02;
k = 1;
temp=0;
for i=0:(row - 1)
    for j=0: (col -1)
        irow = i * 8;
        jcol = j * 8;
        if k <= count
            if msg(k) == 0
                %选择(5,2),(4,3)这两对系数,
                % 策略是(5,2)的DCT系数 < (4,3)时,表示嵌入了0  
                % 如果(5,2) > (4,3) 那我们把两个系数交换,还表示嵌入了0
                if DCTrgb(irow + 5, jcol + 2) < DCTrgb(irow + 4,jcol + 3)
                    temp = DCTrgb(irow + 5, jcol + 2);
                    DCTrgb(irow + 5, jcol + 2) = DCTrgb(irow + 4,jcol + 3);
                    DCTrgb(irow + 4, jcol + 3) = temp;
                end
            else
                if DCTrgb(irow + 5, jcol + 2) > DCTrgb(irow + 4,jcol + 3)
                    temp = DCTrgb(irow + 5, jcol + 2);
                    DCTrgb(irow + 5, jcol + 2) = DCTrgb(irow + 4,jcol + 3);
                    DCTrgb(irow + 4, jcol + 3) = temp;
                end
            end
            %将原本小的系数变的更小,使系数差变大
            if DCTrgb(irow + 5, jcol + 2) < DCTrgb(irow + 4,jcol +3)
                DCTrgb(irow + 5, jcol + 2) = DCTrgb(irow +5, jcol +2) - alpha;
            else
                DCTrgb(irow + 4, jcol + 3) = DCTrgb(irow + 4, jcol +3) - alpha;
            end
            k = k + 1;
        end
    end
end
wi=blkproc(DCTrgb,[8 8],'P1*x*P2',T',T); %嵌入信息的载体DCT变换,恢复图像
orgin_wi=wi/255;
subplot(1,3,3),imshow(orgin_wi),title("嵌入信息后的");

% 提取消息
% ext_msg是提取出的秘密信息
ext_msg = [];
T=dctmtx(8);
DCTcheck=blkproc(wi,[8 8],'P1*x*P2',T,T'); %对隐秘图像进行DCT变换
[row,col]=size(DCTcheck);
row=floor(row/8);
col=floor(col/8);
k = 1;
for i=0:(row - 1)
    for j=0: (col -1)
        irow = i * 8;
        jcol = j * 8;
        %通过比较(5,2),(4,3)这两对系数,判断隐藏的信息是1还是0
        if k <= count
            if DCTcheck(irow + 5, jcol + 2) < DCTcheck(irow + 4,jcol + 3)
                ext_msg(k,1)=1;
            end
            if DCTcheck(irow + 5, jcol + 2) > DCTcheck(irow + 4,jcol + 3)
                ext_msg(k,1)=0;
            end
            k = k + 1;
        end
    end
end
fprintf("嵌入的信息:");
disp(msg);
fprintf("提取的信息:");
disp(ext_msg);

  

参考

1、百度百科

2、知乎

3、DCT实现图像压缩

4、CSDN1   CSDN2 

5、Matlab实现

6、基于MATLAB的RGB转YCBCR色彩空间转换

7、DCT变换可逆信息隐藏原理及代码

免责声明:文章转载自《图像处理-余弦变换》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇YuvImage知识点总结pycharm 设置参数,快捷键下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python图像处理 PIL中convert('L')函数原理

1. img = img.convert()   PIL有九种不同模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。 1.1 img.convert('1')   为二值图像,非黑即白。每个像素用8个bit表示,0表示黑,255表示白。 1.1.1 Code 1 from PIL import Image 2 3 4 def conv...

判断上三角矩阵

2019年春季学期第三周作业 基础作业本周没上课,但是请大家不要忘记学习。本周请大家完成上周挑战作业的第一部分:给定一个整数数组(包含正负数),找到一个具有最大和的子数组,返回其最大的子数组的和。例如:[1, -2, 3, 10, -4, 7, 2, -5]的最大子数组为[3, 10, -4, 7, 2]输入: 请建立以自己英文名字命名的txt文件,并输入...

二维码(QR code)基本知识

1.二维码定义:   二维码(2-Dimensional Bar Code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的。它是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图案表示二进制数据,被设备扫描后可获取其中所包含的信息。一维条码的宽度记载着数据,而其长度没有记载数据。二维条码的长度、...

超详细介绍 图像处理(卷积)(转)

图像处理(卷积)作者太棒了    原文   http://blog.sina.com.cn/s/blog_4bdb170b01019atv.html 图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应) 这里讨论利用输入图像中像素的小邻域来产生输出图像的方法,在信号处理中这种方法称为滤波(filtering)。其中,最常用的是线性滤波:输出...

基于移动最小二乘的图像变形和曲线拟合

在最近的项目中经常遇到给出几个点需要拟合出一条曲线。 在离散的点云中,求曲线曲面拟合,不能简单地连接这些点,如果知道曲线曲面的形式,如为二次曲线等,可以简单地使用最小二乘法估计参数;但如果曲线曲面形式未知,可以使用移动最小二乘法或者主曲线方法。 转载:https://blog.csdn.net/liumangmao1314/article/details/...

python 图像处理:图像的读取、显示与保存

skimage提供了io模块,顾名思义,这个模块是用来图片输入输出操作的。为了方便练习,也提供一个data模块,里面嵌套了一些示例图片,我们可以直接使用。 引入skimage模块可用: from skimage import io skimage包的全称是scikit-image SciKit (toolkit for SciPy) ,它对scipy....