OpenCV+CUDA学习5---Sobel算法

目录

1、OPENCV+CUDA

2、CUDA

3、展示

3.1 cuda

3.2 opencv+cuda


1、OPENCV+CUDA

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/cudaarithm.hpp>
#include <opencv2/cudafeatures2d.hpp>
#include <opencv2/cudabgsegm.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/cudafilters.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/cudalegacy.hpp>
#include <opencv2/cudaobjdetect.hpp>
#include <opencv2/cudaoptflow.hpp>
#include <opencv2/cudastereo.hpp>
#include <opencv2/cudawarping.hpp>



int main(int argc, char* argv[])
{
    try
    {
        cv::Mat src_host = cv::imread("H:\\opencv_project\\opencv_cuda学习\\image\\cameraman.tif", 0);
        cv::cuda::GpuMat dst, src;
        src.upload(src_host);
        //cv::cuda::cvtColor(src, src,cv::COLOR_BGR2BGRA);

        auto sobel_dx = cv::cuda::createSobelFilter(src.type(), src.type(), 1, 0, 3);
        auto sobel_dy = cv::cuda::createSobelFilter(src.type(), src.type(), 0, 1, 3);
        cv::cuda::GpuMat grad_x, grad_y, grad_xy;
        sobel_dx->apply(src, grad_x);
        sobel_dy->apply(src, grad_y);
        cv::cuda::addWeighted(grad_x, 0.5, grad_y, 0.5, 0, grad_xy);
        cv::Mat grad_host;
        grad_xy.download(grad_host);


        cv::namedWindow("opencv-cuda", cv::WINDOW_NORMAL);
        cv::imshow("opencv-cuda", grad_host);
        cv::waitKey();
    }
    catch (const cv::Exception& ex)
    {
        std::cout << "Error: " << ex.what() << std::endl;
    }
    return 0;
}

2、CUDA

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cuda.h>
#include <device_functions.h>
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
//========================Sobel算子边缘检测核函数========================
__global__ void sobelInCuda(unsigned char* dataIn, unsigned char* dataOut, int imgHeight,  int imgWidth)
{
    int xIndex = threadIdx.x + blockIdx.x * blockDim.x;
    int yIndex = threadIdx.y + blockIdx.y * blockDim.y;
    int index = yIndex * imgWidth + xIndex;
    int Gx = 0;
    int Gy = 0;
    if (xIndex > 0 && xIndex < imgWidth - 1 && yIndex > 0 && yIndex < imgHeight - 1)
    {
        Gx = dataIn[(yIndex - 1) * imgWidth + xIndex + 1] + 2 * dataIn[yIndex * imgWidth +  xIndex + 1] + dataIn[(yIndex + 1) * imgWidth + xIndex + 1]
            - (dataIn[(yIndex - 1) * imgWidth + xIndex - 1] + 2 * dataIn[yIndex * imgWidth  + xIndex - 1] + dataIn[(yIndex + 1) * imgWidth + xIndex - 1]);
        
        Gy = dataIn[(yIndex - 1) * imgWidth + xIndex - 1] + 2 * dataIn[(yIndex - 1) *  imgWidth + xIndex] + dataIn[(yIndex - 1) * imgWidth + xIndex + 1]
            - (dataIn[(yIndex + 1) * imgWidth + xIndex - 1] + 2 * dataIn[(yIndex + 1) *  imgWidth + xIndex] + dataIn[(yIndex + 1) * imgWidth + xIndex + 1]);
        dataOut[index] = (abs(Gx) + abs(Gy)) / 2;
    }
}

//====================Sobel算子边缘检测CPU函数====================
void sobel(Mat srcImg, Mat dstImg, int imgHeight, int imgWidth)
{
    int Gx = 0;
    int Gy = 0;
    for (int i = 1; i < imgHeight - 1; i++)
    {
        uchar* dataUp = srcImg.ptr<uchar>(i - 1);
        uchar* data = srcImg.ptr<uchar>(i);
        uchar* dataDown = srcImg.ptr<uchar>(i + 1);
        uchar* out = dstImg.ptr<uchar>(i);
        for (int j = 1; j < imgWidth - 1; j++)
        {
            Gx = (dataUp[j + 1] + 2 * data[j + 1] + dataDown[j + 1]) - (dataUp[j - 1] + 2  * data[j - 1] + dataDown[j - 1]);
            Gy = (dataUp[j - 1] + 2 * dataUp[j] + dataUp[j + 1]) - (dataDown[j - 1] + 2 *  dataDown[j] + dataDown[j + 1]);
            out[j] = (abs(Gx) + abs(Gy)) / 2;
        }
    }
}
int main()
{
    //==================opencv加载图像==================
    Mat grayImg = imread("H:\\opencv_project\\opencv_cuda学习\\image\\hist_02.jpg", 0);
    int imgHeight = grayImg.rows;
    int imgWidth = grayImg.cols;
    Mat gaussImg;
    //====================高斯滤波=====================
    GaussianBlur(grayImg, gaussImg, Size(3, 3), 0, 0, BORDER_DEFAULT);
    //=================Sobel算子CPU实现================
    Mat dst(imgHeight, imgWidth, CV_8UC1, Scalar(0));
    sobel(gaussImg, dst, imgHeight, imgWidth);
    //===============CUDA实现后的传回的图像=============
    Mat dstImg(imgHeight, imgWidth, CV_8UC1, Scalar(0));
    //==================创建GPU内存===================
    unsigned char* d_in;
    unsigned char* d_out;
    cudaMalloc((void**)&d_in, imgHeight * imgWidth * sizeof(unsigned char));
    cudaMalloc((void**)&d_out, imgHeight * imgWidth * sizeof(unsigned char));
    //================将高斯滤波后的图像从CPU传入GPU=================
    cudaMemcpy(d_in, gaussImg.data, imgHeight * imgWidth * sizeof(unsigned char),  cudaMemcpyHostToDevice);
    dim3 threadsPerBlock(32, 32);
    dim3 blocksPerGrid((imgWidth + threadsPerBlock.x - 1) / threadsPerBlock.x, (imgHeight  + threadsPerBlock.y - 1) / threadsPerBlock.y);
    //========================调用核函数=======================
    sobelInCuda << <blocksPerGrid, threadsPerBlock >> > (d_in, d_out, imgHeight,  imgWidth);
    //=======================将图像传回GPU=====================
    cudaMemcpy(dstImg.data, d_out, imgHeight * imgWidth * sizeof(unsigned char),  cudaMemcpyDeviceToHost);
    //=========================释放GPU内存====================
    cudaFree(d_in);
    cudaFree(d_out);
    cv::namedWindow("cuda-sobel",cv::WINDOW_NORMAL);
    cv::imshow("cuda-sobel", dstImg);
    cv::waitKey(0);
    return 0;
}

3、展示

3.1 cuda

OpenCV+CUDA学习5---Sobel算法

3.2 opencv+cuda

OpenCV+CUDA学习5---Sobel算法

 

上一篇:图像边缘检测:Canny算子、Prewitt算子和sobel算子


下一篇:opencv_Sobel