前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV Gabor滤波器实现纹理提取与缺陷分析

OpenCV Gabor滤波器实现纹理提取与缺陷分析

作者头像
OpenCV学堂
发布2018-07-26 10:55:04
6.2K1
发布2018-07-26 10:55:04
举报

一:Gabor滤波器介绍

Gabor滤波器是OpenCV中非常强大一种滤波器,广泛应用在纹理分割、对象检测、图像分维、文档分析、边缘检测、生物特征识别、图像编码与内容描述等方面。Gabor在空间域可以看做是一个特定频率与方向的正弦平面加上一个应用在正弦平面波上的高斯核

在实际计算中,一般情况下会根据输入的theta与lambd的不同,得到一系列的Gabor的滤波器组合,然后把它们的结果相加输出,得到最终的输出结果,在纹理提取,图像分割、纹理分类中特别有用,Gabor滤波器的任意组合提供了非常强大的图像分类能力,被认为是最接近于现代深度学习方式进行图像分类的算法之一。Gabor滤波器应用也非常广泛,几乎从图像处理、分割、分类、对象匹配、人脸识别、文字OCR等领域都有应用。

二:OpenCV中的代码实现

OpenCV中已经实现了Gabor滤波器的核函数生成,有了卷积核函数,一切都好办多啦,通过filter2D卷积函数使用Gabor核即可完成Gabor滤波,Gabor核生成的API函数与参数解释如下:

代码语言:javascript
复制
Mat cv::getGaborKernel (
Size ksize, 卷积核大小
double sigma, // 高斯方差
double theta, // 角度
double lambd, // 波长
double gamma,// 纵横比
double psi = CV_PI *0.5, // 相位差
int ktype = CV_64F // Mat数据类型
)

OpenCV中getGaborKernel函数的代码实现如下:

代码语言:javascript
复制
cv::Mat cv::getGaborKernel( Size ksize, double sigma, double theta,
                            double lambd, double gamma, double psi, int ktype )
{
    double sigma_x = sigma;
    double sigma_y = sigma/gamma;
    int nstds = 3;
    int xmin, xmax, ymin, ymax;
    double c = cos(theta), s = sin(theta);

    if( ksize.width > 0 )
        xmax = ksize.width/2;
    else
        xmax = cvRound(std::max(fabs(nstds*sigma_x*c), fabs(nstds*sigma_y*s)));

    if( ksize.height > 0 )
        ymax = ksize.height/2;
    else
        ymax = cvRound(std::max(fabs(nstds*sigma_x*s), fabs(nstds*sigma_y*c)));

    xmin = -xmax;
    ymin = -ymax;

    CV_Assert( ktype == CV_32F || ktype == CV_64F );

    Mat kernel(ymax - ymin + 1, xmax - xmin + 1, ktype);
    double scale = 1;
    double ex = -0.5/(sigma_x*sigma_x);
    double ey = -0.5/(sigma_y*sigma_y);
    double cscale = CV_PI*2/lambd;

    for( int y = ymin; y <= ymax; y++ )
        for( int x = xmin; x <= xmax; x++ )
        {
            double xr = x*c + y*s;
            double yr = -x*s + y*c;

            double v = scale*std::exp(ex*xr*xr + ey*yr*yr)*cos(cscale*xr + psi);
            if( ktype == CV_32F )
                kernel.at<float>(ymax - y, xmax - x) = (float)v;
            else
                kernel.at<double>(ymax - y, xmax - x) = v;
        }

    return kernel;
}

三:使用Gabor filter提取纹理

使用四个gabor filter实现各种纹理提取,代码实现布匹纹理检测、墙体裂纹检测、斑马线检测。先看效果:

1.布匹纹理检测

布匹纹理图像:

检测结果:

2.墙体裂纹提取

墙体裂纹图像

检测结果:

最终效果:

3.行车斑马线检测

斑马线图像

检测结果:

最终效果:

相关代码:

代码语言:javascript
复制
#include <opencv2/opencv.hpp>
#include "iostream"

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
    Mat src = imread("D:/javaopencv/texture1.png", IMREAD_GRAYSCALE); 
    namedWindow("input", CV_WINDOW_AUTOSIZE);
    imshow("input", src);
    Mat src_f;
    src.convertTo(src_f, CV_32F);

    // 参数初始化
    int kernel_size = 3;
    double sigma = 1.0, lambd = CV_PI/8, gamma = 0.5, psi = 0;
    vector<Mat> destArray;
    double theta[4];
    Mat temp;

    // theta 法线方向
    theta[0] = 0;
    theta[1] = CV_PI/4;
    theta[2] = CV_PI / 2;
    theta[3] = CV_PI - CV_PI / 4;

    // gabor 纹理检测器,可以更多,
    // filters = number of thetas * number of lambd
    // 这里lambad只取一个值,所有4个filter
    for (int i = 0; i<4; i++)
    {
        Mat kernel1;
        Mat dest;
        kernel1 = cv::getGaborKernel(cv::Size(kernel_size, kernel_size), sigma, theta[i], lambd, gamma, psi, CV_32F);
        filter2D(src_f, dest, CV_32F, kernel1);
        destArray.push_back(dest);
    }

    // 显示与保存
    Mat dst1, dst2, dst3, dst4;
    convertScaleAbs(destArray[0], dst1);
    imwrite("D:/gabor1.jpg", dst1);
    convertScaleAbs(destArray[1], dst2);
    imwrite("D:/gabor2.jpg", dst2);
    convertScaleAbs(destArray[2], dst3);
    imwrite("D:/gabor3.jpg", dst3);
    convertScaleAbs(destArray[3], dst4);
    imwrite("D:/gabor4.jpg", dst4);

    // 合并结果
    add(destArray[0], destArray[1], destArray[0]);
    add(destArray[2], destArray[3], destArray[2]);
    add(destArray[0], destArray[2], destArray[0]);
    Mat dst;
    convertScaleAbs(destArray[0], dst, 0.2, 0);

    // 二值化显示
    Mat gray, binary;
    // cvtColor(dst, gray, COLOR_BGR2GRAY);
    threshold(dst, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
    imshow("result", dst);
    imshow("binary", binary);
    imwrite("D:/result_01.png", binary);
    waitKey(0);
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二:OpenCV中的代码实现
  • 三:使用Gabor filter提取纹理
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档