一、OpenCV-Sobel边缘检测

#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>using namespace cv;/*OpenCV中的namedWindow函数WINDOW_NORMAL    显示图像后,允许用户随意调整窗口大小WINDOW_AUTOSIZE    根据图像大小显示窗口,不允许用户调整大小(默认)WINDOW_FREERATIO   窗口大小自适应比例WINDOW_KEEPRATIO   保持图像的比例*/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);//-----------------OpenCV-Sobel边缘检测--------------------double timeStart = (double)getTickCount();//程序计时-开始时间Mat xGrand, yGrand;/*x方向的一阶边缘检测—水平梯度Gx*/Sobel(grayImage, xGrand, CV_16S, 1, 0, 3);convertScaleAbs(xGrand, xGrand);/*y方向的一阶边缘检测—垂直梯度Gy*/Sobel(grayImage, yGrand, CV_16S, 0, 1, 3);convertScaleAbs(yGrand, yGrand);/*叠加x,y方向的边缘—最终图像梯度G*/Mat dst = Mat::zeros(xGrand.size(), yGrand.type());//根据公式,使用勾股定理求出图像近似梯度Gint 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);//imwrite("finalImage.jpg", dst);//导出最终图像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;/*OpenCV中的namedWindow函数WINDOW_NORMAL 显示图像后,允许用户随意调整窗口大小WINDOW_AUTOSIZE    根据图像大小显示窗口,不允许用户调整大小(默认)WINDOW_FREERATIO   窗口大小自适应比例WINDOW_KEEPRATIO   保持图像的比例*///-------------------------------------------------------------------------------------------------
//             x0 x1 x2
//             x3 x4 x5
//             x6 x7 x8
// GPU实现Sobel边缘检测,Sobel算子边缘检测核函数
//-------------------------------------------------------------------------------------------------
__global__ void sobelInCuda(unsigned char* dataIn, unsigned char* dataOut, int imgHeight, int imgWidth)
{int xIndex = threadIdx.x + blockDim.x * blockIdx.x;//X方向的线程索引int yIndex = threadIdx.y + blockDim.y * blockIdx.y;//Y方向的线程索引int index = yIndex * imgWidth + xIndex;//一维的全局索引int Gx = 0;int Gy = 0;//unsigned char x0, x1, x2, x3, x4, x5, x6, x7, x8;if (xIndex > 0 && xIndex < imgWidth - 1 && yIndex > 0 && yIndex < imgHeight - 1)//防止索引越界{//水平方向的边缘检测—计算图像水平梯度GxGx = 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]);//垂直方向的边缘检测—计算图像垂直梯度GyGy = 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]);//根据公式,求出最终的图像梯度GdataOut[index] = (abs(Gx) + abs(Gy)) / 2;以x4为中心,寻找其他像素点的坐标位置//x0 = dataIn[(yIndex - 1) * imgWidth + xIndex - 1];//x1 = dataIn[(yIndex - 1) * imgWidth + xIndex];//x2 = dataIn[(yIndex - 1) * imgWidth + xIndex + 1];//x3 = dataIn[(yIndex)*imgWidth + xIndex - 1];//x4 = dataIn[(yIndex)*imgWidth + xIndex];//x5 = dataIn[(yIndex)*imgWidth + xIndex + 1];//x6 = dataIn[(yIndex + 1) * imgWidth + xIndex - 1];//x7 = dataIn[(yIndex + 1) * imgWidth + xIndex];//x8 = dataIn[(yIndex + 1) * imgWidth + xIndex + 1];//水平方向的边缘检测—计算图像水平梯度Gx//Gx = (x0 + 2 * x3 + x6) - (x2 + 2 * x5 + x8);//垂直方向的边缘检测—计算图像垂直梯度Gy//Gy = (x0 + 2 * x1 + x2) - (x6 + 2 * x7 + x8);//根据公式,求出最终的图像梯度G//dataOut[index] = (abs(Gx) + abs(Gy)) / 2;//printf("out[%d]: %d", index, out[index]);}
}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);//-----------------使用CUDA进行Sobel边缘检测--------------------int imgHeight = grayImg.rows;int imgWidth = grayImg.cols;//使用CUDA进行Sobel边缘检测的最终结果图像Mat dstGpuImg(imgHeight, imgWidth, CV_8UC1, Scalar(0, 0, 0));//创建GPU内存,申请指针并将它指向GPU空间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);//--------------将灰度图像从CPU传输到GPU---------------------cudaMemcpy(d_in, grayImg.data, num, cudaMemcpyHostToDevice);//-----------------定义CUDA中grid和block的维度---------------dim3 threadsPerBlock(32, 32);dim3 blocksPerGrid((imgWidth + threadsPerBlock.x - 1) / threadsPerBlock.x,(imgHeight + threadsPerBlock.y - 1) / threadsPerBlock.y);//--------------------记录核函数起始时间---------------------//double timeStart = (double)getTickCount();//程序计时-开始时间cudaEvent_t start, stop;cudaEventCreate(&start);cudaEventCreate(&stop);cudaEventRecord(start, 0);//避免gpu线程没有完全执行结束//--------------------调用在GPU上运行的核函数--------------------//sobelInCuda<<<每个Grid中的block数,每个block中的thread数>>>//每个thread都会执行核函数sobelInCuda << <blocksPerGrid, threadsPerBlock >> > (d_in, d_out, imgHeight, imgWidth);//-------------------记录核函数结束时间-------------------cudaEventRecord(stop, 0);cudaEventSynchronize(stop);float elapsedTime;cudaEventElapsedTime(&elapsedTime, start, stop);//--------------------将计算以后的图像传回到CPU内存--------------------//double TotalTime = ((double)getTickCount() - timeStart) / getTickFrequency();//程序计时-结束时间cudaMemcpy(dstGpuImg.data, d_out, num, cudaMemcpyDeviceToHost);//------------------------显示处理结果-------------------------namedWindow("CUDA_Soble的结果图像", 1);imshow("CUDA_Soble的结果图像", dstGpuImg);printf("使用CUDA做Sobel算子,消耗的时间:%f毫秒\n", elapsedTime);//printf("使用CUDA做Sobel算子,消耗的时间:%f毫秒\n", TotalTime*1000);//imwrite("finalImage.jpg", dstGpuImg);//导出最终图像//-------------------------释放GPU内存-------------------------cudaFree(d_in);cudaFree(d_out);//-------------------------释放CUDA计时内存--------------------cudaEventDestroy(start);cudaEventDestroy(stop);waitKey(0);return 0;
}

