梯度方向和梯度幅度是多少? [英] What is the gradient orientation and gradient magnitude?

查看:230
本文介绍了梯度方向和梯度幅度是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究计算机视觉中称为边缘检测的模块. 我正在尝试理解梯度方向和梯度幅度的含义.

I am currently studying a module in computer vision called edge detection. I am trying to understand the meaning of gradient orientation and gradient magnitude.

推荐答案

Dima 在其答案,您应该熟悉

As explained by Dima in his answer, you should be familiar with the mathematical concept of gradient in order to better understand the gradient in the field of image processing.

我的答案基于问题.

My answer is based on the answer of mevatron to this question.

在这里您可以找到黑色背景上白色磁盘的简单初始图像:

Here you find a simple initial image of a white disk on a black background:

您可以计算出此图像的梯度的近似值.正如迪玛(Dima)在他的回答中所解释的那样,渐变包含两个部分,水平和垂直部分.

you can compute an approximation of the gradient of this image. As Dima explained in his answer, you have two component of the gradient, an horizontal and a vertical component.

下图显示了水平分量:

它显示图像的灰度在水平方向上发生了多少变化(正x方向,从左向右扫描图像),该变化被编码"在图像的灰度中水平分量:平均灰度等级表示没有变化,明亮等级表示从暗值到明亮值的变化,暗等级表示从亮值到暗值的变化.因此,在上面的图像中,您会在圆的左侧看到较亮的值,因为在初始图像的左侧,您具有从黑到白的过渡,从而为磁盘提供了左侧边缘.类似地,在上图中,您会在圆的右侧看到较暗的值,因为在初始图像的右侧,您具有从白到黑的过渡,从而为磁盘提供了右边缘.在上图中,磁盘的内部和背景处于平均灰度级别,因为磁盘内部和背景没有变化.

it shows how much the gray levels in your image change in the horizontal direction (it is the direction of positive x, scanning the image from left to right), this change is "encoded" in the grey level of the image of the horizontal component: the mean grey level means no change, the bright levels mean change from a dark value to a bright value, the dark levels mean a change from a bright value to a dark value. So, in the above image you see the brighter value in the left part of the circle because it is in the left part of the initial image that you have the black to white transition that gives you the left edge of the disk; similarly, in the above image you see the darker value in the right part of the circle because it is in the right part of the initial image that you have the white to black transition that gives you the right edge of the disk. In the above image, the inner part of the disk and the background are at a mean grey level because there is no change inside the disk and in the background.

我们可以对垂直分量进行类似的观察,它可以显示图像在垂直方向上的变化,即从顶部到底部扫描图像:

We can make analogous observations for the vertical component, it shows how the image change in the vertical direction, i.e. scanning the image from the top to the bottom:

您现在可以结合使用这两个分量以获得梯度的大小和梯度的方向.

You can now combine the two components in order to get the magnitude of the gradient and the orientation of the gradient.

以下图像是梯度的大小:

The following image is the magnitude of the gradient:

同样,在上面的图像中,初始图像的变化以灰度级编码:在这里您可以看到白色表示初始图像的变化很大,而黑色则意味着完全没有变化. 因此,当您查看渐变幅度的图像时,您可以说:如果图像较亮,则表示初始图像有很大变化;如果图像较暗,则表示没有变化或变化很小".

Again, in the above image the change in initial image is encoded in the gray level: here you see that white means an high change in the initial image while black means no change at all. So, when you look at the image of the magnitude of the gradient you can say "if the image is bright it means a big change in the initial image; if it is dark it means no change or very llittle change".

以下图像是渐变的方向:

The following image is the orientation of the gradient:

在上面的图像中,方向再次被编码为灰度级:您可以将方向视为箭头,即从图像的暗部分指向图像的亮部分的角度;角度称为xy框架,其中x从左到右,而y从上到下.在上图中,您可以看到从黑色(零度)到白色(360度)的所有灰度级.我们可以用颜色对信息进行编码:

In the above image the orientation is again encoded as gray levels: you can think at the orientation as the angle of an arrow pointing from the the dark part of the image to the bright part of the image; the angle is referred to an xy frame where the x runs from left to right while the y runs from top to bottom. In the above image you see all the grey level from the black (zero degree) to the white (360 degree). We can encode the information with color:

