图像处理基础与图像变换

news2025/5/13 17:37:51

一、目的

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

二、内容与设计思想

1、实验内容:选择两幅图像,读入图像并显示,同时使用Matlab计算图像的大小、灰度平均值、协方差矩阵、灰度标准差和相关系数。
设计思想:
(1)图像读取和预处理:通过 imread 读取两张图像,确保图像文件路径正确并能够成功加载,并将彩色图像转换为灰度图像。
(2)灰度平均值:通过mean函数计算两幅图像的灰度平均值,反映图像的亮度特征。每个像素的灰度值可以理解为一个标量,整个图像的灰度平均值提供了该图像的整体亮度信息。
(3)协方差矩阵:使用cov函数计算图像的灰度值的协方差,反映图像中不同像素之间的灰度关系。这里,使用cov(double(picture(: )))是为了将图像的像素值展平为一维向量后计算其协方差。
(4)标准差:通过std函数计算每张图像的灰度标准差,标准差反映了图像灰度值的分布离散程度。标准差越大,表示图像灰度变化越剧烈,细节丰富;标准差越小,图像灰度变化较平稳,细节较少。
(5)计算图像相关系数:使用corr2 函数来计算两幅图像的相关系数。
输出结果:
在这里插入图片描述

根据实验的输出结果,可以得到,它们的图像的尺寸一致;两幅图像的灰度平均值非常接近,差异约为 1.06。灰度平均值反映了图像的亮度,较高的平均值表示图像整体较亮。这个差异相对较小,说明两幅图像在亮度方面比较接近;两幅图像的协方差矩阵相差不大,差异仅约为 30,说明它们的灰度变化模式相似;标准差衡量的是灰度值的波动性,标准差越大,图像的灰度变化越剧烈,细节更多。两幅图像的标准差差异也非常小,仅约 0.32,表明它们在灰度变化的分布上相差不大;相关系数为-0.0391,意味着两幅图像在灰度分布上的相似性较低。负值说明两幅图像在某些灰度层级上呈现出一定的反向关系,但由于值非常接近 0,说明它们的整体结构或模式差异较大。

2、实验内容:选择一幅图像,并对其添加高斯噪声,重复步骤多次,再将所得到的图像相加取平均,检验加法去噪的效果,写出加法去噪的原理。
设计思想:
通过imread函数加载图像,并循环用imnoise函数生成的带有高斯噪声的图像,尺寸与原始图像相同。在每次循环中,图像J会被加到total中,total是初始化为一个大小与原图像相同的零矩阵,用于存储所有噪声图像的累加结果。将 total除以num得到去噪的平均图像。最终,转换为uint8类型,以便显示和处理。
输出结果:
在这里插入图片描述

可以看到原始图像显示的是没有任何噪声的清晰图像;带噪图像很模糊,图像细节可能会被模糊或丢失。显示的带噪图像可能会出现斑点或颜色不一致的现象,尤其在高噪声区域更加明显;加法去噪后能看到通过对多张带噪图像进行平均,噪声会被部分抵消,因为噪声是随机分布的,多个带噪图像的平均值能够减轻噪声的影响,恢复图像的真实细节,但相比于原始图像还是比较模糊。

3、实验内容:FFT变换
设计思想:
f=zeros(30,30); f(5:24,13:17)=1; 创建了一个30x30的矩阵,其中中间区域为白色矩形(值为 1),其余区域为黑色(值为 0)。通过 fft2(f) 对图像进行二维快速傅里叶变换,得到频域表示 F。 log(abs(F)) 对频域结果取模并对其取对数,用于增强可视化效果。imshow(F2,[-1 5]) 将频域的图像显示出来,[-1 5] 设置了显示的像素值范围,colormap(jet) 使用了“jet”色图。修改后的代码中,fft2(f, 256, 256) 对图像进行了零填充,将图像的大小从 30x30 增加到 256x256。fftshift(F) 将频谱从左上角的低频区域移到图像中心,使得频域图像更容易观察。
输出结果:
①如图所示:
在这里插入图片描述

