VC++实现Contourlet图像处理

 

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<height;i++)

       {

              for(j=0;j<width;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<width;i++)
 {
  for(j=0;j<height;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,所以要显示的话先进行归一化处理.

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值