CUDA+OPENCV混合编程之访问GpuMat中的每一个像素

一、环境配置

Ubuntu + CUDA + OPENCV。先安装NVIDIA显卡驱动,再安装CUDA,最后编译安装OpenCV(加上了CUDA的模块)。
安装 CUDA:https://blog.csdn.net/DumpDoctorWang/article/details/82317235
编译OpenCV: https://blog.csdn.net/DumpDoctorWang/article/details/82259357

二、代码

//main.cpp
#include 
#include "kernel.h"

#define WIDTH 1024
#define HEIGHT 512
int main()
{
    GpuMat mat(HEIGHT,WIDTH,CV_8UC3);

    generateFrameCaller(mat);
    if (cudaGetLastError() != cudaSuccess){ //Check error after call kernel function
        std::cout << "调用generateFrameCaller失败"<<std::endl;
        exit(-1);
    }
    Mat dst;
    mat.download(dst);
    imshow("result",dst);
    waitKey(0);
    return 0;
}
#ifndef OCSAMPLE_KERNEL_H
#define OCSAMPLE_KERNEL_H

#include 
#include 
#include 

using namespace cv;
using namespace cv::cuda;

void generateFrameCaller(GpuMat mat);

#endif //OCSAMPLE_KERNEL_H

//kernel.cu
#include "kernel.h"
/**
 * 访问图片中的每一个像素
 * @param width mat对应的宽度
 * @param height mat对应的高度
 * @param mat GpuMat被强转为PtrStep<>类型之后的参数
 */
__global__ void generateFrame(PtrStepSz<uchar3> mat)
{
    int i = threadIdx.x + blockIdx.x * blockDim.x; //列坐标
    int j = threadIdx.y + blockIdx.y * blockDim.y; //行坐标

    if(i < mat.cols && j < mat.rows) // 必须要检查是否越界
    {
        mat(j,i) = make_uchar3(i%255, j%255,(i+j)%255);     //mat(j,i)才是正确打开方式
    }
}

/**
 * 调用内核函数的主机函数
 * @param width mat对应的宽度
 * @param height mat对应的高度
 * @param mat GpuMat被强转为PtrStep<>类型之后的参数
 */
void generateFrameCaller(GpuMat mat)
{
    dim3 threads(32,32);
    dim3 blocks(mat.cols/threads.x, mat.rows/threads.y);
    generateFrame<<<blocks,threads>>>(mat);
}
cmake_minimum_required(VERSION 3.0)

project(OCSample)

set(CUDA_USE_STATIC_CUDA_RUNTIME ON) #这一句解决 cannot find -lopencv_dep_cudart
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})

find_package(CUDA REQUIRED)
message(STATUS "CUDA版本: ${CUDA_VERSION}")
message(STATUS "    头文件目录:${CUDA_INCLUDE_DIRS}")
message(STATUS "    库文件列表:${CUDA_LIBRARIES}")
set(CUDA_NVCC_FLAGS -G;-g;-std=c++11) # nvcc flags
include_directories(${CUDA_INCLUDE_DIRS})


set(OpenCV_DIR "/usr/local/opencv343-cuda90/share/OpenCV") # 指定OpenCV安装路径来区分不同的OpenCV版本
find_package(OpenCV REQUIRED)
set(OpenCV_LIB_DIR ${OpenCV_INSTALL_PATH}/lib)
message(STATUS "OpenCV版本: ${OpenCV_VERSION}")
message(STATUS "    头文件目录:${OpenCV_INCLUDE_DIRS}")
message(STATUS "    库文件目录:${OpenCV_LIB_DIR}")
message(STATUS "    库文件列表:${OpenCV_LIBS}")
include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIB_DIR})


CUDA_ADD_EXECUTABLE(main main.cpp kernel.h kernel.cu)
target_link_libraries(main ${OpenCV_LIBS} ${CUDA_LIBRARIES})

三、可能遇到的Bug

解决cannot find -lopencv_dep_cudart问题

你可能感兴趣的:(OpenCV与CUDA混合编程)