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

Posted OpenCV学堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV Gabor滤波器实现纹理提取与缺陷分析相关的知识,希望对你有一定的参考价值。

一:Gabor滤波器介绍

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

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

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

二:OpenCV中的代码实现

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

 
   
   
 
  1. Mat cv::getGaborKernel (

  2. Size ksize, 卷积核大小

  3. double sigma, // 高斯方差

  4. double theta, // 角度

  5. double lambd, // 波长

  6. double gamma,// 纵横比

  7. double psi = CV_PI *0.5, // 相位差

  8. int ktype = CV_64F // Mat数据类型

  9. )

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

 
   
   
 
  1. cv::Mat cv::getGaborKernel( Size ksize, double sigma, double theta,

  2.                            double lambd, double gamma, double psi, int ktype )

  3. {

  4.    double sigma_x = sigma;

  5.    double sigma_y = sigma/gamma;

  6.    int nstds = 3;

  7.    int xmin, xmax, ymin, ymax;

  8.    double c = cos(theta), s = sin(theta);

  9.    if( ksize.width > 0 )

  10.        xmax = ksize.width/2;

  11.    else

  12.        xmax = cvRound(std::max(fabs(nstds*sigma_x*c), fabs(nstds*sigma_y*s)));

  13.    if( ksize.height > 0 )

  14.        ymax = ksize.height/2;

  15.    else

  16.        ymax = cvRound(std::max(fabs(nstds*sigma_x*s), fabs(nstds*sigma_y*c)));

  17.    xmin = -xmax;

  18.    ymin = -ymax;

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

  20.    Mat kernel(ymax - ymin + 1, xmax - xmin + 1, ktype);

  21.    double scale = 1;

  22.    double ex = -0.5/(sigma_x*sigma_x);

  23.    double ey = -0.5/(sigma_y*sigma_y);

  24.    double cscale = CV_PI*2/lambd;

  25.    for( int y = ymin; y <= ymax; y++ )

  26.        for( int x = xmin; x <= xmax; x++ )

  27.        {

  28.            double xr = x*c + y*s;

  29.            double yr = -x*s + y*c;

  30.            double v = scale*std::exp(ex*xr*xr + ey*yr*yr)*cos(cscale*xr + psi);

  31.            if( ktype == CV_32F )

  32.                kernel.at<float>(ymax - y, xmax - x) = (float)v;

  33.            else

  34.                kernel.at<double>(ymax - y, xmax - x) = v;

  35.        }

  36.    return kernel;

  37. }

三:使用Gabor filter提取纹理

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

1.布匹纹理检测

布匹纹理图像:

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

检测结果:

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

2.墙体裂纹提取

墙体裂纹图像

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

检测结果:

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

最终效果:

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

3.行车斑马线检测

斑马线图像

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

检测结果:

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

最终效果:

相关代码:

 
   
   
 
  1. #include <opencv2/opencv.hpp>

  2. #include "iostream"

  3. using namespace cv;

  4. using namespace std;

  5. int main(int argc, char** argv) {

  6.    Mat src = imread("D:/javaopencv/texture1.png", IMREAD_GRAYSCALE);

  7.    namedWindow("input", CV_WINDOW_AUTOSIZE);

  8.    imshow("input", src);

  9.    Mat src_f;

  10.    src.convertTo(src_f, CV_32F);

  11.    // 参数初始化

  12.    int kernel_size = 3;

  13.    double sigma = 1.0, lambd = CV_PI/8, gamma = 0.5, psi = 0;

  14.    vector<Mat> destArray;

  15.    double theta[4];

  16.    Mat temp;

  17.    // theta 法线方向

  18.    theta[0] = 0;

  19.    theta[1] = CV_PI/4;

  20.    theta[2] = CV_PI / 2;

  21.    theta[3] = CV_PI - CV_PI / 4;

  22.    // gabor 纹理检测器,可以更多,

  23.    // filters = number of thetas * number of lambd

  24.    // 这里lambad只取一个值,所有4个filter

  25.    for (int i = 0; i<4; i++)

  26.    {

  27.        Mat kernel1;

  28.        Mat dest;

  29.        kernel1 = cv::getGaborKernel(cv::Size(kernel_size, kernel_size), sigma, theta[i], lambd, gamma, psi, CV_32F);

  30.        filter2D(src_f, dest, CV_32F, kernel1);

  31.        destArray.push_back(dest);

  32.    }

  33.    // 显示与保存

  34.    Mat dst1, dst2, dst3, dst4;

  35.    convertScaleAbs(destArray[0], dst1);

  36.    imwrite("D:/gabor1.jpg", dst1);

  37.    convertScaleAbs(destArray[1], dst2);

  38.    imwrite("D:/gabor2.jpg", dst2);

  39.    convertScaleAbs(destArray[2], dst3);

  40.    imwrite("D:/gabor3.jpg", dst3);

  41.    convertScaleAbs(destArray[3], dst4);

  42.    imwrite("D:/gabor4.jpg", dst4);

  43.    // 合并结果

  44.    add(destArray[0], destArray[1], destArray[0]);

  45.    add(destArray[2], destArray[3], destArray[2]);

  46.    add(destArray[0], destArray[2], destArray[0]);

  47.    Mat dst;

  48.    convertScaleAbs(destArray[0], dst, 0.2, 0);

  49.    // 二值化显示

  50.    Mat gray, binary;

  51.    // cvtColor(dst, gray, COLOR_BGR2GRAY);

  52.    threshold(dst, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

  53.    imshow("result", dst);

  54.    imshow("binary", binary);

  55.    imwrite("D:/result_01.png", binary);

  56.    waitKey(0);

  57.    return 0;

  58. }

更多相关阅读







伏久者,飞必高

开先者,谢独早


关注【OpenCV学堂】

长按或者扫码二维码即可关注

请戳广告支持,谢谢!

【关于学堂】 - 获取作者微信联系

技术交流合作!


以上是关于OpenCV Gabor滤波器实现纹理提取与缺陷分析的主要内容,如果未能解决你的问题,请参考以下文章

Gabor滤波器与特征提取

youcans 的 OpenCV 例程200篇193.基于Gabor 滤波器的特征提取

youcans 的 OpenCV 例程200篇193.基于Gabor 滤波器的特征提取

利用Gabor变换法分析纹理图像 matlab代码实现

图像增强基于粒子群算法优化gabor滤波器实现图像增强matlab源码

智能识别系统设计---图像特征提取