一、OpenCV-Sobel边缘检测

#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>
using namespace cv;
int main()
{
Mat srcImage = imread("sobel_test01.jpg");
if (srcImage.empty())
{
printf("could not load this srcImage!\n");
return -1;
}
namedWindow("原图像", 1);
imshow("原图像", srcImage);
Mat gauImage;
GaussianBlur(srcImage, gauImage, Size(3, 3), 0, 0, 4);
Mat grayImage;
cvtColor(gauImage, grayImage, COLOR_BGR2GRAY);
namedWindow("灰度图",1);
imshow("灰度图", grayImage);
double timeStart = (double)getTickCount();
Mat xGrand, yGrand;
Sobel(grayImage, xGrand, CV_16S, 1, 0, 3);
convertScaleAbs(xGrand, xGrand);
Sobel(grayImage, yGrand, CV_16S, 0, 1, 3);
convertScaleAbs(yGrand, yGrand);
Mat dst = Mat::zeros(xGrand.size(), yGrand.type());
int colsImage = srcImage.cols;
int rowsImage = srcImage.rows;
for (int row = 0; row < rowsImage; row++) {
for (int col = 0; col < colsImage; col++) {
uchar xValue = xGrand.at<uchar>(row, col);
uchar yValue = yGrand.at<uchar>(row, col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(sqrt(xValue * xValue + yValue * yValue));
}
}
double TotalTime = ((double)getTickCount() - timeStart) / getTickFrequency();
namedWindow("x,y方向叠加的最终图像", 1);
imshow("x,y方向叠加的最终图像", dst);
printf("使用OpenCV做Sobel算子,消耗的时间:%f毫秒\n", TotalTime*1000);
waitKey(0);
return 0;
}
二、CUDA-Sobel边缘检测
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cuda.h>
#include <device_functions.h>
#include <opencv2\opencv.hpp>
#include <math.h>
#include <iostream>
using namespace cv;
__global__ void sobelInCuda(unsigned char* dataIn, unsigned char* dataOut, int imgHeight, int imgWidth)
{
int xIndex = threadIdx.x + blockDim.x * blockIdx.x;
int yIndex = threadIdx.y + blockDim.y * blockIdx.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;
}
}
int main()
{
Mat srcImg = imread("sobel_test01.jpg", 1);
if (srcImg.empty())
{
printf("could not load this srcImage!\n");
return -1;
}
namedWindow("原图像", 1);
imshow("原图像", srcImg);
Mat gauImg;
GaussianBlur(srcImg, gauImg, Size(3, 3), 0, 0, 4);
Mat grayImg;
cvtColor(gauImg, grayImg, COLOR_BGR2GRAY);
namedWindow("灰度图", 1);
imshow("灰度图", grayImg);
int imgHeight = grayImg.rows;
int imgWidth = grayImg.cols;
Mat dstGpuImg(imgHeight, imgWidth, CV_8UC1, Scalar(0, 0, 0));
size_t num = imgHeight * imgWidth * sizeof(unsigned char);
unsigned char* d_in;
unsigned char* d_out;
cudaMalloc((void**)&d_in, num);
cudaMalloc((void**)&d_out, num);
cudaMemcpy(d_in, grayImg.data, num, cudaMemcpyHostToDevice);
dim3 threadsPerBlock(32, 32);
dim3 blocksPerGrid((imgWidth + threadsPerBlock.x - 1) / threadsPerBlock.x,
(imgHeight + threadsPerBlock.y - 1) / threadsPerBlock.y);
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
sobelInCuda << <blocksPerGrid, threadsPerBlock >> > (d_in, d_out, imgHeight, imgWidth);
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
float elapsedTime;
cudaEventElapsedTime(&elapsedTime, start, stop);
cudaMemcpy(dstGpuImg.data, d_out, num, cudaMemcpyDeviceToHost);
namedWindow("CUDA_Soble的结果图像", 1);
imshow("CUDA_Soble的结果图像", dstGpuImg);
printf("使用CUDA做Sobel算子,消耗的时间:%f毫秒\n", elapsedTime);
cudaFree(d_in);
cudaFree(d_out);
cudaEventDestroy(start);
cudaEventDestroy(stop);
waitKey(0);
return 0;
}