我将 openCV 中的内置 Sobel 边缘运算用于某些图像处理目的,但结果与该函数的预期不符。
sobel=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
cv2.imshow('Sobel Image',sobel)
我附上了输入图像的示例图像和我得到的结果输出。请帮助我解决这个问题。左边是输入图像,右边是结果图像。
我将 openCV 中的内置 Sobel 边缘运算用于某些图像处理目的,但结果与该函数的预期不符。
sobel=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
cv2.imshow('Sobel Image',sobel)
我附上了输入图像的示例图像和我得到的结果输出。请帮助我解决这个问题。左边是输入图像,右边是结果图像。
您必须进行两次 sobel 操作并将它们混合。另外,请确保您正在处理灰度图像,否则我认为它会分别处理每个通道..
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
grad_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
grad_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
grad = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)
cv2.imshow('grad X',grad_x)
cv2.imshow('grad Y',grad_y)
cv2.imshow('Sobel Image',grad)
cv2.waitKey()
和混合图像的结果是x
:y
如果您需要减少噪音,您可以应用高斯模糊。参考:https ://docs.opencv.org/4.2.0/d2/d2c/tutorial_sobel_derivatives.html
Sobel 算子为您提供 x 或 y 方向的梯度。对于基于 Sobel 的边缘检测,您将梯度的大小与阈值进行比较,以确定哪些像素是边缘。下面的代码显示了如何计算梯度(幅度)并将其标准化显示。
import cv2
import numpy as np
def sobel_edge_detector(img):
grad_x = cv2.Sobel(img, cv2.CV_64F, 1, 0)
grad_y = cv2.Sobel(img, cv2.CV_64F, 0, 1)
grad = np.sqrt(grad_x**2 + grad_y**2)
grad_norm = (grad * 255 / grad.max()).astype(np.uint8)
cv2.imshow('Edges', grad_norm)
cv2.waitKey(0)
注意:OpenCV 的Sobel Derivatives 教程页面使用以下计算,但它们都不正确。
// converting back to CV_8U
convertScaleAbs(grad_x, abs_grad_x);
convertScaleAbs(grad_y, abs_grad_y);
...
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
对于此图像,您需要在使用 Sobel 算子之前对图像进行阈值处理以降低噪声。
image = cv2.imread('image.jpg',cv2.IMREAD_UNCHANGED)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
H = cv2.Sobel(binary, cv2.CV_8U, dx=0, dy=1, ksize=3)
V = cv2.Sobel(binary, cv2.CV_8U, dx=1, dy=0, ksize=3)