OpenCV+CUDA学习5---Sobel算法
2022/1/1 20:08:21
本文主要是介绍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
3.2 opencv+cuda
这篇关于OpenCV+CUDA学习5---Sobel算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享