OpenCV+CUDA学习5---Sobel算法
作者:互联网
目录
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
标签:imgWidth,Sobel,int,yIndex,---,OpenCV,cuda,include,cv 来源: https://blog.csdn.net/zhangdaoliang1/article/details/122270025