diff --git "a/data/1.OpenCV\345\210\235\351\230\266/3.\345\233\276\345\203\217\345\242\236\345\274\272\345\222\214\346\273\244\346\263\242/4.\346\242\257\345\272\246/Gradient.md" "b/data/1.OpenCV\345\210\235\351\230\266/3.\345\233\276\345\203\217\345\242\236\345\274\272\345\222\214\346\273\244\346\263\242/4.\346\242\257\345\272\246/Gradient.md" new file mode 100644 index 0000000000000000000000000000000000000000..206fc8c370b39568c993d1661b9938a816123d39 --- /dev/null +++ "b/data/1.OpenCV\345\210\235\351\230\266/3.\345\233\276\345\203\217\345\242\236\345\274\272\345\222\214\346\273\244\346\263\242/4.\346\242\257\345\272\246/Gradient.md" @@ -0,0 +1,93 @@ +# Sobel 梯度算子 + +在图像处理中,梯度反映了像素值的最大变化率的方向,能够突出和提取边缘,常用于工业检测中产品缺陷检测和自动检测的预处理。 + +OpenCV 提供了三种梯度算子:Sobel、Scharr 和 Laplacian。Sobel 梯度算子是高斯平滑和微分求导的联合运算,抗噪声能力强。 + +Sobel 梯度算子很容易通过卷积操作 cv.filter2D 实现,OpenCV 也提供了函数 **cv.Sobel** 实现 Sobel 梯度算子。 + +**函数说明:** + +``` +cv.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst +``` + +我们用 Sobel 算子从 Lena 图像提取边缘,看看会产生什么样的效果吧。 + +![](./gradientOutput.png) + +下面对 Sobel 梯度算子实现代码正确的是? + +## 答案 + +``` +import cv2 as cv + +if __name__ == '__main__': + img = cv.imread("lena.png", flags=1) + imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) + + SobelX = cv.Sobel(imgGray, cv.CV_16S, 1, 0) # 计算 x 轴方向 + SobelY = cv.Sobel(imgGray, cv.CV_16S, 0, 1) # 计算 y 轴方向 + absX = cv.convertScaleAbs(SobelX) # 转回 uint8 + absY = cv.convertScaleAbs(SobelY) # 转回 uint8 + SobelXY = cv.addWeighted(absX, 0.5, absY, 0.5, 0) # 用绝对值近似平方根 + + cv.imshow("Sobel gradient", SobelXY) + cv.waitKey(0) +``` + +## 选项 + +### 函数 cv.Sobel() 缺少参数:数据深度 ddepth + +``` +import cv2 as cv + +if __name__ == '__main__': + img = cv.imread("lena.png", flags=1) + imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) + + SobelX = cv.Sobel(imgGray, 1, 0) + SobelY = cv.Sobel(imgGray, 0, 1) + absX = cv.convertScaleAbs(SobelX) + absY = cv.convertScaleAbs(SobelY) + SobelXY = cv.addWeighted(absX, 0.5, absY, 0.5, 0) + + cv.imshow("Sobel gradient", SobelXY) + cv.waitKey(0) +``` + +### 梯度运算结果有正负,绝对值或平方和处理后才能加权 + +``` +import cv2 as cv + +if __name__ == '__main__': + img = cv.imread("lena.png", flags=1) + imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) + + SobelX = cv.Sobel(imgGray, cv.CV_16S, 1, 0) # 计算 x 轴方向 + SobelY = cv.Sobel(imgGray, cv.CV_16S, 0, 1) # 计算 y 轴方向 + SobelXY = cv.addWeighted(SobelX, 0.5, SobelY, 0.5, 0) # 用绝对值近似平方根 + + cv.imshow("Sobel gradient", SobelXY) + cv.waitKey(0) + +``` + +### 只对 x 轴方向进行了梯度运算 + +``` +import cv2 as cv + +if __name__ == '__main__': + img = cv.imread("lena.png", flags=1) + imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) + + SobelX = cv.Sobel(imgGray, cv.CV_16S, 1, 0) # 计算 x 轴方向 + absX = cv.convertScaleAbs(SobelX) # 转回 uint8 + + cv.imshow("Sobel gradient", absX) + cv.waitKey(0) +```