原图像(左图)显示为一个简单的30x30图像,其中白色矩形处表示一个频率信号的集中区域。频域图像(右图) 会显示傅里叶变换后的频谱。由于输入图像的大小较小且只包含一个简单的矩形区域,频域图像的中心部分通常包含了低频信息,而周围则是高频信息的表现。
②如图所示:
在这里插入图片描述

对比可得,原始图像的傅里叶变换可能会使得低频部分偏离图像的中央,fftshift函数则会将这些低频部分移动到中心。fftshift 函数会将图像的频谱中的低频分量从四个角落移到频谱的中心位置,使得频域图像更加对称,便于观察。
③如图所示:
在这里插入图片描述

当增大图像尺寸(60x60)和白色矩形区域的大小(15:46, 13:47)时,傅里叶变换后频域的分辨率提高,频域图像的细节更清晰,出现更多的高频分量,低频部分更加集中且分布更加均匀。
原因:这些变化的原因在于傅里叶变换是基于图像的空间频率特性进行转换的,不同的图像内容和尺寸都会影响频域的表现。

4、输出结果:
在这里插入图片描述

图像色彩变换规律:在 DCT 变换后,图像的频域表示被提取出来,原始的空间域图像被转化成频率信息,低频成分集中在图像的左上角,它们通常对应于图像中变化较少、细节较少的区域,高频成分集中在图像的右下角,对应的是图像中细微的变化和快速的像素变化,通常位于图像的边缘和细节部分。
图像的颜色发生变化的原因:在进行 DCT 变换后,图像的频率成分会呈现出很大的动态范围。例如,低频成分的幅值通常较大,而高频成分幅值较小。为了增强对比度和细节,通常采用对数变换(log(abs(J))),这样做可以有效扩展图像中细节较少的部分,使高频部分更可见,从而影响图像的颜色表现。jet(64)是一种颜色映射方案,它将数值范围映射到一系列颜色上,通常从蓝色到红色表示数值从低到高。在 DCT 变换后的图像中,频率较低的区域(左上角)会映射到图像的某一颜色(如红色),而频率较高的区域(右下角)则会映射到另一种颜色(如蓝色)。这会导致图像显示出明显的色彩变化。

5、①图像压缩的基本原理:
频率域表示:通过DCT变换,将图像从空间域转换到频率域。
去除冗余信息:通过丢弃图像的高频信息,减少存储的数据量。
重建图像:通过逆DCT变换,将图像从频率域恢复回空间域。
图像压缩通过这种方式实现了数据量的压缩,且通常会保留图像的大部分重要信息,从而保证视觉质量。
在这里插入图片描述

②diff=I-I2; figure; imshow(diff,[]);
在这里插入图片描述

这将显示一幅图像,其中的像素值表示原始图像和压缩后图像之间的差异。差异越大,说明压缩造成的失真越大。

在这里插入图片描述

非零元素个数与图像差异关系:
非零元素数量增加,更多低频信息被保留,压缩效果减少,图像质量提高,MSE值下降。
非零元素数量减少,更多高频信息被丢弃,压缩效果增强,但图像质量下降,如图所示压缩后的照片模糊许多,MSE值上升。
变换后系数的重要性:
低频系数:图像的主要信息(如亮度、形状等)通常集中在低频系数中,这些系数对于图像的质量至关重要。
高频系数:细节信息(如边缘、噪声等)通常集中在高频系数中,这些系数对人眼的感知影响较小,因此可以舍弃。
综上所述:保留较多的低频系数会保证较好的图像质量,减少高频系数则有助于压缩图像的文件大小,但图像会失去一些细节。

④可以看出,第二次比第一次的图像质量要差很多,因此验证可得③的结论是正确的。
在这里插入图片描述
在这里插入图片描述

6、原图:
在这里插入图片描述

变换后的图像:
在这里插入图片描述

