Sobel算子->方向滤波

索贝尔算子(Sobel operator
在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量,主要用作边缘检测,可被认为是图像在垂直和水平方向变化的测量。

注意:
①观察灰度分布来描述一幅图像成为空间域,观察图像变化的频率被成为频域。
②频域分析:低频对应区域的图像强度变化缓慢,高频对应的变化快。低通滤波器去除了图像的高频部分,高通滤波器去除了图像的低频部分。
两组3x3的矩阵,分别为横向及纵向

这里的卷积因子是卷积神经的一个小知识点就是以卷积因子为标本去对比总样本中的数据,如图卷积因子的工作原理

具体计算
将卷积因子与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:
Gx = (-1)f(x-1, y-1) + 0f(x,y-1) + 1f(x+1,y-1)
+(-2)f(x-1,y) + 0f(x,y)+2f(x+1,y)
+(-1)f(x-1,y+1) + 0f(x,y+1) + 1
f(x+1,y+1)
= [f(x+1,y-1)+2f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)]*

Gy =1 f(x-1, y-1) + 2f(x,y-1)+ 1f(x+1,y-1)
+0f(x-1,y) 0f(x,y) + 0*f(x+1,y)
+(-1)*f(x-1,y+1) + (-2)f(x,y+1) + (-1)f(x+1, y+1)
= [f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1)]-[f(x-1, y+1) + 2
f(x,y+1)+f(x+1,y+1)]

其中f(a,b), 表示图像(a,b)点的灰度值;
图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:
在这里插入图片描述
通常,为了提高效率 使用不开平方的近似值:
在这里插入图片描述
如果梯度G大于某一阀值 则认为该点(x,y)为边缘点。

然后可用以下公式计算梯度方向:
在这里插入图片描述

代码
大致了解了Sobel算子的原理,我们来看一下在OpenCV中的使用方法:

#include <iostream>
#include <iomanip>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "laplacianZC.h"

int main()
{
     //读取图像
    cv::Mat image= cv::imread("boldt.jpg",0);
    if (!image.data)
        return 0; 

    // 展示读入的图像
    cv::namedWindow("Original Image");
    cv::imshow("Original Image",image);

    // 计算 Sobel X 导数
    cv::Mat sobelX;
    cv::Sobel(image,sobelX,CV_8U,1,0,3,0.4,128);

    // 显示图像
    cv::namedWindow("Sobel X Image");
    cv::imshow("Sobel X Image",sobelX);

    // 计算 Sobel Y 导数
    cv::Mat sobelY;
    cv::Sobel(image,sobelY,CV_8U,0,1,3,0.4,128);

    // 显示图像
    cv::namedWindow("Sobel Y Image");
    cv::imshow("Sobel Y Image",sobelY);

    //  计算sobel的摸
    cv::Sobel(image,sobelX,CV_16S,1,0);
    cv::Sobel(image,sobelY,CV_16S,0,1);
    cv::Mat sobel;
    //compute the L1 norm
    sobel= abs(sobelX)+abs(sobelY);

    double sobmin, sobmax;
    cv::minMaxLoc(sobel,&sobmin,&sobmax);
    std::cout << "sobel value range: " << sobmin << "  " << sobmax << std::endl;

    // 打印窗口像素值
    for (int i=0; i<12; i++) {
        for (int j=0; j<12; j++)
            std::cout << std::setw(5) << static_cast<int>(sobel.at<short>(i+135,j+362)) << " ";
        std::cout << std::endl;
    }
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << std::endl;

    // 转换为8位图像
    // sobelImage = -alpha*sobel + 255
    cv::Mat sobelImage;
    sobel.convertTo(sobelImage,CV_8U,-255./sobmax,255);

    // 显示图像
    cv::namedWindow("Sobel Image");
    cv::imshow("Sobel Image",sobelImage);

    // 对Sobel norm应用阈值(低阈值)
    cv::Mat sobelThresholded;
    cv::threshold(sobelImage, sobelThresholded, 225, 255, cv::THRESH_BINARY);

    // 显示图像
    cv::namedWindow("Binary Sobel Image (low)");
    cv::imshow("Binary Sobel Image (low)",sobelThresholded);

    // 对Sobel norm应用阈值(高阈值)
    cv::threshold(sobelImage, sobelThresholded, 190, 255, cv::THRESH_BINARY);

    // 显示图像
    cv::namedWindow("Binary Sobel Image (high)");
    cv::imshow("Binary Sobel Image (high)",sobelThresholded);

参考文章:
OpenCV入门
Sobel算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值