Win10编译OpenCV2.4.9+CUDA7.5的方法

最近开始对视频处理代码做CUDA优化,考虑将OpenCV2.4.9的代码增加GPU版本的实现。经过简单尝试之后发现需要自己重新编译OpenCV。过程中有一些小Trick,在此记录下来。

1.需要准备的软件环境

需要准备的软件环境如下:

软件 版本
操作系统 Windows 10 x64
Visual Studio 2013
CUDA 7.5
OpenCV 2.4.9
CMake 3.0.2

其中操作系统、VS、CUDA、Cmake的版本不一定非得如表中,确保VS+CUDA是可以正常编译运行CUDA Samples程序即可。OpenCV的版本则一定是2.4.9,其他版本没有测试,虽然编译步骤大致相同,但是可以有一些需要自己解决的小问题。

2.编译

(1)首先解压OpenCV2.4.9.exe到一个目录,我的是E:\libraries。修改源码文件
E:\libraries\opencv\sources\modules\gpu\src\nvidia\core\NCV.cu
添加 一个#include如下:

#include 
#include 
#include 
#include  //手动添加
#include "NCV.hpp"

不添加此#include编译GPU模块时会出现max函数找不到的错误。编译GPU模块耗时2个小时左右,出错得全部重新来,所以建议第一步改这里。

(2)打开Cmake-GUI,设置好源代码目录E:/libraries/opencv/sources和目标目录E:/libraries/opencv/build/cuda。目标目录需要手动创建。
cmake
之后点击"Configure"按钮,会要求你选择编译器,我选了VS2013x64,也就是说编译64位的opencv。一会儿之后信息栏就会出现“Configure Done"。然后根据需要可以选择一些模块,其中如果你的CUDA安装好了WITH_CUDA选项默认是勾选上的,默认没有勾选上的话请检查CUDA是否能正常工作。

接下来一个必不可少的步骤是设置CUDA_GENREATION选项,这个选项默认是留空的,需要根据你的显卡架构来设置。可以在网上查询你显卡的架构,我的GTX 870m是Kelper架构的,因此选择Kelper。注意不要选”Auto“,否则编译时会出现“架构不匹配:compute_11”之类的错误。
cmake_detail
另外CUDA_ARCH_BIN选项是CUDA执行版本,一般保留一两个最新的就可以。过多的版本可以导致编译GPU模块时非常慢。

然后点击"Generate",会在目标目录生成一个OpenCV.sln的VS项目。

(3)打开OpenCV.sln,解决方案配置选择“Release”(默认是“DEBUG”),直接编译。大多数模块会在20分钟之内编译完毕。最后是GPU模块,这个模块的编译时间在两个小时左右,编译出的dll文件有128MB左右。如果做了前面所说的修改和选项设置,编译过程应该没有错误。

(4)将编译好的lib和dll文件覆盖OpenCV build目录下VS12 x64对应的文件(覆盖前最好对原文件备份)。然后你的OpenCV可以正常使用GpuMat等GPU数据结构和函数了。

3.注意事项

(1)注意2(1)中的源码修改和2(2)中的CUDA_GENERATION选项设置;
(2)编译GPU模块在我的鲁大师19万分的电脑上耗时2个小时左右,需要耐心。

Ubuntu14.04更新Kernel和Nvidia/Cuda驱动不兼容卡在启动画面的故障排除

1. 故障现象和原因

昨天开笔记本的Ubutnu14.04突然发现卡死在启动画面了,Ctrl+Alt+F1也没反应,只能长按电源键.启动菜单选择"高级"模式进入,用"recover->resume"之后能看到登陆界面,Ctrl+Alt+F1可用,但是一旦输入密码登陆系统再次黑屏卡死。

经过调试,发现故障是由Nvidia-352驱动(由cuda7.5安装包安装)导致的.但是此驱动我使用已经有一个多月,回忆了近期对系统的修改,怀疑是更新Ubuntu核心组件出的问题.这才反应过来启动菜单的高级选项里出现了"3.13.0-66"、"3.13.0-65"、"3.13.0-61"三个kernel版本.推定问题是由新kernel与nvidia-352不兼容导致的。
继续阅读

Matlab通过mex调用CUDA的方法

最近有使用Matlab通过mex调用CUDA加速视频处理的需求,于是折腾了一下,网上的说法可谓千奇百怪众说纷纭,却没有能用的。经过六个多小时的反复搜索和尝试,本人终于成功编译运动了了matlab的mexCUDA例程:mexGPUExample.cu。

1.软件环境

这个过程涉及三个环境:Visual Studio、Cuda Toolkit和Matlab。其中Cuda依赖Visual Studio、Matlab依赖Cuda和Visual Studio。官方正式支持的版本关系如下表:

Matlab版本 CUDA版本 Visual Studio版本
2014a 5.5 2008,2010
2014b 6.5 2008,2010,2012

