在OpenCV中测量边缘强度,梯度的大小

6
我有一个需要检查相机聚焦的应用程序。为此,我想在单轴(1D)上的几个预定义位置测量边缘强度(梯度幅值)。图像目标将是简单的黑色物体在白色背景上的印刷品。
我正在使用Python的OpenCV。我知道OpenCV中有几种边缘检测算法,如Canny、Sobel和Laplace,但所有这些都是用于过滤图像。我想要实际衡量边缘的强度。OpenCV中是否有任何算法可以提供这样的功能?或者我只需编写自己的算法来衡量边缘强度?
2个回答

6

这是一个Python版本:

def getGradientMagnitude(im):
    "Get magnitude of gradient for given image"
    ddepth = cv2.CV_32F
    dx = cv2.Sobel(im, ddepth, 1, 0)
    dy = cv2.Sobel(im, ddepth, 0, 1)
    dxabs = cv2.convertScaleAbs(dx)
    dyabs = cv2.convertScaleAbs(dy)
    mag = cv2.addWeighted(dxabs, 0.5, dyabs, 0.5, 0)
    return mag

mag = getGradientMagnitude(im)

这段代码是错误的。它计算了 0.5 * abs(dx) + 0.5 * abs(dy)。需要的是 sqrt(dx**2 + dy**2)。函数 cv2.magnitude 可以计算出这个值:mag = cv2.magnitude(dx, dy) - Cris Luengo

5

您可以按照以下步骤计算幅值:

  1. 计算 dxdy 的导数(使用 cv::Sobel
  2. 计算幅值 sqrt(dx^2 + dy^2)(使用 cv::magnitude

以下是一个简单的 C++ 代码,用于计算梯度的幅值。您可以轻松地将其移植到 Python 中,因为它只涉及几个 OpenCV 函数的调用:

#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
    //Load image
    Mat3b img = imread("path_to_image");

    //Convert to grayscale
    Mat1b gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);

    //Compute dx and dy derivatives
    Mat1f dx, dy;
    Sobel(gray, dx, CV_32F, 1, 0);
    Sobel(gray, dy, CV_32F, 0, 1);

    //Compute gradient
    Mat1f magn;
    magnitude(dx, dy, magn);

    //Show gradient
    imshow("Magnitude", magn);
    waitKey();

    return 0;
}

1
请看这里:http://answers.opencv.org/question/5395/how-to-calculate-blurriness-and-sharpness-of-a-given-image/这是关于编程的内容。 - sturkmen
@Chad 从幅度中获得的是一个与图像大小相同的矩阵。在该矩阵中的每个位置上,您都有相应的边缘强度。对该矩阵进行平均处理,将给出整个图像的平均边缘强度。 - Simon
谢谢提供的信息,我仔细审查后决定对结果进行求和。感谢 @sturkmen。 - Chad
@sturkmen 我不知道它是否在正式场合下是正确的,但是 net_force 看起来很酷 :D - Miki
1
@Miki,我找到了正确的答案calcBlurriness,详情请参见这里 - sturkmen
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接