OpenCV/CUDA—Sobel边缘检测相关推荐

  1. C/C++ OpenCV之Sobel边缘检测

    Void Sobel( outputArray src, int depth, int dx, int dy, int ksize=3, double scale=1, double delat=0, ...

  2. opencv图像处理之边缘检测

    边缘检测 1 原理 边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点.图像属性中的显著变化通常反映了属性的重要事件和变化. 图像边缘检测大幅度地减少了数据量, ...

  3. OpenCV使用Sobel或Scharr OpenCV函数进行边缘检测的实例(附完整代码)

    OpenCV使用Sobel或Scharr OpenCV函数进行边缘检测的实例 OpenCV使用Sobel或Scharr OpenCV函数进行边缘检测的实例 OpenCV使用Sobel或Scharr O ...

  4. opencv:卷积涉及的基础概念,Sobel边缘检测代码实现及卷积填充模式

    具体参考我的另一篇文章: opencv:卷积涉及的基础概念,Sobel边缘检测代码实现及Same(相同)填充与Vaild(有效)填充 这里是对这一篇文章的补充! 卷积-三种填充模式 橙色部分为imag ...

  5. Sobel边缘检测算法及OpenCV函数实现

    转自https://www.cnblogs.com/herenzhiming/articles/6526741.html  https://blog.csdn.net/qaz_wz/article/d ...

  6. CUDA:实现Sobel边缘检测滤波器的实例

    CUDA:实现Sobel边缘检测滤波器的实例 FunctionPointers_kernels.h FunctionPointers.cpp FunctionPointers_kernels.cu F ...

  7. OpenCV Sobel 边缘检测

    Sobel算子检测方法对灰度渐变和噪声较多的图像处理效果较好,sobel算子对边缘定位不是很准确,图像的边缘不止一个像素:当对精度要求不是很高时,是一种较为常用的边缘检测方法. OpenCV中sobe ...

  8. 【opencv初学者】3、sobel边缘检测

    #include <vector> #include <stdio.h> #include <opencv2/opencv.hpp>using namespace ...

  9. OpenCV入门系列 —— Sobel边缘检测

    OpenCV入门系列 -- Sobel边缘检测 前言 程序说明 输出结果 代码示例 总结 前言 随着工业自动化.智能化的不断推进,机器视觉(2D/3D)在工业领域的应用和重要程度也同步激增(识别.定位 ...

最新文章

  1. linux学习治疗,这时代,医生都用VR帮你看病了!
  2. python3中的一些小改动
  3. matlab 老照片处理,matlab实现PS算法之百叶窗、老照片
  4. 电商巨头纷纷入场中国农民丰收节交易会 谋定产销对接活动
  5. 封装SQLDMO操作的类
  6. Android压缩文件(压缩目录)
  7. im4java profile_GraphicsMagick+im4java
  8. python 基础 list和 tuple dict和set
  9. nodejs对mongodb数据库的增删改查操作(转载)
  10. 笑联 x mPaaS | 12 个模块,全面小程序化,如何打造真正的一次开发复用多端?
  11. PHP常量:define和const的不同之处
  12. Google在东京召开了一场AI座谈会
  13. HttpClient 发送请求和参数
  14. 计算机组成与系统 报告,计算机组成与系统结构课设报告.docx
  15. SQLITE3 使用总结
  16. 如何让不给听得ge乖乖听话?python教你如何做...
  17. 第三章第九题(商业:检验ISBN-10)((Business: check ISBN-10))
  18. 如果不能产生价值,阅读便毫无意义
  19. SpringBoot实现微信登录
  20. 中国地区NPM使用可能最快的方法-记mirror-config-china的使用

热门文章

  1. 朝鲜扔导弹那天,我们去了趟板门店
  2. linux 安装报错 make FORCE_UNSAFE_CONFIGURE=1
  3. QT编程:复选框QCheckBox
  4. 个人练习代码库/ColorMatrix/色调、饱和度、亮度调整
  5. SSH1和SSH2区别
  6. 【Web3】Web3连接到以太坊网络(测试网、主网)
  7. 洲际酒店集团加码战略布局华南地区建设;冲浪热门目的地民宿搜索量翻四番 | 全球旅报...
  8. 提高店铺全重的方法,根据店铺权重为店铺引流
  9. 【wikioi】1033 蚯蚓的游戏问题(费用流)
  10. 主分区转换成逻辑分区需要多久