本人用的Win10系统(64位),Matlab2014b、Cuda 7.5和VS2013。如果使用官方支持的版本,需要降级Cuda驱动和VS版本,要命的是,低版本的Cuda驱动在Win10上会崩溃(本人遇到过一次)。通过修改mex配置文件,可以使以上软件版本也用Cuda。

继续阅读

线性约束最优化问题的Frank-Wolfe方法

在无约束最优化问题的基础上,我们可以进一步来求解约束最优化问题。约束最优化问题的一般形式为:
$$
\begin{aligned}
&\min f(x) \\
&s.t. \quad g_i(x)\ge0, i=1,...,m
\end{aligned}
$$

先考虑$g_i(x)$均为线性函数的情况,此时问题与线性规划的约束条件相同,仅仅是目标函数变成了非线性的。我们可以用泰勒展开对目标函数进行近似,将它线性化。将$f(x)$在$x_k$处展开,有
$$
f(x)\approx f(x_k) + \nabla f(x_k)^T(x-x_k)
$$
故原问题近似于
$$
\begin{aligned}
&\min f(x)\approx f(x_k) + \nabla f(x_k)^T(x-x_k) \\
&s.t.\quad x \in S
\end{aligned}
$$
其中$S$为线性约束构成的可行域。去掉常量后,问题可以写为
$$
\begin{aligned}
&\min f(x)\approx \nabla f(x_k)^Tx \\
&s.t.\quad x \in S
\end{aligned}
$$
设此问题的最优解为$y_k$,则直观上$d_k=y_k-x_k$ 应当为原问题的可行下降方向。沿着此方向做一维搜索则可进行一次迭代。为了防止一维搜索的结果超出可行域,我们限制步长$0\leq\lambda\leq1$。注意到线性规划的可行域为凸集,由于$x_k$和$y_k$均为可行点,它们确定的连线均在可行域中。限制步长$0\leq\lambda\leq1$保证了一维搜索的结果在可行域中。

Frank-Wolfe算法的步骤总结如下:

  1. 选择初值。初始点$x_0\in S$,给定允许误差$\epsilon>0$,令$k=0$。
  2. 求解近似线性规划:$$ \begin{aligned}&\min \nabla f(x_k)^Tx \\ &s.t.\quad x \in S\end{aligned}$$ 得最优解$y_k$。
  3. 构造可行下降方向。令$d_k=y_k-x_k$。若$||\nabla f(x_k)^Td_k \leq \epsilon||$,停止计算,输出$x_k$;否则,转4。
  4. 进行一维搜索:$$\min_{0\leq \lambda \leq 1} f(x_k+\lambda d_k)$$得步长$\lambda_k$。令$$x_{k+1}=x_k+\lambda_k d_k \\ k \leftarrow k+1 $$,转2。

Frank-Wolfe方法将线性约束最优化问题转化为一系列线性规划问题和一维搜索问题求解。可以证明,当$f$具有连续一阶偏导数,且可行域$S$有界,Frank-Wolfe方法是收敛的。

无约束最优化方法学习笔记

这一段时间学习优化理论中的一些经典方法,写下一些要点和体会,帮助自己和有需要的人理解最优化方法。

1.基础知识

首先来看无约束最优化问题:
\begin{equation}
\min f(x)
\end{equation}
其中函数 $f:R^n\rightarrow R$.求解此问题的方法方法分为两大类:最优条件法和迭代法。

所谓的最优条件法,是指当函数存在解析形式,能够通过最优性条件求解出显式最优解。对于无约束最优化问题,如果$f(x)$在最优点$\bar{x}$附近可微,那么$\bar{x}$是局部极小点的必要条件为:
\begin{equation}
\nabla f(\bar{x})=0
\end{equation}

我们常常就是通过这个必要条件去求取可能的极小值点,再验证这些点是否真的是极小值点。当上式方程可以求解的时候,无约束最优化问题基本就解决了。实际中,这个方程往往难以求解。这就引出了第二大类方法:迭代法。

迭代法,也称为“搜索”法,主要思想是通过简单的运算构造点列,逐渐逼近问题的最优解。这里说的“点”是多维空间中的点,也称为“向量”。还有少部分算法通过构造点的集合来逼近问题的最优解,如单纯形调优法。

用于求解无约束最优化问题的方法可以分为解析法和直接法两大类。解析法在构造迭代公式的过程中往往使用了泰勒展开来作近似或者推导,因此迭代步骤中含有梯度$\nabla f(x)$或黑塞(Hessian)矩阵$\nabla^2f(x)$,在问题的解析形态较好的情况下使用往往能获得比较快的收敛速度。而直接法则从物理角度思考如何递推,不会用到梯度或者黑塞矩阵,它对问题的解析形态几乎没有要求,只要能计算出函数值即可。当然,它的收敛速度往往难于保证。
继续阅读