IPOL上的non-local means源程序的移植过程

来源:互联网 发布:公司数据管理软件 编辑:程序博客网 时间:2024/06/03 02:37
       之前一直在网上找有没有NLM算法的源程序,一次偶然的机会,在Image Processing On Line上找到non-local means源程序的演示,并且可以下载这个源代码,所以立马把代码下下来,看看运行结果如何,如果觉得效果好的话,我直接将这个程序集成在我已经写好的一些去噪程序里。
          解压下载好的文件夹,打开其中的ReadMe.txt,看里面的介绍,发现这个程序正是这篇文章的作者 Antoni Buades先生写的,我一看是C程序,我就立即找.dsw文件或者.sln文件,因为只要找到这两个文件我就可以用VS这个IDE进行编译连接执行程序了,不幸的是,我没到这两个文件,但是我看到文件夹中包含一个了一个MakeFile文件,并且ReadMe.txt里有:
Simply use the provided makefile, with the command `make`.
     然后我就在cmd提示符下输入make命令,出现如下情况:
    
     就在网上找了原因,我就找了下如何才能使用这个makefile,就找到了一个mingw32这个编译器,根据资料显示只要装好这个编译器,然后将其中相应的bin目录放到系统路径下(设置环境变量,在bin目录下有个执行程序mingw32-make.exe),于是我在命令提示符下使用mingw32-make命令,使用这个命令就是在当前目录下寻找makefile文件,执行其中的指令,出现如下情况:
 
    
          由于我看不懂makefile文件,后来发现.o之类的文件,我才清楚这个是用在Unix下的makefile文件,不能在windows下直接使用,既然直接通过这种方式编译不来,那么我只有在VS下自己建立工程,然后导入相应的源程序,来编译咯。
          由于这里面使用到了libpng库,所以我就到libpng的官方网站http://www.libpng.org/下载了libpng-1.5.6库(注意下载windows下使用的lpng156.zip),这是一个开源库,由于libpng库又要zlib库,于是我又在网上下载了一个zlib-1.2.5库,好的,所有的就续工作完毕。
    接下来就是看如何使用这个libpng库,直接找到libpng文件夹下的ReadMe.txt,这里提示:
     See INSTALL for instructions on how to install libpng.
     于是就找到INSTALL打开来看,这里提示:
     you can use one of the "projects" in the "projects" directory,于是我就转到projects目录下,看到vstudio和visualc71这两个文件夹,由于我装的是VS2008,所以只能使用visualc71这个文件夹里的.sln文件,VS2010下可以使用vstudio里的.sln文件。
     找到visualc71这个文件夹里的libpng.sln文件,在此之前阅读下相应的ReadMe.txt,看如何使用这个文件,在这里要把libpng这个文件夹和zlib这个文件夹放在同一层目录下,我们编译libpng.sln,
至于VS的操作就不用多说啦。
     通过上述过程,我们会得到5个新的文件:
* Win32_DLL_Release\libpng15.dll      DLL build
* Win32_DLL_Debug\libpng15d.dll       DLL build (debug version)
* Win32_DLL_VB\libpng15vb.dll         DLL build for Visual Basic, using stdcall
* Win32_LIB_Release\libpng.lib        static build
* Win32_LIB_Debug\libpngd.lib         static build (debug version)
     PS:在libpng.sln中有一个pngtest工程,可以用来测试你最后是否把一些库编译成功。
     好的,这些工作我们做好之后,我们现在开始新建一个工程,我这里命名为IPOLNLM,将之前下载的程序导入这个工程中,并将之前在projects\visualc71文件夹中生成的Win32_DLL_Debug这个文件夹中的libpng15d.lib,libpng15d.dll,以及同样在这个文件夹下的Zlib文件夹中的zlib1d.lib,zlib1d.dll文件拷入IPOLNLM这个工程中,由于这里要使用到libpng的头文件,只要在tools->options->vc++ directories,将这个头文件所在的路径包含进来就OK了,这样引用这个头文件就不会找不到啦。

     做好上述工作之后,我们进行编译,会报错:
    Cannot open include file: 'unistd.h',一查发现这unistd.h是UNIX下使用的库函数头文件,类似于windows下的'windows.h',这里的话,为了不让其报错,我们可以自己先写一个unistd.h文件,然后再看会报什么错,unistd.h的内容为:

/** This file is part of the Mingw32 package.
* unistd.h maps (roughly) to io.h
*/
#ifndef _UNISTD_H
#define _UNISTD_H

#include <io.h>
#include <process.h>

#endif /* _UNISTD_H */

    由于我们是在当前目录中引用这个unistd.h这个头文件,所以需要将#include <unistd.h>改成#include "unistd.h",然后继续编译,继续报错:
1. 'M_PI' : undeclared identifier
2. 'rintf': identifier not found
    首先我们可以查下M_PI是一个宏,实际上cmath函数里的,但是无法识别,这个好像是一个C/C+标准函数库的一个bug,解决方法很简单,
    在libauxiliar.h这个头文件中加入#define _USE_MATH_DEFINES这个宏定义,就OK。
    rintf是一个四舍五入函数,在这里我们可以将
int iLutLength = (int) rintf((float) LUTMAX * (float) LUTPRECISION);
改成
int iLutLength = (int) ((float) LUTMAX * (float) LUTPRECISION+0.5);
    效果是一样的。继续编译,然后又报错,
   _main already defined in nlmeans_ipol.obj

    这是因为在这个工程里面有三个main函数,由于我们这里只是为了使用NLM进行去噪,所以img_diff_ipol.cpp和img_mse_ipol.cpp这两个文件我们可以暂时先从当前工程中删除掉,
    然后再编译,链接,OK成功了!
    在控制台下输出:
usage: nlmeans_ipol image sigma noisy denoised!
    这是因为这个函数需要main函数传递参数,我们没有传递,至于怎么传,我想大家都知道,嘿嘿.(PS:这个程序只能处理png图像,所以大家请传递.png格式的图像进行处理)
    由于使用了OPENMP技术,所以这个NLM程序速度还是比较快的!HOHO
 

原创粉丝点击