OpenCV Gabor滤波器实现纹理提取与缺陷分析
Posted OpenCV学堂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV Gabor滤波器实现纹理提取与缺陷分析相关的知识,希望对你有一定的参考价值。
一:Gabor滤波器介绍
Gabor滤波器是OpenCV中非常强大一种滤波器,广泛应用在纹理分割、对象检测、图像分维、文档分析、边缘检测、生物特征识别、图像编码与内容描述等方面。Gabor在空间域可以看做是一个特定频率与方向的正弦平面加上一个应用在正弦平面波上的高斯核
在实际计算中,一般情况下会根据输入的theta与lambd的不同,得到一系列的Gabor的滤波器组合,然后把它们的结果相加输出,得到最终的输出结果,在纹理提取,图像分割、纹理分类中特别有用,Gabor滤波器的任意组合提供了非常强大的图像分类能力,被认为是最接近于现代深度学习方式进行图像分类的算法之一。Gabor滤波器应用也非常广泛,几乎从图像处理、分割、分类、对象匹配、人脸识别、文字OCR等领域都有应用。
二:OpenCV中的代码实现
OpenCV中已经实现了Gabor滤波器的核函数生成,有了卷积核函数,一切都好办多啦,通过filter2D卷积函数使用Gabor核即可完成Gabor滤波,Gabor核生成的API函数与参数解释如下:
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函数的代码实现如下:
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.行车斑马线检测
斑马线图像
检测结果:
最终效果:
相关代码:
#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;
}
更多相关阅读
伏久者,飞必高
开先者,谢独早
关注【OpenCV学堂】
长按或者扫码二维码即可关注
请戳广告支持,谢谢!
【关于学堂】 - 获取作者微信联系
技术交流合作!
以上是关于OpenCV Gabor滤波器实现纹理提取与缺陷分析的主要内容,如果未能解决你的问题,请参考以下文章
youcans 的 OpenCV 例程200篇193.基于Gabor 滤波器的特征提取
youcans 的 OpenCV 例程200篇193.基于Gabor 滤波器的特征提取