在Visual Studio 2012中使用CUDA构建OpenCV

4
我需要使用Visual Studio 2012编译OpenCV 2.4.5。特别是我对使用Cuda 5.0编译gpu模块感兴趣。
为了在VS2012中启用CUDA编译,我遵循了这篇指南
我使用CMake创建VS2012解决方案,然后对于每个.cu文件,我将元素类型从“自定义构建规则”更改为“CUDA C/C++”。
我可以编译大多数项目文件,但在某些文件上遇到了烦人的问题。
例如,fgd_bgfg.cu会导致
错误 C2039:“ParameterType”不是“cv::gpu::device::TypeTraits”的成员
但是在type_traits.hpp中,我可以看到
typedef typename type_traits_detail::Select<IsSimpleParameter<UnqualifiedType>::value,
            T, typename type_traits_detail::AddParameterType<T>::type>::type ParameterType;

这是一个非常烦人的问题,我无法摆脱!

我不敢相信没有人已经使用VS2012和GPU构建过opencv,你有什么建议吗?


1
CUDA官方不支持VS2012,因此在VS2012中使用CUDA构建OpenCV失败并不令人意外。 - talonmies
我知道这个,但是很多人已经使用CUDA并且掌握了一些技巧,比如我在问题中提到的那个。此外,OpenCV预编译库已经包含了VS2012二进制文件。对我来说,没有人尝试使用VS2012编译GPU模块似乎非常奇怪。 - Nicola Pezzotti
我能够在最新的CUDA 5.5 RC(此版本正式支持VS 2012)中使用VS 2012构建OpenCV。只有一个问题:您应该将CMake变量CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE设置为OFF。 - vinograd47
我会尽快尝试,你编译的OpenCV版本是哪个? - Nicola Pezzotti
1
我编译了主分支。但是最新的OpenCV发行版(2.4.6)也支持CUDA 5.5,所以它也应该可以工作。 - vinograd47
1个回答

1
似乎CUDA编译器无法处理模板特性技术。一种简单的方法是使用三种基本类型:double,float和int来指定TypeTraits模板。我不确定这种方式是否正确,但CUDA编译器不会抱怨。
代码如下:
template<> struct TypeTraits<double>
{
    typedef type_traits_detail::UnConst<double>::type                                                NonConstType;
    typedef type_traits_detail::UnVolatile<double>::type                                             NonVolatileType;
    typedef type_traits_detail::UnVolatile<typename type_traits_detail::UnConst<double>::type>::type UnqualifiedType;
    typedef type_traits_detail::PointerTraits<double>::type                            PointeeType;
    typedef type_traits_detail::ReferenceTraits<double>::type                                        ReferredType;

    enum { isConst          = type_traits_detail::UnConst<double>::value };
    enum { isVolatile       = type_traits_detail::UnVolatile<double>::value };

    enum { isReference      = type_traits_detail::ReferenceTraits<double>::value };
    enum { isPointer        = type_traits_detail::PointerTraits<typename type_traits_detail::ReferenceTraits<double>::type>::value };

    enum { isUnsignedInt    = type_traits_detail::IsUnsignedIntegral<double>::value };
    enum { isSignedInt      = type_traits_detail::IsSignedIntergral<double>::value };
    enum { isIntegral       = type_traits_detail::IsIntegral<double>::value };
    enum { isFloat          = type_traits_detail::IsFloat<double>::value };
    enum { isArith          = isIntegral || isFloat };
    enum { isVec            = type_traits_detail::IsVec<double>::value };

    typedef double ParameterType;
};
template<> struct TypeTraits<float>
{
    typedef type_traits_detail::UnConst<float>::type                                                NonConstType;
    typedef type_traits_detail::UnVolatile<float>::type                                             NonVolatileType;
    typedef type_traits_detail::UnVolatile<typename type_traits_detail::UnConst<float>::type>::type UnqualifiedType;
    typedef type_traits_detail::PointerTraits<float>::type                            PointeeType;
    typedef type_traits_detail::ReferenceTraits<float>::type                                        ReferredType;

    enum { isConst          = type_traits_detail::UnConst<float>::value };
    enum { isVolatile       = type_traits_detail::UnVolatile<float>::value };

    enum { isReference      = type_traits_detail::ReferenceTraits<float>::value };
    enum { isPointer        = type_traits_detail::PointerTraits<typename type_traits_detail::ReferenceTraits<float>::type>::value };

    enum { isUnsignedInt    = type_traits_detail::IsUnsignedIntegral<float>::value };
    enum { isSignedInt      = type_traits_detail::IsSignedIntergral<float>::value };
    enum { isIntegral       = type_traits_detail::IsIntegral<float>::value };
    enum { isFloat          = type_traits_detail::IsFloat<float>::value };
    enum { isArith          = isIntegral || isFloat };
    enum { isVec            = type_traits_detail::IsVec<float>::value };

    typedef float ParameterType;
};

template<> struct TypeTraits<int>
{
    typedef type_traits_detail::UnConst<int>::type                                                NonConstType;
    typedef type_traits_detail::UnVolatile<int>::type                                             NonVolatileType;
    typedef type_traits_detail::UnVolatile<typename type_traits_detail::UnConst<int>::type>::type UnqualifiedType;
    typedef type_traits_detail::PointerTraits<int>::type                            PointeeType;
    typedef type_traits_detail::ReferenceTraits<int>::type                                        ReferredType;

    enum { isConst          = type_traits_detail::UnConst<int>::value };
    enum { isVolatile       = type_traits_detail::UnVolatile<int>::value };

    enum { isReference      = type_traits_detail::ReferenceTraits<int>::value };
    enum { isPointer        = type_traits_detail::PointerTraits<typename type_traits_detail::ReferenceTraits<int>::type>::value };

    enum { isUnsignedInt    = type_traits_detail::IsUnsignedIntegral<int>::value };
    enum { isSignedInt      = type_traits_detail::IsSignedIntergral<int>::value };
    enum { isIntegral       = type_traits_detail::IsIntegral<int>::value };
    enum { isFloat          = type_traits_detail::IsFloat<int>::value };
    enum { isArith          = isIntegral || isFloat };
    enum { isVec            = type_traits_detail::IsVec<int>::value };

    typedef int ParameterType;
};

复制type_traits.hpp中的代码,放在原始TypeTraits定义后面。构建...然后祈祷。

祝好运!:-D


使用主分支,我使用VS2012和CUDA支持构建了Emgu x64版本。为此,我不得不进行一些更改: 1.修改Build_Binary_x86.bat以启用CUDA模式 2.更改CUDA设备的“代码生成”编译参数:compute_30,sm_30。 顺便说一下,我是在Windows 7 64位下工作的。 - igame

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接