7、实验内容:编写程序实现图像的水平垂直和中心对称
设计思想:
图像可以通过二维矩阵表示,每个元素通常表示一个像素点的颜色值。对称操作实际上是对矩阵进行某些特定的转换,通过修改矩阵的行列索引来实现。
水平对称:将矩阵的每一列逆序。
垂直对称:将矩阵的每一行逆序。
中心对称:将整个矩阵在行和列上同时进行逆序。
输出结果:
在这里插入图片描述

三、使用环境

Matlab、Dev-C++、openCV

四、小结

1、第一题在求相关系数时报错
分析:在使用 corr2 函数计算两个图像的相关系数时,它要求两个图像的尺寸必须相同。
2、在进行图像处理操作时,结果图像的处理效果与预期不符。
原因:在不同的图像处理步骤中,图像的类型(如 BGR 转灰度图)没有正确转换,导致处理结果不正确。
3、 实验体会和收获
通过这次实验,我深刻认识到理论知识的重要性,尤其是在图像处理领域。通过实际编程实践,我能更好地理解和运用图像处理算法,尤其是在 OpenCV 等工具库的使用上得到了更深入的理解。在实验中遇到的问题让我对如何快速定位和解决问题有了更高的敏感性。从查阅文档、调试程序到在网上寻找解决方案,每一步都增加了我的技术储备和应对突发问题的能力。通过本次实验,我不仅提升了自己的编程技能,还增强了系统调试和问题解决的能力。将来的实验中,我会更加注重理论学习与实践操作的结合,并不断积累解决问题的经验。

源代码附件

1、
picture1 = imread(‘C:\Users\吴倩\Pictures\Saved Pictures\图片一.png’);
picture2 = imread(‘C:\Users\吴倩\Pictures\Saved Pictures\图片二.png’);

if size(picture1, 3) == 3
picture1 = rgb2gray(picture1);
end
if size(picture2, 3) == 3
picture2 = rgb2gray(picture2);
end

% 图像的大小
size1 = size(picture1);
size2 = size(picture2);
disp(‘图像一的大小:’);
disp(size1);
disp(‘图像二的大小:’);
disp(size2);

