2015-05-24 39 views
0

以下代碼是PCL(點雲)庫中的代碼片段。它計算圖像的積分和。從模板中提取原始數據以用於CUDA

template <class DataType, unsigned Dimension> class IntegralImage2D 
{ 
    public: 
     static const unsigned dim_fst = Dimension; 
     typedef cv::Vec<typename TypeTraits<DataType>::IntegralType, dim_fst> FirstType; 
     std::vector<FirstType> img_fst; 

     //.... lots of methods missing here that actually calculate the integral sum 

     /** \brief Compute the first order sum within a given rectangle 
      * \param[in] start_x x position of rectangle 
      * \param[in] start_y y position of rectangle 
      * \param[in] width width of rectangle 
      * \param[in] height height of rectangle 
      */ 
     inline FirstType getFirstOrderSum(unsigned start_x, unsigned start_y, unsigned width, unsigned height) const 
     { 
      const unsigned upper_left_idx = start_y * (wdt + 1) + start_x; 
      const unsigned upper_right_idx = upper_left_idx + width; 
      const unsigned lower_left_idx =(start_y + height) * (wdt + 1) + start_x; 
      const unsigned lower_right_idx = lower_left_idx + width; 

      return(img_fst[lower_right_idx] + img_fst[upper_left_idx] - img_fst[upper_right_idx] - img_fst[lower_left_idx]); 
     } 

目前正在使用下面的代碼得到的結果:

IntegralImage2D<float,3> iim_xyz; 

IntegralImage2D<float, 3>::FirstType fo_elements; 
IntegralImage2D<float, 3>::SecondType so_elements; 
fo_elements = iim_xyz.getFirstOrderSum(pos_x - rec_wdt_2, pos_y - rec_hgt_2, rec_wdt, rec_hgt); 
so_elements = iim_xyz.getSecondOrderSum(pos_x - rec_wdt_2, pos_y - rec_hgt_2, rec_wdt, rec_hgt); 

但是我想parallelise代碼(寫getFirstOrderSum作爲CUDA設備功能)。由於CUDA不識別這些FirstType和SecondType對象(或者任何opencv對象),所以我很努力(我是C++的新手)從模板中提取原始數據。

如果可能,我想將img_fst對象轉換爲某種可以在cuda內核上分配的向量或數組。

似乎img_fst是類型std::vector<cv::Matx<double,3,1>

+2

也許與您的問題沒有直接關係,但[npp庫](http://docs.nvidia.com/cuda/npp/index.html#abstract)提供了計算積分圖像的方法。 –

+0

看來你正在尋找'Mat :: ptr'。 – Jarod42

+0

@ Jarod42:你能詳細說明一下嗎?這是爲了墊子而不是爲了正確嗎? – Thomas

回答

0

的事實證明可以就像使用法線向量傳遞的原始數據。

void computation(ps::IntegralImage2D<float, 3> iim_xyz){ 
    cv::Vec<double, 3>* d_img_fst = 0; 
    cudaErrorCheck(cudaMalloc((void**)&d_img_fst, sizeof(cv::Vec<double, 3>)*(iim_xyz.img_fst.size()))); 
    cudaErrorCheck(cudaMemcpy(d_img_fst, &iim_xyz.img_fst[0], sizeof(cv::Vec<double, 3>)*(iim_xyz.img_fst.size()), cudaMemcpyHostToDevice)); 
//.. 
} 

__device__ double* getFirstOrderSum(unsigned start_x, unsigned start_y, unsigned width, unsigned height, int wdt, cv::Vec<double, 3>* img_fst) 
{ 
    const unsigned upper_left_idx = start_y * (wdt + 1) + start_x; 
    const unsigned upper_right_idx = upper_left_idx + width; 
    const unsigned lower_left_idx = (start_y + height) * (wdt + 1) + start_x; 
    const unsigned lower_right_idx = lower_left_idx + width; 

    double* result = new double[3]; 
    result[0] = img_fst[lower_right_idx].val[0] + img_fst[upper_left_idx].val[0] - img_fst[upper_right_idx].val[0] - img_fst[lower_left_idx].val[0]; 
    result[1] = img_fst[lower_right_idx].val[1] + img_fst[upper_left_idx].val[1] - img_fst[upper_right_idx].val[1] - img_fst[lower_left_idx].val[1]; 
    result[2] = img_fst[lower_right_idx].val[2] + img_fst[upper_left_idx].val[2] - img_fst[upper_right_idx].val[2] - img_fst[lower_left_idx].val[2]; 

    return result; //i have to delete this pointer otherwise I will create memory leak 
} 
相關問題