sobel边缘检测
视频讲解如下:
当前系列所有demo下载地址:
https://github.com/GaoRenBao/OpenCv4-Demo
不同编程语言对应的OpenCv版本以及开发环境信息如下:
语言 | OpenCv版本 | IDE |
C# | OpenCvSharp4.4.8.0.20230708 | Visual Studio 2022 |
C++ | OpenCv-4.5.5-vc14_vc15 | Visual Studio 2022 |
Python | OpenCv-Python (4.6.0.66) | PyCharm Community Edition 2022.1.3 |
我们使用的开发环境是:Visual Studio 2019
首先需要准备一张图片1.jpg,如下

经过sobel边缘检测后的效果如下:

下面给大家演示了C#、C++、Python这三种环境下是如何进行sobel边缘检测。
C#版本代码如下:
C#版本需要安装“OpenCvSharp4”、“OpenCvSharp4.runtime.win”两个库才行。不然会报错。
如果需要使用“ BitmapConverter.ToBitmap”操作,则需要追加安装“OpenCvSharp4.Extensions”库。
using OpenCvSharp;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
Mat grad_x = new Mat();
Mat grad_y = new Mat();
Mat abs_grad_x = new Mat();
Mat abs_grad_y = new Mat();
Mat dst = new Mat();
//【1】读取图像
Mat src = Cv2.ImRead("../../../images/girl2.jpg");
//【2】显示原图
Cv2.ImShow("原图", src);
//【3】求 X方向梯度
Cv2.Sobel(src, grad_x, MatType.CV_16S, 1, 0, 3, 1, 1, BorderTypes.Default);
Cv2.ConvertScaleAbs(grad_x, abs_grad_x);
Cv2.ImShow("【效果图】 X方向Sobel", abs_grad_x);
//【4】求Y方向梯度
Cv2.Sobel(src, grad_y, MatType.CV_16S, 0, 1, 3, 1, 1, BorderTypes.Default);
Cv2.ConvertScaleAbs(grad_y, abs_grad_y);
Cv2.ImShow("【效果图】Y方向Sobel", abs_grad_y);
//【5】合并梯度(近似)
Cv2.AddWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
Cv2.ImShow("【效果图】整体方向Sobel", dst);
Cv2.ImShow("效果", dst);
Cv2.WaitKey(0);
//【6】在pictureBox1中显示效果图
//Bitmap map = BitmapConverter.ToBitmap(dst);
//pictureBox1.Image = map;
}
}
}
C++版本代码如下:
#include <vector>
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
//【0】创建 grad_x 和 grad_y 矩阵
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y, dst;
//【1】载入原始图
Mat src = imread("../images/girl2.jpg");
//【2】显示原始图
imshow("【原始图】sobel边缘检测", src);
//【3】求 X方向梯度
Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);
imshow("【效果图】 X方向Sobel", abs_grad_x);
//【4】求Y方向梯度
Sobel(src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y);
imshow("【效果图】Y方向Sobel", abs_grad_y);
//【5】合并梯度(近似)
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
imshow("【效果图】整体方向Sobel", dst);
waitKey(0);
return 0;
}
Python版本代码如下:
import cv2
import numpy as np
img = cv2.imread("1.jpg")
# 第一个参数:需要处理的图像;
# 第二个参数:是图像的深度,-1表示采用的是与原图像相同的深度,设定为 CV_16S 避免外溢。目标图像的深度必须大于等于原图像的深度;
# 第三个参数:dx方向求导,0表示这个方向上没有求导,一般为0、1、2。
# 第四个参数:dy方向求导,0表示这个方向上没有求导,一般为0、1、2。
# 第五个参数:dst不用解释了;
# 第六个参数:ksize是Sobel算子的大小,必须为1、3、5、7。
# 第七个参数:scale是缩放导数的比例常数,默认情况下没有伸缩系数;
# 第八个参数:delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;
# 第九个参数:borderType是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。
x = cv2.Sobel(img,cv2.CV_16S,1,0,None,3,1,cv2.BORDER_DEFAULT)
y = cv2.Sobel(img,cv2.CV_16S,0,1,None,3,1,cv2.BORDER_DEFAULT)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
dst = cv2.addWeighted(absX,0.5,absY,0.5,0)
cv2.imshow("absX", absX)
cv2.imshow("absY", absY)
cv2.imshow("Result", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()