数字信号与图像处理实验三:图像处理基础与图像变换

这篇具有很好参考价值的文章主要介绍了数字信号与图像处理实验三:图像处理基础与图像变换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数字信号与图像处理实验三:图像处理基础与图像变换

实验目的

​ 通过本实验加深对数字图像的理解,熟悉MATLAB中的有关函数;应用DCT对图像进行变换;熟悉图像常见的统计指标,实现图像几何变换的基本方法。

实验内容:

  1. ​ 选择两幅图像,读入图像并显示,同时使用Matlab计算图像的大小,灰度平均值、协方差矩阵、灰度标准差和相关系数。

  2. DCT变换

    RGB = imread('autumn.tif');
    I = rgb2gray(RGB);
    figure(1);
    imshow(I);
    J = dct2(I);
    figure(2);
    imshow(log(abs(J)),[]), colormap(jet(64)), colorbar
    

    观察实验结果,说明figure2中图像色彩变换的规律,并写出其原因。

  3. DCT图像压缩

    I=imread('cameraman.tif');
    I=im2double(I);
    T=dctmtx(8);
    B=blkproc(I,[8 8],'P1*x*P2',T,T');
    mask=[1 1 1 1 0 0 0 0 
             1 1 1 0 0 0 0 0 
             1 1 0 0 0 0 0 0 
             1 0 0 0 0 0 0 0 
             0 0 0 0 0 0 0 0 
             0 0 0 0 0 0 0 0 
             0 0 0 0 0 0 0 0 
             0 0 0 0 0 0 0 0];
    B2=blkproc(B,[8 8],'P1.*x',mask);
    I2=blkproc(B2,[8 8],'P1*x*P2',T',T);
    subplot(1,2,1),imshow(I);
    subplot(1,2,2),imshow(I2);
    

    ① 运行代码,观察实验结果,写出图像压缩的基本原理。

    ② 计算原图像和压缩后图像的差(相减)

    ③ 修改mask矩阵中非0元素的个数,写出修改后的压缩的图像和原图像之间的差和非0元素个数的关系,并比较变换后系数的重要性

    ④ 使用别的图像进行上述实验,验证结论正确与否

  4. 使用C++与OpenCV实现(3)的图像压缩

  5. 编写程序实现图像的水平垂直和中心对称(注:不能用系统的旋转函数)
    :图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

实验要求

  1. 熟悉MATLAB的图像处理函数
  2. 熟练掌握java/C#/C/C++的图像处理方法
  3. 完成程序代码编写

实验过程

What is DCT

维基百科——DCT

​ 离散余弦变换(DCT for Discrete Cosine Transform),是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换(DFT),但是只使用实数。

​ 离散余弦变换,尤其是它的第二种类型,经常被信号处理和图像处理使用,用于对信号和图像(包括静止图像和运动图像)进行有损数据压缩。这是由于离散余弦变换具有很强的"能量集中"特性:大多数的自然信号(包括声音和图像)的能量都集中在离散余弦变换后的低频部分,而且当信号具有接近**马尔科夫过程**(Markov processes)的统计特性时,离散余弦变换的去相关性接近于K-L变换(Karhunen-Loève 变换–它具有最优的去相关性)的性能。

一维DCT变换

一维DCT变换共有种形式,其中最常用的是第种形式,由于其运算简单、适用范围广。

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

f(i):原始信号

F(u):DCT变换后的系数

N:原始信号的点数

c(u):可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵

二维DCT变换

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

MATLAB用到的函数

  • dct2()函数 —— 二维离散余弦变换

  • colormap():查看并设置当前颜色图。

    详解参考

    传参:map —— 新颜色方案的颜色图。例如colormap(jet(64))将当前图窗的颜色图设置为从jet颜色图中选择的64种颜色。

下面列出预定义的颜色图:

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

  • colorbar:在当前坐标区或图的右侧显示一个垂直颜色栏。颜色栏显示当前颜色图并指示数据值到颜色图的映射。

  • blkproc(A, [m,n], fun, parameter1, parameter2, ……)

    [m, n]:图像以m*n为分块单位,对图像进行处理

    fun:应用此函数分别对每个分块单位的像素进行处理

    parameter1, parameter2。。。:fun函数的参数

p1.图像基本操作

读取图像

% 图像读取
I1 = imread('实验三\wallhaven-vqmqrm_1920x1080.png');
I2 = imread('实验三\wallhaven-zyxz9v_1920x1080.png');

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉
:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

读取图像大小

% 图像大小
sizeI1 = size(I1);
sizeI2 = size(I2);

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

转灰度图

% RGB转为灰度图
grayI1 = rgb2gray(I1);
grayI2 = rgb2gray(I2);

计算灰度图均值

% 计算灰度图均值
aveGrayI1 = mean2(grayI1);
aveGrayI2 = mean2(grayI2);

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

计算标准差

v1 = std2(I1);
v2 = std2(I2);

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

计算相关系数

灰度图和中值滤波处理后的图像,计算两者相关系数

% 计算相关系数
I11 = medfilt2(grayI1);     % 中值滤波
r1 = corr2(grayI1, I11);

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

计算协方差

% 计算协方差
% 函数im2double 将其值归一化到[0,1]之间
dI1 = im2double(grayI1);
dI2 = im2double(grayI2);
cov1 = cov(dI1, dI2);

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

显示图像

% 显示图像
subplot(1,2,1);imshow(grayI1);title('灰度图');
subplot(1,2,2);imshow(I11);title('中值滤波');

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

p2. DCT变换

灰度图

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

DCT变换

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

​ 如图,使用dct2函数对灰度图像执行二维DCT。使用对数刻度显示变换后的图像,可以观察到,大部分能量在左上角。

源码

clc
clear
close all

% 图像读取
I1 = imread('实验三\wallhaven-vqmqrm_1920x1080.png');
% I2 = imread('实验三\wallhaven-zyxz9v_1920x1080.png');

% 转灰度图
grayI1 = rgb2gray(I1);

figure(1);
imshow(grayI1);

% dct2
J = dct2(grayI1);
figure(2);
imshow(log(abs(J)),[]);
colormap(jet(64));
colorbar;

% idct2
K = idct2(J);
K = rescale(K);

figure(3);
montage({grayI1, K});
title('Original Grayscale Image (Left) and Processed Image (Right)');


% , colormap(jet(64)), colorbar

p3. DCT图像压缩

示例源码

I=imread('实验三\wallhaven-zyxz9v_1920x1080.png');
I=rgb2gray(I);
I=im2double(I);
T=dctmtx(8);	% 生成一个8*8 DCT变换矩阵
B=blkproc(I,[8 8],'P1*x*P2',T,T');	% x就是每一个分成的8*8大小的块,P1=T,P2=T'
									% P1*x*P2相当于像素块的处理函数
									% 也就是fun=P1*x*P2=T*x*T' 功能是进行DCT
mask=[1 1 1 1 0 0 0 0 
         1 1 1 0 0 0 0 0 
         1 1 0 0 0 0 0 0 
         1 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0];			% 保留左上角10个系数
B2=blkproc(B,[8 8],'P1.*x',mask);	% 舍弃每个块中的高频系数,达到图像压缩的目的
I2=blkproc(B2,[8 8],'P1*x*P2',T',T); % 进行反余弦变换,得到压缩后的图象
figure(1);imshow(I);title('原图');
figure(2);imshow(I2);title('经过IDCT变换后得到的重构图像');

% 注意:如果是三维图象(如RGB)则要先将图像转换成图像变成灰度图象或者用reshape函数转换维数

① 运行代码,观察实验结果,写出图像压缩的基本原理。

运行结果如下:

figure1

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

figure2

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

压缩原理

​ 先将要压缩的图像分割为一定的8×8像素的图像子块,再用DCT把子块变为8×8的DCT系数阵;

然后用一个8×8的量化值阵列(mask)对这些系数进行量化;最后用熵编码器将量化后的系数编码成一串比特数据流.经过传输或存储,比特数据流经过熵解码器进行解码,重新生成一组量化了的DCT系数,使用与编码时相同的量化值阵列对这些量化了的系数进行反量化,利用反向离散余弦变换(IDCT)将此8×8DCT系数阵列变换成空间域的8×8图像子块,最后将反变换后的组合成一幅图像.这样完成了一幅图像的压缩与解压过程。

② 计算原图像和压缩后图像的差(相减)

figure(3);imshow(abs(I-I2));title('原图像与重构图像之差,反应失真程度');
figure3

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

​ 可以看到,原图与重构图像素之间差值很小,为黑色。

③ 修改mask矩阵中非0元素的个数,写出修改后的压缩的图像和原图像之间的差和非0元素个数的关系,并比较变换后系数的重要性

实验结果如下:

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

​ 通过以上实验结果对比图片可知,只保留左上角部分系数,图像还原效果并未受大的影响。

由上个DCT变换中可以注意到,图像DCT系数能量集中在左上方的低频区域,对于一些高频数据,将其置为0后,图像复原并未受较大影响。

​ 对于图像来说,其中的边缘、细节上的信号往往是变化比较快,比较剧烈的。所以,图像中的高频信号对应的是图像中的细节和边缘信息。而图像中的大部分内容信息,往往是变换缓慢、频率低的信号。所以,信号中的低频信号对应主要的图像信息。这样,我们就可以通过DCT,求出对应的不同频域分量,最后只保留低频数据,舍弃高频数据,就可以达到压缩的目的了。

例如一个8乘8的图像块,其DCT变换后的数据,左上角为低频数据,右下角为高频数据,并且数据能量主要集中在低频区域,即低频区域的值比较大,高频区域的值较小。也就是因为高频区域值小,能量低,所以我们可以在接下来的压缩中,将他们置0,在图片质量看起来影响不大的情况下完成压缩。

​ 在这里,我们需要理解一下,为什么低频数据的值就比较大,而高频数据的值比较小呢?首先,对于获得的基函数,低频数值高于高频数值。在设定u=0时,其此时的基函数的取值都等于1,都为正数,如果源信号与此基函数频率相同或相近,那么他们相乘得到的系数将都是相对较大的值,在设定u=1时,其此时的基函数的取值大概为09,0.8,0.5,0.2,-0.2,-0.5,-0.8,-0.9有正数有负数,且绝对值都小于1,那么,对于一个与此信号频率相同的源信号,相乘后的结果较u=0时要小。所以在低频域内得到较大的数值。并且对于一个8*8的图像块非负数据,其最左上角的那个DC值,等于8乘上源信号的平均值;再者,在一般的图像中,低频数据量高于高频数据量,一幅图片中大多数数据,不论是亮度或者是色度,变化都不会很剧烈,所以,低频区域值较大,所占能量更高。:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

源码:

mask1=[1 1 1 0 0 0 0 0 
         1 1 0 0 0 0 0 0 
         1 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0];
mask2=[1 1 0 0 0 0 0 0 
         1 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0];
mask3=[1 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0];
mask4=[1 1 1 1 1 0 0 0 
         1 1 1 1 0 0 0 0 
         1 1 1 0 0 0 0 0 
         1 1 0 0 0 0 0 0 
         1 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0 
         0 0 0 0 0 0 0 0];
mask5=[1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 0 
         1 1 1 1 1 1 0 0 
         1 1 1 1 1 0 0 0 
         1 1 1 1 0 0 0 0 
         1 1 1 0 0 0 0 0 
         1 1 0 0 0 0 0 0 
         1 0 0 0 0 0 0 0];


mask6=[0 0 0 0 0 0 0 1 
         0 0 0 0 0 0 1 1 
         0 0 0 0 0 1 1 1 
         0 0 0 0 1 1 1 1 
         0 0 0 1 1 1 1 1 
         0 0 1 1 1 1 1 1 
         0 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1];
mask7=[0 0 0 0 0 0 1 1 
         0 0 0 0 0 1 1 1 
         0 0 0 0 1 1 1 1 
         0 0 0 1 1 1 1 1 
         0 0 1 1 1 1 1 1 
         0 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1];
mask8=[0 0 0 0 0 1 1 1 
         0 0 0 0 1 1 1 1 
         0 0 0 1 1 1 1 1 
         0 0 1 1 1 1 1 1 
         0 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1];
mask9=[0 0 0 0 1 1 1 1 
         0 0 0 1 1 1 1 1 
         0 0 1 1 1 1 1 1 
         0 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1];
mask10=[0 0 0 1 1 1 1 1 
         0 0 1 1 1 1 1 1 
         0 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1 
         1 1 1 1 1 1 1 1];
B2 = blkproc(B,[8 8],'P1.*x',mask1);
I2 = blkproc(B2,[8 8],'P1*x*P2',T',T);
B3 = blkproc(B,[8 8],'P1.*x',mask2);
I3 = blkproc(B3,[8 8],'P1*x*P2',T',T);
B4 = blkproc(B,[8 8],'P1.*x',mask3);
I4 = blkproc(B4,[8 8],'P1*x*P2',T',T);
B5 = blkproc(B,[8 8],'P1.*x',mask4);
I5 = blkproc(B5,[8 8],'P1*x*P2',T',T);
B6 = blkproc(B,[8 8],'P1.*x',mask5);
I6 = blkproc(B6,[8 8],'P1*x*P2',T',T);

B7 = blkproc(B,[8 8],'P1.*x',mask6);
I7 = blkproc(B7,[8 8],'P1*x*P2',T',T);
B8 = blkproc(B,[8 8],'P1.*x',mask7);
I8 = blkproc(B8,[8 8],'P1*x*P2',T',T);
B9 = blkproc(B,[8 8],'P1.*x',mask8);
I9 = blkproc(B9,[8 8],'P1*x*P2',T',T);
B10 = blkproc(B,[8 8],'P1.*x',mask9);
I10 = blkproc(B10,[8 8],'P1*x*P2',T',T);
B11 = blkproc(B,[8 8],'P1.*x',mask10);
I11 = blkproc(B11,[8 8],'P1*x*P2',T',T);

figure(1);
subplot(3,2,1);imshow(I);title('原图');
subplot(3,2,2);imshow(I2);title('mask保留左上角6个系数');
subplot(3,2,3);imshow(I3);title('mask保留左上角3个系数');
subplot(3,2,4);imshow(I4);title('mask保留左上角1个系数');
subplot(3,2,5);imshow(I5);title('mask保留左上角15个系数');
subplot(3,2,6);imshow(I6);title('mask保留左上角36个系数');

figure(2);
subplot(3,2,1);imshow(I);title('原图');
subplot(3,2,2);imshow(I7);title('mask保留右下角36个系数');
subplot(3,2,3);imshow(I8);title('mask保留右下角43个系数');
subplot(3,2,4);imshow(I9);title('mask保留右下角49个系数');
subplot(3,2,5);imshow(I10);title('mask保留右下角54个系数');
subplot(3,2,6);imshow(I11);title('mask保留右下角58个系数');

④ 使用别的图像进行上述实验,验证结论正确与否

实验序号:2

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

实验序号:3

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

P4.OpenCV C++代码复现

Mat相关

Mat类的成员函数
col(int i)  //获取第i列数据,返回也是Mat类型

row(int j)  //获取第j行数据,返回也是Mat类型

size()  //矩阵尺寸[rows, cols]

total()  //rows* cols,而非矩阵元素数

channels()  //图像通道数

rowRange()colRange() // 读取连续几行或者几列

m.rowRange(2,4)

遍历像素函数at()

格式为:myMat.at<float>(i, j) 获取矩阵第i行第j列的元素

获取矩阵行首元素指针ptr(),格式为mymat.ptr<int>(i)  指向第i行首元素的指针

m.isContiuous()每一行是否连续存储的。
多通道Mat访问
# 用at进行多通道访问,对应的数据类型如下:
typedef Vec<uchar, 2> Vec2b; //无符号双通道 CV_8U:0~255
typedef Vec<uchar, 3> Vec3b; //无符号3通道
typedef Vec<uchar, 4> Vec4b;
typedef Vec<short, 2> Vec2s; //short型双通道 CV_16S:-32768~32767
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;
typedef Vec<int, 2> Vec2i; //整型双通道 CV_32S:-2147483648~2147483647
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<float, 2> Vec2f; //浮点型双通道 CV_32F:1.1810-38~3.401038
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;
typedef Vec<double, 2> Vec2d; //double型双通道 CV_64F:2.2310-308~1.7910308
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;
OpenCV三通道图像Mat遍历
cout<<"Mat src:"<<endl;
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            cout<<""<<src.at<Vec3d>(i, j)<<"  ";
        }
        cout<<endl;
    }

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

dctmtx()函数复现

根据一维DCT变换公式计算即可

void dctmtx8(Mat A){  // 8*8
    for(int i=0; i<A.rows; ++i){
        for(int j=0; j<A.cols; ++j){
            double a;
            if(i==0){
                a = sqrt(1.0 / A.rows);
            }else{
                a = sqrt(2.0 / A.rows);
            }
            A.at<double>(i, j) = a * cos((j + 0.5) * M_PI * i / A.rows);
        }
    }
}

DCT变换 or IDCT

A * ROIMat * A'

IDCT只需修改一行计算公式即可

A' * ROIMat * A

void myDct(Mat image, Mat A){
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动

    for(int i = 0; i < image.size().height/8; i++)
    {
        for (int j = 0; j < image.size().width/8; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			
			ROIMat = A * ROIMat * A.t(); // DCT
            //  ROIMat = A.t() * ROIMat * A; IDCT
		}
    }

}

mask 量化函数

// 量化 复现 B2=blkproc(B,[8 8],'P1.*x',mask);	% 舍弃每个块中的高频系数,达到图像压缩的目的
void maskimg(Mat image){
    for(int i = 0; i < image.size().height; i++)
    {
        for (int j = 0; j < image.size().width; j++)
		{
            if(mask[j%8][i%8]==0){
                image.at<double>(i, j) = 0.0;
            }
		}
    }
}

图像大小扩充至8的倍数(补零操作,最后再复原)

//形状扩充
int adjust_width = width;
    if(width % 8 != 0){
        adjust_width = adjust_width + 8 - (width % 8);
    }
    int adjust_height = height;
    if(height % 8 != 0){
        adjust_height = adjust_height + 8 - (height % 8);
    }
    cout<<"expand img width:"<<adjust_width<<" height:"<<adjust_height<<endl;
    big_dgsrc = Mat(adjust_height, adjust_width, CV_64FC1, 0.0);
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            big_dgsrc.at<double>(i, j) = dgsrc.at<double>(i, j);
        }
    }

// 形状复原
for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            dgsrc.at<double>(i, j) = big_dgsrc.at<double>(i, j);
        }
    }

多通道处理

BGR转YUV,分解为三通道,分别对各通道数据作DCT、量化、IDCT。

最后合并即可实现。

实验结果(灰度图DCT图像压缩)

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

实验结果(RGB图DCT图像压缩)

保留左上角10个系数

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

保留左上角6个系数

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉

源码(dctimg.cpp)

#include<opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include<iostream>
#include<math.h>

#define M_PI 3.14159265358979323846 
using namespace std;
using namespace cv;
int width,height;
double msk[8][8] = { 
                        {1,1,1,1,1,0,0,0},
                        {1,1,1,1,0,0,0,0},
                        {1,1,1,0,0,0,0,0},
                        {1,1,0,0,0,0,0,0},
                        {1,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0}};


void dctmtx8(Mat A){  // 生成一个8*8 DCT变换矩阵
    for(int i=0; i<A.rows; ++i){
        for(int j=0; j<A.cols; ++j){
            double a;
            if(i==0){
                a = sqrt(1.0 / A.rows);
            }else{
                a = sqrt(2.0 / A.rows);
            }
            A.at<double>(i, j) = a * cos((j + 0.5) * M_PI * i / A.rows);
        }
    }
}

void myDct(Mat image, Mat A){
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动

    for(int i = 0; i < height/8; i++)
    {
        for (int j = 0; j < width/8; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			//X = AXA'
			ROIMat = A * ROIMat * A.t();
		}
    }

    for(int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
		{
            if(height - i < 8 || width -j < 8){
                continue;
            }
            if(msk[j%8][i%8]==0){
                image.at<double>(i, j) = 0.0;
            }
		}
    }
		
}


Mat myIDct(Mat image, Mat A){
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动
    Mat res;
    for(int i = 0; i < height/8; i++)
    {
        for (int j = 0; j < width/8 ; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			ROIMat = A.t() * ROIMat * A;
		}
    }
    image.convertTo(res, CV_8UC1);
    return res;
}



int main(){

    Mat src;
    Mat graysrc;
    Mat dgsrc;
    src = imread("/home/luffy/digital/img/luffy14.jpg");
    if (src.empty())
    {
        cout << "没有读取到图像" << endl;
        return -1;
    }
    cvtColor(src, graysrc, COLOR_BGR2GRAY);
    // width == cols
    // height == rows;
    width = src.size().width;
    height = src.size().height;
    cout<<"img width: "<<width<<" height: "<<height<<endl;
    Mat A(8, 8, CV_64FC1);// 离散余弦系数矩阵 
    //基于8*8块的DCT变换及其反变换
    //计算A系数
	dctmtx8(A);
    //转换成浮点数矩阵,进行dct变换
	graysrc.convertTo(dgsrc, CV_64FC1);
    myDct(dgsrc, A);
    //计算压缩率, 用非零矩阵点数量比总数量、
	// gsrc.convertTo(graysrc, CV_8UC1);
	// double dctRate = countNonZero(graysrc) / (420.0 * 320.0);
	// cout << "the size becomes " << dctRate * 100 << "% of the original." << endl;
	// Rect windows();		 //利用这个8*8的矩形来进行8*8块的DCT变换
    imshow("原图像", graysrc);
    imshow("DCT变化、量化后的压缩图", dgsrc);
    Mat res = myIDct(dgsrc, A);
    imshow("IDCT恢复后的图像", res);
    waitKey(0);
    return 0;
}

源码(rgbdctimg.cpp)

#include<opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include<iostream>
#include<math.h>

#define M_PI 3.14159265358979323846 
using namespace std;
using namespace cv;
int width,height;
double msk[8][8] = { 
                        {1,1,1,1,1,0,0,0},
                        {1,1,1,1,0,0,0,0},
                        {1,1,1,0,0,0,0,0},
                        {1,1,0,0,0,0,0,0},
                        {1,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0}};


void dctmtx8(Mat A){  // 8*8
    for(int i=0; i<A.rows; ++i){
        for(int j=0; j<A.cols; ++j){
            double a;
            if(i==0){
                a = sqrt(1.0 / A.rows);
            }else{
                a = sqrt(2.0 / A.rows);
            }
            A.at<double>(i, j) = a * cos((j + 0.5) * M_PI * i / A.rows);
        }
    }
}

void myDct(Mat image, Mat A){
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动

    for(int i = 0; i < height/8; i++)
    {
        for (int j = 0; j < width/8; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			//X = AXA'
			ROIMat = A * ROIMat * A.t();
		}
    }

    for(int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
		{
            if(height - i < 8 || width -j < 8){
                continue;
            }
            if(msk[j%8][i%8]==0){
                image.at<double>(i, j) = 0.0;
            }
		}
    }
		
}


void myIDct(Mat image, Mat A){
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动
    Mat res;
    for(int i = 0; i < height/8; i++)
    {
        for (int j = 0; j < width/8 ; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			//X = AXA'
			ROIMat = A.t() * ROIMat * A;
		}
    }
}



int main(){

    Mat src;
    src = imread("/home/luffy/digital/img/luffy14.jpg");
    if (src.empty())
    {
        cout << "没有读取到图像" << endl;
        return -1;
    }
    // width == cols
    // height == rows;
    width = src.size().width;
    height = src.size().height;
    cout<<"img width: "<<width<<" height: "<<height<<endl;

    //分解为YUV颜色空间
	Mat YUVImage;
	cvtColor(src,YUVImage,COLOR_BGR2YUV);
	
	//分解为三个通道
	vector<Mat> YUV;
	split(YUVImage,YUV);
	
	//先转换下格式
	Mat Y, U, V;
	YUV[0].convertTo(Y,CV_64FC1);
	YUV[1].convertTo(U,CV_64FC1);
	YUV[2].convertTo(V,CV_64FC1);
    Mat A(8, 8, CV_64FC1);  // 离散余弦系数矩阵
    //计算A系数
	dctmtx8(A);
    myDct(Y, A);
    myDct(U, A);
    myDct(V, A);
    imshow("原图像", src);
    imshow("DCT_Y", Y);
    imshow("DCT_U", U);
    imshow("DCT_V", V);
    //计算压缩率, 用非零矩阵点数量比总数量、
	// gsrc.convertTo(graysrc, CV_8UC1);
	// double dctRate = countNonZero(graysrc) / (420.0 * 320.0);
	// cout << "the size becomes " << dctRate * 100 << "% of the original." << endl;
	// Rect windows();		 //利用这个8*8的矩形来进行8*8块的DCT变换

    myIDct(Y, A);
    myIDct(U, A);
    myIDct(V, A);

    vector<Mat> YUV_dst(3);
	//格式转换
	Y.convertTo(YUV_dst[0],CV_8UC1);
	U.convertTo(YUV_dst[1],CV_8UC1);
    V.convertTo(YUV_dst[2],CV_8UC1);
 
	//将三个通道进行合并
	Mat yuv,dst_RGB;
	merge(YUV_dst,yuv);
 
	//转为RGB图像
	cvtColor(yuv,dst_RGB,COLOR_YUV2BGR);
    imshow("恢复后的图像", dst_RGB);
    waitKey(0);
    return 0;
}

源码(改)dctimg2.cpp

#include<opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include<iostream>
#include<math.h>

#define M_PI 3.14159265358979323846 
using namespace std;
using namespace cv;
double mask[8][8] = { 
                        {1,1,1,1,0,0,0,0},
                        {1,1,1,0,0,0,0,0},
                        {1,1,0,0,0,0,0,0},
                        {1,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0}};

// 复现 T=dctmtx(8); 生成一个8*8 DCT变换矩阵
void dctmtx8(Mat A){
    for(int i=0; i<A.rows; ++i){
        for(int j=0; j<A.cols; ++j){
            double a;
            if(i==0){
                a = sqrt(1.0 / A.rows);
            }else{
                a = sqrt(2.0 / A.rows);
            }
            A.at<double>(i, j) = a * cos((j + 0.5) * M_PI * i / A.rows);
        }
    }
}

//复现 I2=blkproc(B2,[8 8],'P1*x*P2',T',T); % 进行反余弦变换,得到压缩后的图象
void myDct(Mat image, Mat A){   
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动

    for(int i = 0; i < image.size().height/8; i++)
    {
        for (int j = 0; j < image.size().width/8; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			//X = AXA'
			ROIMat = A * ROIMat * A.t();
		}
    }	
}

// 量化 复现 B2=blkproc(B,[8 8],'P1.*x',mask);	% 舍弃每个块中的高频系数,达到图像压缩的目的
void maskimg(Mat image){
    for(int i = 0; i < image.size().height; i++)
    {
        for (int j = 0; j < image.size().width; j++)
		{
            if(mask[j%8][i%8]==0){
                image.at<double>(i, j) = 0.0;
            }
		}
    }
}

// 复现 I2=blkproc(B2,[8 8],'P1*x*P2',T',T); % 进行反余弦变换,得到解压缩后的图像
void myIDct(Mat image, Mat A){
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动
    for(int i = 0; i < image.size().height/8; i++)
    {
        for (int j = 0; j < image.size().width/8 ; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			ROIMat = A.t() * ROIMat * A;
		}
    }
}


int main(){

    Mat src, graysrc, big_dgsrc, dgsrc;
    src = imread("/home/luffy/digital/img/luffy14.jpg");
    if (src.empty())
    {
        cout << "没有读取到图像" << endl;
        return -1;
    }
    cvtColor(src, graysrc, COLOR_BGR2GRAY); // 转为灰色图
    // width == cols
    // height == rows;
    // 图像的宽、高度
    int width = src.size().width;
    int height = src.size().height;
    cout<<"img width: "<<width<<" height: "<<height<<endl;
    Mat A(8, 8, CV_64FC1);// 离散余弦系数矩阵 
    //基于8*8块的DCT变换及其反变换
    //计算A系数
	dctmtx8(A);
    //转换成浮点数矩阵,进行dct变换
	graysrc.convertTo(dgsrc, CV_64FC1);
    
    int adjust_width = width;
    if(width % 8 != 0){
        adjust_width = adjust_width + 8 - (width % 8);
    }
    int adjust_height = height;
    if(height % 8 != 0){
        adjust_height = adjust_height + 8 - (height % 8);
    }
    cout<<"expand img width:"<<adjust_width<<" height:"<<adjust_height<<endl;
    big_dgsrc = Mat(adjust_height, adjust_width, CV_64FC1, 0.0);
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            big_dgsrc.at<double>(i, j) = dgsrc.at<double>(i, j);
        }
    }
    myDct(big_dgsrc, A);
    maskimg(big_dgsrc);
    
    //计算压缩率, 用非零矩阵点数量比总数量、
	// gsrc.convertTo(graysrc, CV_8UC1);
	// double dctRate = countNonZero(graysrc) / (420.0 * 320.0);
	// cout << "the size becomes " << dctRate * 100 << "% of the original." << endl;
	// Rect windows();		 //利用这个8*8的矩形来进行8*8块的DCT变换
    imshow("原图像", graysrc);
    Mat res1;
    big_dgsrc.convertTo(res1, CV_8UC1);
    imshow("DCT变化、量化后的压缩图", res1);
    myIDct(big_dgsrc, A);
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            dgsrc.at<double>(i, j) = big_dgsrc.at<double>(i, j);
        }
    }
    Mat res2;
    dgsrc.convertTo(res2, CV_8UC1);
    imshow("IDCT恢复后的图像", res2);
    waitKey(0);
    return 0;
}

源码(改)rgbdctimg2.cpp

#include<opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include<iostream>
#include<math.h>

#define M_PI 3.14159265358979323846 
using namespace std;
using namespace cv;
int width,height;
double mask[8][8] = { 
                        {1,1,0,0,0,0,0,0},
                        {1,1,0,0,0,0,0,0},
                        {1,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0}};

// 复现 T=dctmtx(8); 生成一个8*8 DCT变换矩阵
void dctmtx8(Mat A){
    for(int i=0; i<A.rows; ++i){
        for(int j=0; j<A.cols; ++j){
            double a;
            if(i==0){
                a = sqrt(1.0 / A.rows);
            }else{
                a = sqrt(2.0 / A.rows);
            }
            A.at<double>(i, j) = a * cos((j + 0.5) * M_PI * i / A.rows);
        }
    }
}

//复现 I2=blkproc(B2,[8 8],'P1*x*P2',T',T); % 进行反余弦变换,得到压缩后的图象
void myDct(Mat image, Mat A){   
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动

    for(int i = 0; i < image.size().height/8; i++)
    {
        for (int j = 0; j < image.size().width/8; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			//X = AXA'
			ROIMat = A * ROIMat * A.t();
		}
    }	
}

// 量化 复现 B2=blkproc(B,[8 8],'P1.*x',mask);	% 舍弃每个块中的高频系数,达到图像压缩的目的
void maskimg(Mat image){
    for(int i = 0; i < image.size().height; i++)
    {
        for (int j = 0; j < image.size().width; j++)
		{
            if(mask[j%8][i%8]==0){
                image.at<double>(i, j) = 0.0;
            }
		}
    }
}

// 复现 I2=blkproc(B2,[8 8],'P1*x*P2',T',T); % 进行反余弦变换,得到解压缩后的图像
void myIDct(Mat image, Mat A){
    Mat ROIMat = Mat(8, 8, CV_64FC1);	//用于分块处理的时候在原图像上面移动
    for(int i = 0; i < image.size().height/8; i++)
    {
        for (int j = 0; j < image.size().width/8 ; j++)
		{
            ROIMat = image(Rect(j * 8, i * 8, 8, 8));
			ROIMat = A.t() * ROIMat * A;
		}
    }
}



int main(){

    Mat src;
    src = imread("/home/luffy/digital/img/luffy14.jpg");
    if (src.empty())
    {
        cout << "没有读取到图像" << endl;
        return -1;
    }
    // width == cols
    // height == rows;
    width = src.size().width;
    height = src.size().height;
    cout<<"img width: "<<width<<" height: "<<height<<endl;

    //分解为YUV颜色空间
	Mat YUVImage;
	cvtColor(src,YUVImage,COLOR_BGR2YUV);
	
	//分解为三个通道
	vector<Mat> YUV;
	split(YUVImage,YUV);
	
	//转换为64位浮点数据类型
	Mat Y, U, V;
	YUV[0].convertTo(Y,CV_64FC1);
	YUV[1].convertTo(U,CV_64FC1);
	YUV[2].convertTo(V,CV_64FC1);

    Mat A(8, 8, CV_64FC1);  // 离散余弦系数矩阵
    //计算A系数
	dctmtx8(A);
    int adjust_width = width;
    if(width % 8 != 0){
        adjust_width = adjust_width + 8 - (width % 8);
    }
    int adjust_height = height;
    if(height % 8 != 0){
        adjust_height = adjust_height + 8 - (height % 8);
    }
    cout<<"expand img width:"<<adjust_width<<" height:"<<adjust_height<<endl;
    Mat Y1 = Mat(adjust_height, adjust_width, CV_64FC1, 0.0);
    Mat U1 = Mat(adjust_height, adjust_width, CV_64FC1, 0.0);
    Mat V1 = Mat(adjust_height, adjust_width, CV_64FC1, 0.0);
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            Y1.at<double>(i, j) = Y.at<double>(i, j);
        }
    }
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            U1.at<double>(i, j) = U.at<double>(i, j);
        }
    }
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            V1.at<double>(i, j) = V.at<double>(i, j);
        }
    }
    myDct(Y1, A);
    myDct(U1, A);
    myDct(V1, A);
    maskimg(Y1);
    maskimg(U1);
    maskimg(V1);
    imshow("原图像", src);
    imshow("DCT_Y通道", Y1);
    imshow("DCT_U通道", U1);
    imshow("DCT_V通道", V1);

    myIDct(Y1, A);
    myIDct(U1, A);
    myIDct(V1, A);

    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            Y.at<double>(i, j) = Y1.at<double>(i, j);
        }
    }
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            U.at<double>(i, j) = U1.at<double>(i, j);
        }
    }
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
            V.at<double>(i, j) = V1.at<double>(i, j);
        }
    }
    vector<Mat> YUV_dst(3);
	//格式转换
	Y.convertTo(YUV_dst[0],CV_8UC1);
	U.convertTo(YUV_dst[1],CV_8UC1);
    V.convertTo(YUV_dst[2],CV_8UC1);
 
	//将三个通道进行合并
	Mat yuv,dst_RGB;
	merge(YUV_dst,yuv);
	//转为RGB图像
	cvtColor(yuv,dst_RGB,COLOR_YUV2BGR);
    imshow("恢复后的图像", dst_RGB);
    waitKey(0);
    return 0;
}

