八里台碧桂园二手房:VC++实现Contourlet图像处理

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 14:14:19

VC++实现Contourlet图像处理

分类: C/C++ 2011-08-02 10:37 88人阅读 评论(1) 收藏 举报

Contourlet的作者只提供了Matlab源代码,效率较低,法国的一位大牛,IRISA University的Vivien Chappelier,编写了Contourlet的C代码。本文简单介绍利用该源代码实现基于Contourlet的图像处理,系统平台为WindowsXP + VC++6.0。因为Contourlet涉及大量的矩阵操作,因此在矩阵处理中采用LIBIT库。图像基本处理(包括图像输入输出等一些最基本的操作)则采用OpenCV库。

所有源代码都可在以下网址下载:

LIBIT:http://libit.sourceforge.net

OpenCV:http://www.opencv.org.cn

Contourlet 源代码:http://www.irisa.fr/temics/Equipe/Chappelier/contourlets.tar.gz

一、OpenCV和LIBIT

OpenCV使用较广,网上有大量的中文资料,在此不再介绍。

从网上搜索情况来看,使用LIBIT库的人极少,这里主要介绍如何使用该库,至于库函数的详细说明请参阅附带的文档,如果未来有时间,有可能会翻译该文档,暂时还是看鸟语吧。LIBIT库采用C语言编写,大大扩展了C语言处理向量、矩阵和复数的能力,同时还提供一些的信号处理函数,比如傅里叶变换和小波变换等。根据我的体会,使用该库对程序速度有一定影响,但考虑到该库处理矩阵非常方便,同时包含小波变换等函数,因此在一般应用中不妨使用。

LIBIT库的调用方法有两种,第一种方法是将LIBIT库的头文件和源文件全部加入工程中,和程序一起编译链接,比较麻烦且编译时间长,不推荐。第二种方法是将LIBIT库生成为动态链接库,在工程中调用即可。这里采用隐式调用方法,隐式调用动态链接库需要:DLL文件、LIB文件和头文件。LIBIT库本身不包含DLL和LIB文件,需要自己生成。

1, 打开LIBIT库VC目录下的工程文件libit.dsw。

2, 在项目管理中的FileView中,展开libit files和libit_static files,删除其中的vlc_coding.h和vlc_coding.cpp。

3, 编译libit和libit_static,分别生成libit.dll和libit_static.lib。

4, 将libit.dll复制到你的工程目录下的debug目录;新建lib目录,将libit_static.lib复制到该目录;

5, 将LIBIT库的include目录复制到你的工程目录下。

6, 设置工程:

7, Project Settings-->C/C++,Precompiled Headers设置为Not using precompiled headers,Preprocessor的Additional include directories添加include

Project Settings-->Link, Object/library modules添加libit_static.lib, Additional library path中添加lib

二、将IplImage图像数据转化为LIBIT库矩阵形式

mat load_mat(IplImage* img)

{

int i,j;

int width=img->width;

int height=img->height;

mat m = mat_new (height, width);

for(i=0;i

{

for(j=0;j

{

m[i][j]=cvGetReal2D(img, j, i );

}

}

return m;

}

IplImage转为mat的函数:


IplImage* save_mat(mat m)
{
int i,j;
int width=mat_height(m); //矩阵列数为图像宽
int height=mat_width(m); //矩阵行数为图像高

IplImage* img = cvCreateImage(cvSize(width,height),8,1);

for(i=0;i{
for(j=0;j{
cvSetReal2D(img, i,j,m[j][i] );
}
}
return img;
}

三,对图像进行Contourlet变换

函数默认采用9/7滤波器,若要使用其他滤波器,在contourlet.cpp更改.


IplImage* ImgCT(IplImage* src,int ct_levels)
{
int i, j;
int w, h;

ivec dfb_levels; //向量组存放每一层的方向数
mat source, dest;
contourlet_t *contourlet;

//转换图像为mat格式
source = load_mat(src);
h = mat_height(source);
w = mat_width(source);
dest = mat_new(w, h);

//方向数设置,考虑到速度,只分解3层,每层方向数为4
dfb_levels=ivec_new(ct_levels);
dfb_levels[0]=4;
dfb_levels[1]=4;
dfb_levels[2]=4;

contourlet = contourlet_new(ct_levels, dfb_levels);

//Contourlet分解
contourlet_transform(contourlet, source);

//Contourlet重构
contourlet_itransform(contourlet, dest);
IplImage* result_img=save_mat(dest);

//释放变量
contourlet_delete(contourlet);
ivec_delete(dfb_levels);
mat_delete(dest);
mat_delete(source);

return result_img;
}

contourlet的结构体已经定义了各部分系数,所以要分开处理也比较方便.

typedef struct {
int ct_levels;

ivec dfb_levels;
mat low;
mat **high;
mat *dwt;
vec H0;
vec G0;
} contourlet_t;

比如要显示第1层第1个方向:

mat high=contourlet->high[1][1];
IplImage* high_img=save_mat(high);

cvNamedWindow("high[1][1]",1);
cvShowImage("high[1][1]",high_img);

不过要注意的是低频部分系数范围并不是0~255,所以要显示的话先进行归一化处理.