在上图中,信息是以这种方式编码的:

in the above image the information is encode in this way:

红色:角度在0到90度之间

red: the angle is between 0 and 90 degree

青色:角度在90至180度之间

cyan: the angle is between 90 and 180 degree

绿色:角度在180度到270度之间

green: the angle is between 180 and 270 degree

黄色:角度在270至360度之间

yellow: the angle is between 270 and 360 degree

这是用于生成上述图像的C ++ OpenCV代码.

Here it is the C++ OpenCV code for producing the above images.

请注意以下事实:为了计算方向,我使用了功能 doc 所述a>,当梯度的垂直分量和水平分量都为零时,角度为0;这可能很方便,但是从数学的角度来看,这显然是错误的,因为当两个分量都为零时,未定义方向,并且对于浮点C ++类型中保持的方向唯一有意义的值是NaN.

Pay attention to the fact that, for the computation of the orientation, I use the function cv::phase which, as explained in the doc, gives an angle of 0 when both the vertical component and the horizontal component of the gradient are zero; that may be convenient but from a mathematical point of view is plainly wrong because when both components are zero the orientation is not defined and the only meaningful value for an orientation kept in a floating-point C++ type is a NaN.

这是完全错误的,因为例如0度方向已经与水平边缘相关,并且不能用于表示其他内容,例如没有边缘的区域,因此没有方向的区域.

It is plainly wrong because a 0 degree orientation, for example, is already related to an horizontal edge and it cannot be used to represent something else like a region with no edges and so a region where orientation is meaningless.

// original code by https://stackoverflow.com/users/951860/mevatron
// see https://stackoverflow.com/a/11157426/15485
// https://stackoverflow.com/users/15485/uvts-cvs added the code for saving x and y gradient component 

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

Mat mat2gray(const cv::Mat& src)
{
    Mat dst;
    normalize(src, dst, 0.0, 255.0, cv::NORM_MINMAX, CV_8U);

    return dst;
}

Mat orientationMap(const cv::Mat& mag, const cv::Mat& ori, double thresh = 1.0)
{
    Mat oriMap = Mat::zeros(ori.size(), CV_8UC3);
    Vec3b red(0, 0, 255);
    Vec3b cyan(255, 255, 0);
    Vec3b green(0, 255, 0);
    Vec3b yellow(0, 255, 255);
    for(int i = 0; i < mag.rows*mag.cols; i++)
    {
        float* magPixel = reinterpret_cast<float*>(mag.data + i*sizeof(float));
        if(*magPixel > thresh)
        {
            float* oriPixel = reinterpret_cast<float*>(ori.data + i*sizeof(float));
            Vec3b* mapPixel = reinterpret_cast<Vec3b*>(oriMap.data + i*3*sizeof(char));
            if(*oriPixel < 90.0)
                *mapPixel = red;
            else if(*oriPixel >= 90.0 && *oriPixel < 180.0)
                *mapPixel = cyan;
            else if(*oriPixel >= 180.0 && *oriPixel < 270.0)
                *mapPixel = green;
            else if(*oriPixel >= 270.0 && *oriPixel < 360.0)
                *mapPixel = yellow;
        }
    }

    return oriMap;
}

int main(int argc, char* argv[])
{
    Mat image = Mat::zeros(Size(320, 240), CV_8UC1);
    circle(image, Point(160, 120), 80, Scalar(255, 255, 255), -1, CV_AA);

    imshow("original", image);

    Mat Sx;
    Sobel(image, Sx, CV_32F, 1, 0, 3);

    Mat Sy;
    Sobel(image, Sy, CV_32F, 0, 1, 3);

    Mat mag, ori;
    magnitude(Sx, Sy, mag);
    phase(Sx, Sy, ori, true);

    Mat oriMap = orientationMap(mag, ori, 1.0);

    imshow("x", mat2gray(Sx));
    imshow("y", mat2gray(Sy));

    imwrite("hor.png",mat2gray(Sx));
    imwrite("ver.png",mat2gray(Sy));

    imshow("magnitude", mat2gray(mag));
    imshow("orientation", mat2gray(ori));
    imshow("orientation map", oriMap);
    waitKey();

    return 0;
}

这篇关于梯度方向和梯度幅度是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