P5 图像对称

主要图像处理代码

水平对称,分别对每行的数据水平翻转即可;

//水平对称处理 horizontal_src
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            horizontal_src.at<Vec3b>(i, j) = src.at<Vec3b>(i, width-j-1);
        }
    }

垂直对称,分别对每列的数据垂直翻转即可;

//垂直对称
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            vertical_src.at<Vec3b>(i, j) = src.at<Vec3b>(height-i-1, j);
        }
    }

中心对称,水平+垂直对称。

//中心对称
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            center_src.at<Vec3b>(i, j) = src.at<Vec3b>(height-i-1, width-j-1);
        }
    }

运行效果如下图:

:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉
:图像处理基础与图像变换实验目的:通过本实验加深对数字图像的理解,熟悉matlab中,C++,图像处理,matlab,计算机视觉文章来源地址https://www.toymoban.com/news/detail-763678.html

源码
#include<opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include<iostream>
#include<math.h>

#define M_PI 3.14159265358979323846 
using namespace std;
using namespace cv;
int width,height;

int main(){
    Mat src, horizontal_src, vertical_src, center_src;
    src = imread("/home/luffy/digital/img/luffy14.jpg");
    if (src.empty())
    {
        cout << "没有读取到图像" << endl;
        return -1;
    }
    // width == cols
    // height == rows;
    width = src.size().width;
    height = src.size().height;
    //深拷贝
    horizontal_src = src.clone();
    vertical_src = src.clone();
    center_src = src.clone();

    cout<<"img width: "<<width<<" height: "<<height<<endl;
    cout<<"channel: "<<src.channels()<<endl;
    cout<<"img processing ..."<<endl;
    //水平对称处理 horizontal_src
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            horizontal_src.at<Vec3b>(i, j) = src.at<Vec3b>(i, width-j-1);
        }
    }
    //垂直对称
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            vertical_src.at<Vec3b>(i, j) = src.at<Vec3b>(height-i-1, j);
        }
    }
    //中心对称
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            center_src.at<Vec3b>(i, j) = src.at<Vec3b>(height-i-1, width-j-1);
        }
    }
    cout<<"done !"<<endl;
    imshow("原图像",src);
    imshow("水平对称处理",horizontal_src);
    imshow("垂直对称处理", vertical_src);
    imshow("中心对称处理", center_src);
    waitKey(0);
    return 0;
}

