课程设计报告书
课程名称: 数字图像处理
题 目: 数字图像处理的傅里叶变换
学生姓名:
专 业: 计算机科学与技术
班 别: 计科本101班
学 号:
指导老师:
日 期: 2013 年 06 月 20 日
数字图像处理的傅里叶变换
1.课程设计目的和意义
(1)了解图像变换的意义和手段
(2)熟悉傅里叶变换的基本性质
(3)热练掌握FFT的方法反应用
(4)通过本实验掌握利用MATLAB编程实现数字图像的傅里叶变换
通过本次课程设计,掌握如何学习一门语言,如何进行资料查阅搜集,如何自己解决问题等方法,养成良好的学习习惯。扩展理论知识,培养综合设计能力。
2.课程设计内容
(1)熟悉并掌握傅立叶变换
(2)了解傅立叶变换在图像处理中的应用
(3)通过实验了解二维频谱的分布特点
(4)用MATLAB实现傅立叶变换仿真
3.课程设计背景与基本原理
傅里叶变换是可分离和正交变换中的一个特例,对图像的傅里叶变换将图像从图像空间变换到频率空间,从而可利用傅里叶频谱特性进行图像处理。从20世纪60年代傅里叶变换的快速算法提出来以后,傅里叶变换在信号处理和图像处理中都得到了广泛的使用。
3.1课程设计背景
数字图像处理(Digital Image Processing)又称为计算机图像处理,它是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。是通过计算机对图像进行去除噪声、增强、复原、分割、提取特征等处理的方法和技术。
3.2 傅里叶变换
(1)应用傅里叶变换进行数字图像处理
数字图像处理(digital image processing)是用计算机对图像信息进行处理的一门技术,使利用计算机对图像进行各种处理的技术和方法。
20世纪20年代,图像处理首次得到应用。20世纪60年代中期,随电子计算机的发展得到普遍应用。60年代末,图像处理技术不断完善,逐渐成为一个新兴的学科。利用数字图像处理主要是为了修改图形,改善图像质量,或是从图像中提起有效信息,还有利用数字图像处理可以对图像进行体积压缩,便于传输和保存。数字图像处理主要研究以下内容:傅立叶变换、小波变换等各种图像变换;对图像进行编码和压缩;采用各种方法对图像进行复原和增强;对图像进行分割、描述和识别等。随着技术的发展,数字图像处理主要应用于通讯技术、宇宙探索遥感技术和生物工程等领域。
傅里叶变换在数字图像处理中广泛用于频谱分析,傅里叶变换是线性系统分析的一个有力工具,它使我们能够定量地分析诸如数字化系统,采样点,电子放大器,卷积滤波器,噪声,显示点等地作用(效应)。傅里叶变换(FT)是数字图像处理技术的基础,其通过在时空域和频率域来回切换图像,对图像的信息特征进行提取和分析,简化了计算工作量,被喻为描述图像信息的第二种语言,广泛应用于图像变换,图像编码与压缩,图像分割,图像重建等。因此,对涉及数字图像处理的工作者,深入研究和掌握傅里叶变换及其扩展形式的特性,是很有价值得。
(2)关于傅里叶(Fourier)变换
在信号处理中,傅里叶变换可以将时域信号变到频域中进行处理,因此傅里叶变换在信号处理中有着特殊重要的地位。
傅里叶变换能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。在不同的研究领域,傅里叶变换具有多种不同的变体形式,如连续傅里叶变换和离散傅里叶变换。傅里叶变换属于谐波分析。傅里叶变换的逆变换容易求出,而且形式与正变换非常类似;正弦基函数是微分运算的本征函数,从而使得线性微分方程的求解可以转化为常系数的代数方程的求解.在线性时不变的物理系统内,频率是个不变的性质,从而系统对于复杂激励的响应可以通过组合其对不同频率正弦信号的响应来获取; 卷积定理指出:傅里叶变换可以化复杂的卷积运算为简单的乘积运算,从而提供了计算卷积的一种简单手段; 离散形式的傅里叶变换可以利用数字计算机快速的算出(其算法称为快速傅里叶变换算法(FFT))。
3.3 离散余弦变换
离散余弦变换(discrete cosine transform,DCT)是一种可分离和正交变换并且是对称的。它与傅里叶变换也有密切的联系,近年得到了广泛应用,特别是在图像压缩领域。
1-D离散余弦变换和其反变换由以下两式定义:
u=0,1,...,N-1
x=0,1,...,N-1
其中a(u)为归一化加权系数,由下式定义:
2-Dd DCT对由下面两式定义:
u,v=0,1,...,N-1
x,y=0,1,...,N-1
4.设计步骤
(1)打开计算机,安装和启动MATLAB程序;在“Current Directory” 中选择待处理图像文件所在文件夹。
(2)利用MatLab菜单栏中单击“File”→“New”→“M-File”,在弹出的Editor - Untitled窗口编辑区中输入程序代码。
(3)输入完成后单击Editor - Untitled菜单栏中的“Debug”→“Save and Run”运行程序。对该程序进行编译,检查错误并纠正,运行并显示结果,比较差异。
5、程序设计
方法一:直接将彩色图像进行傅里叶变换,再求离散傅里叶频谱图程序如下:
i=imread('maomi.bmp');
figure(1)
imshow(i);
colorbar; %显示图像的颜色条
title('原彩色图像') %图像命名
X1=img(:,:,1);
X2=img(:,:,2);
X3=img(:,:,3);
Y1=fft2(X1); %傅里叶变换
Y2=fft2(X2);
Y3=fft2(X3);
Y11=real(ifft2(Y1)); %傅里叶反变换
Y21=real(ifft2(Y2));
Y31=real(ifft2(Y3));
Y(:,:,1)=Y11;
Y(:,:,2)=Y21;
Y(:,:,3)=Y31;
YY=uint8(Y);
figure(2);
imshow(YY,[ ]);
colorbar; %显示图像的颜色条
title('经过二维快速傅里叶变换再逆变换后的图像') %图像命名
i=i(:,:,3);
ffti=fft2(i);
sffti=fftshift(ffti); %求离散傅里叶频谱
%对原始图像进行二维离散傅里叶变换,并将其坐标原点移到频谱图中央位置
RRfdp1=real(sffti); %取傅立叶变换的实部
IIfdp1=imag(sffti); %取傅立叶变换的虚部
a=sqrt(RRfdp1.^2+IIfdp1.^2); %计算频谱幅值
a=(a-min(min(a)))/(max(max(a))-min(min(a)))*225; %归一化
figure(5) %设定窗口
imshow(real(a)); %显示离散傅里叶频谱图像
colorbar; %显示图像的颜色条
title('原彩色图像的离散傅里叶频谱') %图像命名
方法二:将彩色图像转换为灰度图像在进行傅里叶变换,再求原彩色图像的离散傅里叶频谱图程序如下:
i=imread('maomi.bmp'); %读入原图像文件
figure(1); %设定窗口
imshow(i); %显示原图像
colorbar; %显示图像的颜色条
title('原彩色图像') %图像命名
I=rgb2gray(i);
figure(2); %设定窗口
imshow(I);
colorbar; %显示图像的颜色条
title('原彩色图像转换为灰度图像') %图像命名
j=fft2(I); %二维离散傅里叶变换
k=fftshift(j); %直流分量移到频谱中心
l=log(abs(k)); %数字图像的对数变换
figure(3); %设定窗口
imshow(l,[]); %显示过二维快速傅里叶变换后的图像
colorbar; %显示图像的颜色条
title('经过二维快速傅里叶变换后的图像') %图像命名
n=ifft2(j)/255; %逆二维快速傅里叶变换
figure(4); %设定窗口
imshow(n); %显示经过二维快速傅里叶逆变换后的图像
colorbar; %显示图像的颜色条
title('经过二维快速傅里叶逆变换后的灰度图像') %图像命名
i=i(:,:,3);
ffti=fft2(i);
sffti=fftshift(ffti); %求离散傅里叶频谱
%对原始图像进行二维离散傅里叶变换,并将其坐标原点移到频谱图中央位置
RRfdp1=real(sffti); %取傅立叶变换的实部
IIfdp1=imag(sffti); %取傅立叶变换的虚部
a=sqrt(RRfdp1.^2+IIfdp1.^2); %计算频谱幅值
a=(a-min(min(a)))/(max(max(a))-min(min(a)))*225; %归一化
figure(5) %设定窗口
imshow(real(a)); %显示离散傅里叶频谱图像
colorbar; %显示图像的颜色条
title('原彩色图像的离散傅里叶频谱') %图像命名
6.运行结果
对源代码检查无误运行后,通过这些图可以看出一幅图片经过不同类型的傅里叶变换后,能够达到不同的处理效果。
6.1方法一运行结果如下:
图1-1 原彩色图像
图1-2 经过二维快速傅里叶变换再逆变换后的图像
图1-3 原彩色图像的离散傅里叶频谱图
6.2方法二运行结果如下:
图2-1 原彩色图像
图2-2 原彩色图像的灰度图
图2-3 经过二维傅里叶变换后的图像
图2-4 经过二维快速傅里叶逆变换后的灰度图像
图2-5 原彩色图像的离散傅里叶频谱图
{
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsGrayTitle = "灰度图";
const char *pstrWindowsHistTitle = "直方图";
const char *pstrWindowsGrayEqualizeTitle = "灰度图-均衡化后";
const char *pstrWindowsHistEqualizeTitle = "直方图-均衡化后";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("小白.jpeg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
IplImage *pGrayEqualizeImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
// 灰度图
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
// 直方图图像数据
int nHistImageWidth = 255;
int nHistImageHeight = 150;
int nScale = 2;
// 灰度直方图及直方图图像
CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage);
IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram);
// 均衡化
cvEqualizeHist(pGrayImage, pGrayEqualizeImage);
// 均衡化后的灰度直方图及直方图图像
CvHistogram *pcvHistogramEqualize = CreateGrayImageHist(&pGrayEqualizeImage);
IplImage *pHistEqualizeImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogramEqualize);
// 显示
cvNamedWindow(pstrWindowsGrayTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsHistTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsGrayEqualizeTitle,
CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsHistEqualizeTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsGrayTitle, pGrayImage);
cvShowImage(pstrWindowsHistTitle, pHistImage);
13
{
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsGrayTitle = "灰度图";
const char *pstrWindowsHistTitle = "直方图";
const char *pstrWindowsGrayEqualizeTitle = "灰度图-均衡化后";
const char *pstrWindowsHistEqualizeTitle = "直方图-均衡化后";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("小白.jpeg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
IplImage *pGrayEqualizeImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
// 灰度图
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
// 直方图图像数据
int nHistImageWidth = 255;
int nHistImageHeight = 150;
int nScale = 2;
// 灰度直方图及直方图图像
CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage);
IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram);
// 均衡化
cvEqualizeHist(pGrayImage, pGrayEqualizeImage);
// 均衡化后的灰度直方图及直方图图像
CvHistogram *pcvHistogramEqualize = CreateGrayImageHist(&pGrayEqualizeImage);
IplImage *pHistEqualizeImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogramEqualize);
// 显示
cvNamedWindow(pstrWindowsGrayTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsHistTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsGrayEqualizeTitle,
CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsHistEqualizeTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsGrayTitle, pGrayImage);
cvShowImage(pstrWindowsHistTitle, pHistImage);
13
本课程设计的评价由三部分组成,包括程序演示(50%),课程设计报告(30%),回答教师提问(20%)。
1、 程序演示:
(1) 优
(2) 良
(3) 中
(4) 及格
(5) 不及格
2、 课程设计报告:
(1) 优
(2) 良
(3) 中
(4) 及格
(5) 不及格
3、 回答教师提问:
(1) 优
(2) 良
(3) 中
(4) 及格
(5) 不及格 功能完善,全部测试正确,并且能够对局部进行完善 功能完善,但测试欠缺 功能基本完善,但程序尚有部分错误 实现了主要功能基本完善,有部分功能尚未实现。 功能不完善,且程序错误较多,无法运行 包括设计内容,设计思想,已经完成的任务及达到的目标, 设计思路清晰、书写条理清楚,源程序结构合理、清晰,注 释说明完整,有对本次课程设计的心得体会。 包括设计内容,设计思想,已经完成的任务及达到的目标, 设计思路基本清晰、书写条理基本清楚,源程序结构合理、 清晰,注释说明基本完整,有对本次课程设计的心得体会。 课程设计报告内容基本完整,思路较清晰,书写基本清楚, 源程序结构尚可,有注释说明但不完整 课程设计报告内容基本完整,思路较差,书写尚清楚。 课程设计报告内容不完整,书写没有条理。 能回答教师提出的所有问题,并完全正确,思路清晰 基本能回答教师提出的所有问题,有些小错误 基本能回答教师提出的问题,少数问题回答错误或不清楚 能回答教师提出的问题,但较多问题回答错误或不能回答 基本不能回答教师提出的问题
2
一、实验目的
掌握数字图像处理的基本原理。
二、实验总体设计(流程图)
写出数字图像处理各功能代码
↓
设计程序整合各功能
三、实验详细设计(各个功能模块设计及实现主要函数)
程序如下,包括图像缩放
图象灰度化
图像的Canny边缘检测
图象二值化
图象自适应二值化
灰度直方图
彩色直方图
灰度直方图均衡化
四、实验结果与分析
各功能成功实现满足图像处理使用要求。
五、实验心得
通过这次实验,进一步巩固了数字图像处理系统中的基本原理与方法, 并熟悉了opencv的功能与应用,进一步提高了编程实践能力。 学习很有成果
1
六、主要代码
#include <opencv2/opencv.hpp>
#include <highgui.h>
#include <cv.h>
#include <cvaux.h>
#include <math.h>
#include <opencv2/legacy/compat.hpp>
#include <iostream>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
//图象缩放
int main()
{
const char *pstrImageName = "小白.jpeg";
//const char *pstrWindowsTitle = "MY TEST1!";
const char *pstrSaveImageName = "小白缩放图.jpeg";
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsDstTitle = "缩放图";
double fScale = 0.785; //缩放倍数
CvSize czSize; //目标图象尺寸
//从文件中读取图像
IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);
IplImage *pDstImage = NULL;
//计算图象大小
czSize.width = int(pSrcImage->width * fScale);
czSize.height = int(pSrcImage->height * fScale);
//创建图象并缩放
pDstImage = cvCreateImage(czSize,pSrcImage->depth,pSrcImage->nChannels); cvResize(pSrcImage, pDstImage, CV_INTER_AREA);
//创建窗口
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsDstTitle, CV_WINDOW_AUTOSIZE);
2
//在指定窗口中显示图像
cvShowImage(pstrWindowsSrcTitle, pSrcImage);
cvShowImage(pstrWindowsDstTitle, pDstImage);
//等待按键事件
cvWaitKey();
//保存图象
cvSaveImage(pstrSaveImageName, pDstImage);
//释放图象
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsDstTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&pDstImage);
return 0;
}
//图象灰度化
/*
int main(int argc, char* argv[])
{
const char* imagename = "小白.jpeg";
const char* imageTitle = "原图小白";
const char* imagename1 = "灰度小白.jpeg";
const char* imageTitle1 = "灰度小白";
//读取图象
IplImage * img = cvLoadImage(imagename);
if (!img)
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
if (!img->imageData) // 检查是否正确载入图像
return -1;
cvNamedWindow(imageTitle, CV_WINDOW_AUTOSIZE); //创建窗口 cvShowImage(imageTitle,img); //指定窗口显示图像
//创建目标图像
3
IplImage* img1 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1); cvCvtColor(img, img1, CV_BGR2GRAY); //灰度化
cvNamedWindow(imageTitle1, CV_WINDOW_AUTOSIZE); //创建显示目标的窗口
cvShowImage(imageTitle1, img1); //显示灰度图像
cvWaitKey(); //等待按键事件
cvSaveImage(imagename1, img1); //保存图象
//释放图象
cvReleaseImage(&img);
cvReleaseImage(&img1);
cvDestroyAllWindows();
return 0;
}
*/
//图像的Canny边缘检测
/*
IplImage *g_pSrcImage, *g_pCannyImg; //定义图象指针
const char *pstrWindowsCannyTitle = "边缘检测图";
//cvCreateTrackbar的回调函数
void on_trackbar(int threshold)
{
//canny边缘检测
cvCanny(g_pSrcImage, g_pCannyImg, threshold, threshold * 3, 3);
cvShowImage(pstrWindowsCannyTitle, g_pCannyImg); //显示图象 }
int main()
{
const char *pstrImageName = "小白灰度图.jpeg";
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsToolBar = "Threshold";
const char *pstrImageCannyName = "小白边缘检测图.jpeg";
//从文件中载入图像的灰度图CV_LOAD_IMAGE_GRAYSCALE - 灰度图 g_pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_GRAYSCALE);
g_pCannyImg = cvCreateImage(cvGetSize(g_pSrcImage), IPL_DEPTH_8U, 1);
//创建窗口
4
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsCannyTitle, CV_WINDOW_AUTOSIZE);
//创建滑动条
int nThresholdEdge = 1;
cvCreateTrackbar(pstrWindowsToolBar, pstrWindowsCannyTitle, &nThresholdEdge, 100, on_trackbar);
//在指定窗口中显示图像
cvShowImage(pstrWindowsSrcTitle, g_pSrcImage);
on_trackbar(1);
//等待按键事件
cvWaitKey();
cvSaveImage(pstrImageCannyName, g_pCannyImg);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsCannyTitle);
cvReleaseImage(&g_pSrcImage);
cvReleaseImage(&g_pCannyImg);
return 0;
}
*/
//图象二值化
/*
IplImage *g_pGrayImage = NULL;
IplImage *g_pBinaryImage = NULL;
const char *pstrWindowsBinaryTitle = "二值图";
void on_trackbar(int pos)
{
// 转为二值图
cvThreshold(g_pGrayImage, g_pBinaryImage,
CV_THRESH_BINARY);
// 显示二值图
cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage);
}
int main(int argc, char** argv)
{
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsToolBarName = "二值图阈值";
5 pos, 255,
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("小白.jpeg", CV_LOAD_IMAGE_UNCHANGED);
// 转为灰度图
g_pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1); cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);
// 创建二值图
g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U,
1);
// 显示原图
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvShowImage(pstrWindowsSrcTitle, pSrcImage);
// 创建二值图窗口
cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
// 滑动条
int nThreshold = 0;
cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);
on_trackbar(1);
cvWaitKey(0);
cvSaveImage("小白二值图.jpeg", g_pBinaryImage);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsBinaryTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&g_pGrayImage);
cvReleaseImage(&g_pBinaryImage);
return 0;
}
*/
//图象自适应二值化
/*
int main(int argc, char** argv)
{
IplImage *g_pBinaryImage;
const char *pstrWindowsBinaryTitle = "二值图";
6
const char *pstrWindowsSrcTitle = "灰度图";
const char *pstrImageSrcName = "小白灰度图.jpeg";
const char *pstrImageBinaryName = "小白自适应二值化.jpeg";
if (argc != 7)
{
return -1;
}
int threshold_type = atoi(argv[2]) ? CV_THRESH_BINARY : CV_THRESH_BINARY_INV;
int adaptive_method = atoi(argv[3]) ? CV_ADAPTIVE_THRESH_MEAN_C : CV_ADAPTIVE_THRESH_GAUSSIAN_C;
int block_size = atoi(argv[4]);
double offset = (double)atof(argv[5]);
// 读取灰度图
IplImage *g_pGrayImage = cvLoadImage(pstrImageSrcName, CV_LOAD_IMAGE_GRAYSCALE);
// 创建二值图
g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U,
1);
cvAdaptiveThreshold(g_pGrayImage, g_pBinaryImage, 255, adaptive_method, threshold_type, block_size, offset);
// 显示原图
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvShowImage(pstrWindowsSrcTitle, g_pGrayImage);
// 创建二值图窗口
cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
cvWaitKey(0);
cvSaveImage(pstrImageBinaryName, g_pBinaryImage);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsBinaryTitle);
cvReleaseImage(&g_pGrayImage);
cvReleaseImage(&g_pBinaryImage);
return 0;
}
*/
//灰度直方图
/*
7
void FillWhite(IplImage *pImage)
{
cvRectangle(pImage, cvPoint(0, 0), cvPoint(pImage->width, pImage->height), CV_RGB(255, 255, 255), CV_FILLED);
}
// 创建灰度图像的直方图
CvHistogram* CreateGrayImageHist(IplImage **ppImage)
{
int nHistSize = 256;
float fRange[] = { 0, 255 }; //灰度级的范围
float *pfRanges[] = { fRange };
CvHistogram *pcvHistogram = cvCreateHist(1, &nHistSize, CV_HIST_ARRAY, pfRanges);
cvCalcHist(ppImage, pcvHistogram);
return pcvHistogram;
}
// 根据直方图创建直方图图像
IplImage* CreateHisogramImage(int nImageWidth, int nScale, int nImageHeight, CvHistogram *pcvHistogram)
{
IplImage *pHistImage = cvCreateImage(cvSize(nImageWidth * nScale, nImageHeight), IPL_DEPTH_8U, 1);
FillWhite(pHistImage);
//统计直方图中的最大直方块
float fMaxHistValue = 0;
cvGetMinMaxHistValue(pcvHistogram, NULL, &fMaxHistValue, NULL, NULL);
//分别将每个直方块的值绘制到图中
int i;
for (i = 0; i < nImageWidth; i++)
{
float fHistValue = cvQueryHistValue_1D(pcvHistogram, i); //像素为i的直方块大小
int nRealHeight = cvRound((fHistValue / fMaxHistValue) * nImageHeight); //要绘制的高度
cvRectangle(pHistImage,
cvPoint(i * nScale, nImageHeight - 1),
cvPoint((i + 1) * nScale - 1, nImageHeight - nRealHeight),
cvScalar(i, 0, 0, 0),
CV_FILLED
);
}
8
return pHistImage;
}
int main(int argc, char** argv)
{
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsGrayTitle = "灰度图";
const char *pstrWindowsHistTitle = "直方图";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("小白.jpeg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
// 灰度图
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
// 灰度直方图
CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage);
// 创建直方图图像
int nHistImageWidth = 255;
int nHistImageHeight = 150; //直方图图像高度
int nScale = 2;
IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram);
// 显示
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsGrayTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsHistTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsSrcTitle, pSrcImage);
cvShowImage(pstrWindowsGrayTitle, pGrayImage);
cvShowImage(pstrWindowsHistTitle, pHistImage);
cvWaitKey(0);
cvReleaseHist(&pcvHistogram);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsGrayTitle);
cvDestroyWindow(pstrWindowsHistTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&pGrayImage);
9
cvReleaseImage(&pHistImage);
return 0;
}
*/
//彩色直方图
/*
int main(int argc, char** argv)
{
IplImage * src = cvLoadImage("小新.jpg");
IplImage* hsv = cvCreateImage(cvGetSize(src), 8, 3);
IplImage* h_plane = cvCreateImage(cvGetSize(src), 8, 1);
IplImage* s_plane = cvCreateImage(cvGetSize(src), 8, 1);
IplImage* v_plane = cvCreateImage(cvGetSize(src), 8, 1);
IplImage* planes[] = { h_plane, s_plane };
// H 分量划分为16个等级,S分量划分为8个等级
int h_bins = 16, s_bins = 8;
int hist_size[] = { h_bins, s_bins };
// H 分量的变化范围
float h_ranges[] = { 0, 180 };
// S 分量的变化范围
float s_ranges[] = { 0, 255 };
float* ranges[] = { h_ranges, s_ranges };
// 输入图像转换到HSV颜色空间
cvCvtColor(src, hsv, CV_BGR2HSV);
cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane, 0);
//创建直方图,二维, 每个维度上均分
CvHistogram * hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1); // 根据H,S两个平面数据统计直方图
cvCalcHist(planes, hist, 0, 0);
// 获取直方图统计的最大值,用于动态显示直方图
float max_value;
cvGetMinMaxHistValue(hist, 0, &max_value, 0, 0);
// 设置直方图显示图像
int height = 240;
10
int width = (h_bins*s_bins * 6);
IplImage* hist_img = cvCreateImage(cvSize(width, height), 8, 3);
cvZero(hist_img);
// 用来进行HSV到RGB颜色转换的临时单位图像
IplImage * hsv_color = cvCreateImage(cvSize(1, 1), 8, 3);
IplImage * rgb_color = cvCreateImage(cvSize(1, 1), 8, 3);
int bin_w = width / (h_bins * s_bins);
for (int h = 0; h < h_bins; h++)
{
for (int s = 0; s < s_bins; s++)
{
int i = h*s_bins + s;
// 获得直方图中的统计次数,计算显示在图像中的高度
float bin_val = cvQueryHistValue_2D(hist, h, s);
int intensity = cvRound(bin_val*height / max_value);
// 获得当前直方图代表的颜色,转换成RGB用于绘制
cvSet2D(hsv_color, 0, 0, cvScalar(h*180.f / h_bins, s*255.f / s_bins, 255, 0));
cvCvtColor(hsv_color, rgb_color, CV_HSV2BGR);
CvScalar color = cvGet2D(rgb_color, 0, 0);
cvRectangle(hist_img, cvPoint(i*bin_w, height),
cvPoint((i + 1)*bin_w, height - intensity),
color, -1, 8, 0);
}
}
cvNamedWindow("Source", 1);
cvShowImage("Source", src);
cvNamedWindow("H-S Histogram", 1);
cvShowImage("H-S Histogram", hist_img);
cvWaitKey(0);
}
*/
//灰度直方图均衡化
/*
void FillWhite(IplImage *pImage)
{
cvRectangle(pImage, cvPoint(0, 0), cvPoint(pImage->width, pImage->height),
11
{
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsGrayTitle = "灰度图";
const char *pstrWindowsHistTitle = "直方图";
const char *pstrWindowsGrayEqualizeTitle = "灰度图-均衡化后";
const char *pstrWindowsHistEqualizeTitle = "直方图-均衡化后";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("小白.jpeg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
IplImage *pGrayEqualizeImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
// 灰度图
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
// 直方图图像数据
int nHistImageWidth = 255;
int nHistImageHeight = 150;
int nScale = 2;
// 灰度直方图及直方图图像
CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage);
IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram);
// 均衡化
cvEqualizeHist(pGrayImage, pGrayEqualizeImage);
// 均衡化后的灰度直方图及直方图图像
CvHistogram *pcvHistogramEqualize = CreateGrayImageHist(&pGrayEqualizeImage);
IplImage *pHistEqualizeImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogramEqualize);
// 显示
cvNamedWindow(pstrWindowsGrayTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsHistTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsGrayEqualizeTitle,
CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsHistEqualizeTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsGrayTitle, pGrayImage);
cvShowImage(pstrWindowsHistTitle, pHistImage);
13
{
const char *pstrWindowsSrcTitle = "原图";
const char *pstrWindowsGrayTitle = "灰度图";
const char *pstrWindowsHistTitle = "直方图";
const char *pstrWindowsGrayEqualizeTitle = "灰度图-均衡化后";
const char *pstrWindowsHistEqualizeTitle = "直方图-均衡化后";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("小白.jpeg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
IplImage *pGrayEqualizeImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
// 灰度图
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
// 直方图图像数据
int nHistImageWidth = 255;
int nHistImageHeight = 150;
int nScale = 2;
// 灰度直方图及直方图图像
CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage);
IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram);
// 均衡化
cvEqualizeHist(pGrayImage, pGrayEqualizeImage);
// 均衡化后的灰度直方图及直方图图像
CvHistogram *pcvHistogramEqualize = CreateGrayImageHist(&pGrayEqualizeImage);
IplImage *pHistEqualizeImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogramEqualize);
// 显示
cvNamedWindow(pstrWindowsGrayTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsHistTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsGrayEqualizeTitle,
CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsHistEqualizeTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsGrayTitle, pGrayImage);
cvShowImage(pstrWindowsHistTitle, pHistImage);
13
cvShowImage(pstrWindowsGrayEqualizeTitle, pGrayEqualizeImage); cvShowImage(pstrWindowsHistEqualizeTitle, pHistEqualizeImage); cvWaitKey(0); //回收资源 cvDestroyWindow(pstrWindowsGrayTitle); cvDestroyWindow(pstrWindowsHistTitle); cvDestroyWindow(pstrWindowsGrayEqualizeTitle); cvDestroyWindow(pstrWindowsHistEqualizeTitle); cvReleaseImage(&pSrcImage);
cvReleaseImage(&pGrayImage);
cvReleaseImage(&pHistImage);
cvReleaseImage(&pGrayEqualizeImage);
cvReleaseImage(&pHistEqualizeImage);
return 0;
}
14
成绩评定表
课程设计报告书课程名称题目学生姓名专业班别学号指导老师日期年月日数字图像处理的傅里叶变换1课程设计目的和意义1了解图像变换的意义和…
数字图像处理课程设计报告1课程设计目的1提高分析问题解决问题的能力进一步巩固数字图像处理系统中的基本原理与方法2熟悉掌握一门计算机…
数字图像处理课程设计报告课设题目运动目标的跟踪学院信息科学与工程学院专业电子与信息工程班级0902501班姓名学号指导教师赵占锋周…
数字图像处理课程设计1课程设计目的1提高分析问题解决问题的能力进一步巩固数字图像处理系统中的基本原理与方法2熟悉掌握一门计算机语言…
数字图像处理课程设计报告课设题目学院专业班级姓名学号指导教师彩色图像增强软件信息科学与工程学院电子与信息工程1002501曾小路1…
目录1目的与要求22图像二值化和马赛克应用背景33设计内容以及原理44各个功能模块的主要实现程序以及代码55程序运行结果以及图像处…
数字图像处理课程设计报告课设题目学院专业班级姓名学号指导教师彩色图像增强软件信息科学与工程学院电子与信息工程1002501曾小路1…
数字图像处理课程设计报告1课程设计目的1提高分析问题解决问题的能力进一步巩固数字图像处理系统中的基本原理与方法2熟悉掌握一门计算机…
数字图像处理课程设计报告姓名学号班级设计题目教师提交日期20xx7750215net2班指纹识别设计赵哲老师12月25日1一设计内…
数字图像处理设计报告设计目的配合数字图像处理课程的教学使学生能巩固和加深对数字图像处理基础理论和基本知识的理解掌握使用图像处理软件…
东北大学秦皇岛分校计算机与通信工程学院综合课程设计设计题目形态学图像处理的Matlab设计与实现专业名称班级学号学生姓名指导教师设…