% 灰度平均值
mean1 = mean(picture1(😃);
mean2 = mean(picture2(😃);
disp(‘图像一的灰度平均值为:’);
disp(mean1);
disp(‘图像二的灰度平均值为:’);
disp(mean2);

% 协方差矩阵
cov1 = cov(double(picture1(😃));
cov2 = cov(double(picture2(😃));
disp(‘图像一的协方差矩阵:’);
disp(cov1);
disp(‘图像二的协方差矩阵:’);
disp(cov2);

% 灰度标准差
sdg1 = std(double(picture1(😃));
sdg2 = std(double(picture2(😃));

disp(‘图像一的灰度标准差:’);
disp(sdg1);
disp(‘图像二的灰度标准差:’);
disp(sdg2);

% 相关系数
correlation = corr2(picture1, picture2);
disp(‘两张图片的相关系数为:’);
disp(correlation);

2、
I = imread(‘C:\Users\吴倩\Pictures\壁纸\图片一.jpg’);
num = 10;
[m, n, p] = size(I);
total = zeros(m, n, p);

for k = 1:num
J = imnoise(I, ‘gaussian’, 0, 0.01);
total = total + double(J);
end

aver = uint8(total / num);

subplot(2, 2, 1), imshow(I), title(‘原始图像’);
subplot(2, 2, 2), imshow(J), title(‘带噪图像’);
subplot(2, 2, 3), imshow(aver), title(‘加法去噪结果’);

3、
f = zeros(60, 60);
f(15:46, 13:47) = 1;
figure(1)
imshow(f);
F=fft2(f,256,256);
F2=fftshift(F);
figure(2)
imshow(F2, [-1 5]);
colormap(jet);

4、
RGB = imread(‘C:\Users\吴倩\Desktop\美丽女人照片\IMG_7091.JPG’);
I = rgb2gray(RGB);
figure(1);
imshow(I);
J = dct2(I);
figure(2);
imshow(log(abs(J)),[]), colormap(jet(64)), colorbar

5、
I=imread(‘C:\Users\吴倩\Pictures\壁纸\图片三.jpg’);
I = rgb2gray(I);
I=im2double(I);
T=dctmtx(8);
B=blkproc(I,[8 8],‘P1xP2’,T,T’);
mask=[ 1 1 1 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];
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);

6、
#include <opencv2/opencv.hpp>
#include
#include

cv::Mat applyDCT(const cv::Mat& src) {
cv::Mat dct;
cv::dct(src, dct);
return dct;
}

cv::Mat applyIDCT(const cv::Mat& dct) {
cv::Mat idct;
cv::idct(dct, idct);
return idct;
}

cv::Mat applyMask(const cv::Mat& dct, const cv::Mat& mask) {
cv::Mat maskedDct = dct.clone();
for (int i = 0; i < dct.rows; ++i) {
for (int j = 0; j < dct.cols; ++j) {
if (mask.at(i, j) == 0) {
maskedDct.at(i, j) = 0;
}
}
}
return maskedDct;
}

int main() {
cv::Mat image = cv::imread(“C:\Users\吴倩\Pictures\壁纸\图片三.jpg”, cv::IMREAD_GRAYSCALE);
if (image.empty()) {
std::cerr << “Error!” << std::endl;
return -1;
}
image.convertTo(image, CV_32F, 1.0 / 255.0);
int blockSize = 8;
cv::Mat dctImage = image.clone();
for (int i = 0; i < image.rows; i += blockSize) {
for (int j = 0; j < image.cols; j += blockSize) {
cv::Rect roi(j, i, blockSize, blockSize);
cv::Mat block = image(roi);
cv::Mat dctBlock = applyDCT(block);
dctBlock.copyTo(dctImage(roi));
}
}
cv::Mat mask = cv::Mat::ones(blockSize, blockSize, CV_32F);
int nonZeroCount = 4; //
for (int i = nonZeroCount; i < blockSize; ++i) {
for (int j = nonZeroCount; j < blockSize; ++j) {
mask.at(i, j) = 0;
}
}

cv::Mat compressedImage = image.clone();
for (int i = 0; i < image.rows; i += blockSize) {
    for (int j = 0; j < image.cols; j += blockSize) {
        cv::Rect roi(j, i, blockSize, blockSize);
        cv::Mat block = dctImage(roi);
        cv::Mat maskedBlock = applyMask(block, mask);
        maskedBlock.copyTo(compressedImage(roi));
    }
}

cv::Mat reconstructedImage = compressedImage.clone();
for (int i = 0; i < compressedImage.rows; i += blockSize) {
    for (int j = 0; j < compressedImage.cols; j += blockSize) {
        cv::Rect roi(j, i, blockSize, blockSize);
        cv::Mat block = compressedImage(roi);
        cv::Mat idctBlock = applyIDCT(block);
        idctBlock.copyTo(reconstructedImage(roi));
    }
}
cv::imshow("原图", image);
cv::imshow("重建图像", reconstructedImage);
cv::waitKey(0);
cv::Mat diffImage;
cv::absdiff(image, reconstructedImage, diffImage);
cv::imshow("Difference Image", diffImage);
cv::waitKey(0);
std::cout << "Non-zero elements in mask: " << nonZeroCount << std::endl;

return 0;

}

7、
picture = imread(‘C:\Users\吴倩\Pictures\Saved Pictures\图片一.png’);
%水平对称
hor = picture;
hor = hor(:, end👎1, 😃;
%垂直对称
ver = picture;
ver = ver(end👎1, :, 😃;
% 中心对称
cen = picture;
cen = cen(end👎1, end👎1, 😃;
figure;
subplot(2,2,1);
imshow(picture);
title(‘原图’);
subplot(2,2,2);
imshow(hor);
title(‘水平对称’);
subplot(2,2,3);
imshow(ver);
title(‘垂直对称’);
subplot(2,2,4);
imshow(cen);
title(‘中心对称’);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2373871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

并发笔记-锁(一)

文章目录 1. 基本问题与锁的概念 (The Basic Idea)2. 锁的API与Pthreads (Lock API and Pthreads)3. 构建锁的挑战与评估标准 (Building A Lock & Evaluating Locks)4. 早期/简单的锁实现尝试及其问题 (Early/Simple Attempts)4.1 控制中断 (Controlling Interrupts)4.2 仅…

【Bootstrap V4系列】学习入门教程之 组件-媒体对象(Media object)

Bootstrap V4系列 学习入门教程之 组件-媒体对象&#xff08;Media object&#xff09; 媒体对象&#xff08;Media object&#xff09;一、Example二、Nesting 嵌套三、Alignment 对齐四、Order 顺序五、Media list 媒体列表 媒体对象&#xff08;Media object&#xff09; B…

2025数字中国创新大赛-数字安全赛道数据安全产业积分争夺赛决赛Writeup

文章目录 综合场景赛-模型环境安全-3综合场景赛-数据识别与审计-1综合场景赛-数据识别与审计-2综合场景赛-数据识别与审计-3 有需要题目附件的师傅&#xff0c;可以联系我发送 综合场景赛-模型环境安全-3 upload文件嵌套了多个png图片字节数据&#xff0c;使用foremost直接分离…

无法更新Google Chrome的解决问题

解决问题&#xff1a;原文链接&#xff1a;【百分百成功】Window 10 Google Chrome无法启动更新检查&#xff08;错误代码为1&#xff1a;0x80004005&#xff09; google谷歌chrome浏览器无法更新Chrome无法更新至最新版本&#xff1f; 下载了 就是更新Google Chrome了

数字孪生市场格局生变:中国2025年规模214亿,工业制造领域占比超40%

一、技术深度解析&#xff1a;数字孪生的核心技术栈与演进 1. 从镜像到自治&#xff1a;数字孪生技术架构跃迁 三维重建突破&#xff1a;LiDAR点云精度达2cm&#xff0c;无人机测深刷新频率5Hz&#xff0c;支撑杭州城市大脑内涝预警模型提前6小时预测。AI算法融合&#xff1a…

全球首款无限时长电影生成模型SkyReels-V2本地部署教程:视频时长无限制!

一、简介 SkyReels-V2 模型集成了多模态大语言模型&#xff08;MLLM&#xff09;、多阶段预训练、强化学习以及创新的扩散强迫&#xff08;Diffusion-forcing&#xff09;框架&#xff0c;实现了在提示词遵循、视觉质量、运动动态以及视频时长等方面的全面突破。通过扩散强迫框…

颠覆性技术革命:CAD DWG图形瓦片化实战指南

摘要 CAD DWG图形瓦片化技术通过金字塔模型构建多分辨率地图体系&#xff0c;实现海量工程图纸的Web高效可视化。本文系统解析栅格瓦片与矢量瓦片的技术原理&#xff0c;详细对比两者在生成效率、样式自由度和客户端性能等维度的差异&#xff0c;并结合工程建设、工业设计和智…

不换设备秒通信,PROFINET转Ethercat网关混合生产线集成配置详解

在汽车制造中&#xff0c;连接Profinet控制的PLC&#xff08;如西门子S7&#xff09;与EtherCAT伺服驱动器&#xff08;如倍福AX5000&#xff09;&#xff0c;实现运动控制同步。 在汽车制造的混合生产线集成中&#xff0c;实现西门子S7 PLC与倍福AX5000 EtherCAT伺服驱动器的…

c++STL-string的使用

这里写自定义目录标题 string的使用string写成类模板的原因string的版本举例构造、析构函数和赋值重载构造函数和析构函数operator Iterators迭代器begin和endrbegin和rendcbegin和cend&#xff0c;crbegin和crend&#xff08;c11&#xff09; capacity容量有关函数不同编译器下…

UNet网络 图像分割模型学习

UNet 由Ronneberger等人于2015年提出&#xff0c;专门针对医学图像分割任务&#xff0c;解决了早期卷积网络在小样本数据下的效率问题和细节丢失难题。 一 核心创新 1.1对称编码器-解码器结构 实现上下文信息与高分辨率细节的双向融合 如图所示&#xff1a;编码器进行了4步&…

使用 SHAP 进行特征交互检测:揭示变量之间的复杂依赖关系

我们将探讨如何使用 SHAP&#xff08;SHapley 加法解释&#xff09;来检测和可视化机器学习模型中的特征交互。了解特征组合如何影响模型预测对于构建更透明、更准确的模型至关重要。SHAP 有助于揭示这些复杂的依赖关系&#xff0c;并使从业者能够以更有意义的方式解释模型决策…

Python-MCPInspector调试

Python-MCPInspector调试 使用FastMCP开发MCPServer&#xff0c;熟悉【McpServer编码过程】【MCPInspector调试方法】-> 可以这样理解&#xff1a;只编写一个McpServer&#xff0c;然后使用MCPInspector作为McpClient进行McpServer的调试 1-核心知识点 1-熟悉【McpServer编…

Java设计模式-策略模式(行为型)

策略模式详解 一、策略模式概述 1.1 基本概念 策略模式是一种行为型设计模式&#xff0c;它主要用于处理算法的不同变体。其核心思想是将算法的定义与使用分离开来&#xff0c;把一系列具体的算法封装成独立的策略类&#xff0c;这些策略类实现相同的策略接口。客户端可以在…

html body 设置heigth 100%,body内元素设置margin-top出滚动条(margin 重叠问题)

今天在用移动端的时候发现个问题&#xff0c;html,body 设置 height&#xff1a;100% 会出现纵向滚动条 <!DOCTYPE html> <html> <head> <title>html5</title> <style> html, body {height: 100%; } * {margin: 0;padding: 0; } </sty…

C语言模糊不清的知识

1、malloc、calloc、realloc的区别和用法 malloc实在堆上申请一段连续指定大小的内存区域&#xff0c;并以void*进行返回&#xff0c;不会初始化内存。calloc与malloc作用一致&#xff0c;只是calloc会初始化内存&#xff0c;自动将内存清零。realloc用于重新分配之前通过mallo…

如何配置光猫+路由器实现外网IP访问内部网络?

文章目录 前言一、网络拓扑理解二、准备工作三、光猫配置3.1 光猫工作模式3.2 光猫端口转发配置&#xff08;路由模式时&#xff09; 四、路由器配置4.1 路由器WAN口配置4.2 端口转发配置4.3 动态DNS配置&#xff08;可选&#xff09; 五、防火墙设置六、测试配置七、安全注意事…

springboot3+vue3融合项目实战-大事件文章管理系统获取用户详细信息-ThreadLocal优化

一句话本质 为每个线程创建独立的变量副本&#xff0c;实现多线程环境下数据的安全隔离&#xff08;线程操作自己的副本&#xff0c;互不影响&#xff09;。 关键解读&#xff1a; 核心机制 • 同一个 ThreadLocal 对象&#xff08;如示意图中的红色区域 tl&#xff09;被多个线…

【高数上册笔记篇02】:数列与函数极限

【参考资料】 同济大学《高等数学》教材樊顺厚老师B站《高等数学精讲》系列课程 &#xff08;注&#xff1a;本笔记为个人数学复习资料&#xff0c;旨在通过系统化整理替代厚重教材&#xff0c;便于随时查阅与巩固知识要点&#xff09; 仅用于个人数学复习&#xff0c;因为课…

c++STL-string的模拟实现

cSTL-string的模拟实现 string的模拟实现string的模拟线性表的实现构造函数析构函数获取长度&#xff08;size&#xff09;和获取容量&#xff08;capacity&#xff09;访问 [] 和c_str迭代器&#xff08;iterator&#xff09;交换swap拷贝构造函数赋值重载&#xff08;&#x…

YashanDB(崖山数据库)V23.4 LTS 正式发布

2024年回顾 2024年11月我们受邀去深圳参与了2024国产数据库创新生态大会。在大会上崖山官方发布了23.3。这个也是和Oracle一样采用的事编年体命名。 那次大会官方希望我们这些在一直从事在一线的KOL帮助产品提一些改进建议。对于这样的想法&#xff0c;我们都是非常乐于合作…