到了这里,关于数字信号与图像处理实验三:图像处理基础与图像变换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python数字图像处理基础(七)——直方图均衡化、傅里叶变换

    均衡化原理 图像均衡化是一种基本的图像处理技术,通过更新图像直方图的像素强度分布来调整图像的全局对比度。这样做可以使低对比度的区域在输出图像中获得更高的对比度。 简单理解:改变图像对比度,让色彩更丰富,灰度值直方图:瘦高 - 均衡 本质上,直方图均衡

    2024年01月18日
    浏览(40)
  • 数字图像处理 关于matlab的图像变换

    熟悉及掌握图像的傅里叶变换、离散余弦变化原理及性质,实现图像的频率域变换。 1. 读入一幅图像,分别为图像添加叠加密度为0.04的椒盐噪声,均值为0方差为0.02的高斯噪声,做FFT变换。将原始图像、原始图像频谱图、添加噪声后的图像,以及噪声图像的频谱图同时显示出

    2024年02月05日
    浏览(34)
  • 数字图像处理中对数变换与Gamma变换

    1.对数变换 图像的对数变换主要的作用是压缩动态范围,原因是对数曲线在像素值较低的区域斜率大,在像素值较高的区域斜率较小,所以图像经过对数变换后,较暗区域的对比度将有所提升,所以就可以增强图像的暗部细节。 其中, c c c 是一个常数, f f f 是浮点数。对数

    2024年02月07日
    浏览(28)
  • 数字图像处理:亮度对比度-几何变换-噪声处理

    亮度与对比度转换 图像变换可分为以下两种: 点算子:基于像素变换,在这一类图像变换中,仅仅根据输入像素值计算相应的输出像素值 邻域算子:基于图像区域进行变换 两种常用的点算子是用常数对点的像素值进行乘法或加法运算,可以表示为: g ( i , j ) = α ∗ f ( i ,

    2024年02月10日
    浏览(43)
  • 《数字图像处理-OpenCV/Python》连载(44)图像的投影变换

    本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 几何变换分为等距变换、相似变换、仿射变换和投影变换,是指对图像的位置、大小、形状和投影进行变换,将图像从原始平面投影到新的视平面。OpenCV图像的几

    2024年02月04日
    浏览(45)
  • Matlab|数字图像处理02|图像的傅里叶变换(平移/旋转性质)及图像的离散余弦变换

    问题1:x,y方向同时平移后频谱有何变化? 答:经过平移后的傅里叶变换幅值图与原图像得到的傅里叶变换幅值图基本相同,平移不改变频谱的幅值。 代码运行结果: 代码: 问题2:编程验证一幅图旋转45度后,其傅里叶谱图也旋转了45度。 代码: 问题3:第8行10的数字大小对

    2024年02月08日
    浏览(31)
  • (数字图像处理MATLAB+Python)第四章图像正交变换-第四、五节:Radon变换和小波变换

    Radon变换 :是一种用于将图像从空间域转换到投影域的数学工具,其基本思想是将图像中每个点的灰度值投影到一组直线上,然后将这些投影合并在一起形成投影域。Radon变换可以用于多种图像处理任务,包括图像重建、特征提取、图像分割等 Radon变换原理 :给定一个函数

    2023年04月20日
    浏览(31)
  • 数字图像处理实验——数字图像处理初步

    一、实验目的与要求 1.熟悉及掌握在MATLAB中能够处理哪些格式的图像; 2.熟练掌握在MATLAB中如何读取图像及图像的属性信息(大小、颜色、亮度(灰度)、宽度、高度等); 3.掌握如何在MATLAB中按照指定要求存储一副图像的方法; 4.了解图像的算术运算在数字图像中的初步应

    2024年02月04日
    浏览(33)
  • (数字图像处理MATLAB+Python)第四章图像正交变换-第一节:离散傅里叶变换

    一维离散傅里叶变换(Discrete Fourier Transform,DFT) :是一种数学技术,用于将代表离散时间信号的N个复数序列从 时域转换到频域 。DFT被广泛用于许多应用,如音频和图像处理、通信和控制系统。DFT是傅里叶变换的离散版本,傅里叶变换是一种用于分析频域信号的连续数学技

    2023年04月13日
    浏览(71)
  • 数字图像处理:实验三 图像增强

    图像增强是数字图像处理过程中常采用的一种方法。为了改善视觉效果或便于人和机器对图像的理解和分析,根据图像的特点或存在的问题采取的改善方法或加强特征的措施称为图像增强。图像增强处理是改变图像视觉效果的手段,增强后的图像便于对它的后续处理。图像增

    2024年02月04日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包