• OpenCV图像纹理


    LBP描述

    LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;它具有旋转不变性和灰度不变性等显著的优点。它是首先由T. Ojala, M.Pietikäinen, 和D. Harwood 在1994年提出,用于纹理特征提取。而且,提取的特征是图像的局部的纹理特征

    计算过程 

    原始的LBP算子定义为在3\*3的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3\*3邻域内的8个点经比较可产生8位二进制数(通常转换为十进制数即LBP码,共256种),即得到该窗口中心像素点的LBP值,并用这个值来反映该区域的纹理信息。数学表达式方式如下图所示

    70f436408cb74b9a9e4812ab38623f9c.webp

     上述表述可能会比较抽象,接下来我们举一个例子表述 一下:

    36d6c7fce56e48cb8880d94a03a4310f.webp 

    代码实现

    1. class LBP
    2. {
    3. public:
    4. LBP(string url = "mm.jpg") :img(imread(url, IMREAD_GRAYSCALE))
    5. {
    6. result["img"] = img;
    7. }
    8. void GetLBP()
    9. {
    10. result["LBP"] = Mat::zeros(img.rows - 2, img.cols - 2, CV_8UC1);
    11. for (int i = 1; i < img.rows - 1; i++)
    12. {
    13. for (int j = 1; j < img.cols - 1; j++)
    14. {
    15. uchar temp = img.at(i, j);
    16. uchar color = 0;
    17. color |= (img.at(i - 1, j - 1) > temp) << 7;
    18. color |= (img.at(i - 1, j) > temp) << 6;
    19. color |= (img.at(i - 1, j + 1) > temp) << 5;
    20. color |= (img.at(i, j + 1) > temp) << 4;
    21. color |= (img.at(i+1, j + 1) > temp) << 3;
    22. color |= (img.at(i+1, j) > temp) << 2;
    23. color |= (img.at(i+1, j - 1) > temp) << 1;
    24. color |= (img.at(i, j - 1) > temp) << 0;
    25. result["LBP"].at(i - 1, j - 1) = color;
    26. }
    27. }
    28. }
    29. void Show()
    30. {
    31. for (auto v : result)
    32. {
    33. imshow(v.first, v.second);
    34. }
    35. waitKey(0);
    36. }
    37. protected:
    38. map result;
    39. Mat img;
    40. };

     214a5f7746aa4b7499ff86a167f1bba9.webp

    SIFT特征检测

    尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由 David Lowe在1999年所发表,2004年完善总结。 其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。

    SIFT算法是为了解决图片的匹配问题,想要从图像中提取一种对图像的大小和旋转变化保持鲁棒的特征,从而实现匹配。这一算法的灵感也十分的直观:人眼观测两张图片是否匹配时会注意到其中的典型区域(特征点部分),如果我们能够实现这一特征点区域提取过程,再对所提取到的区域进行描述就可以实现特征匹配了。

     

    SIFT算法大致流程

    高斯金字塔

    • 人看物体时近大远小,可以对图片下采样实现
    • 远处模糊,可以对图像高斯平滑实现

     

    高斯差分金字塔特征提取

    • 获取了不同尺度的图片
    • 获取高频区域(边缘检测的算法使用差分滤波器如拉普拉斯滤波器、sobel滤波器)

     

    特征点处理

    • 阈值化操作(去噪)
    • 非极大值抑制
    • 二阶泰勒修正
    • 低对比度去除
    • 边缘效应去除

     

    描述特征点

    • 确定特征点区域方向
    • 特征点区域描述子

     

    API介绍 

    static Ptr create(int nfeatures = 0, int nOctaveLayers = 3,double contrastThreshold = 0.04, double edgeThreshold = 10,double sigma = 1.6);
    /*******************************************************************
    *            nfeatures:                     保留的最佳特性的数量            
    *            cornOctaveLayersners:        高斯金字塔最小层级数
    *            contrastThreshold:            对比度阈值用于过滤区域中的弱特征
    *            edgeThreshold:              用于过滤掉类似边缘特征的阈值
    *            sigma:                        高斯输入层级            
    *********************************************************************/

     


    virtual void detect( InputArray image,std::vector& keypoints,InputArray mask=noArray());
    /*******************************************************************
    *            image:                 输入图                
    *            keypoints:            角点信息
    *            mask:                计算亚像素角点区域大小            
    *********************************************************************/

     


    void drawKeypoints( InputArray image, const std::vector& keypoints, InputOutputArray outImage,const Scalar& color=Scalar::all(-1), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT );
    /*******************************************************************
    *            image:                 输入图                
    *            keypoints:            角点信息
    *            outImage:            输出图
    *            color:              颜色
    *            flags:                绘制标记            
    *********************************************************************/

    完整代码 

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. using namespace cv;
    7. class SIFTFeature
    8. {
    9. public:
    10. SIFTFeature() :img(imread("mm.jpg"))
    11. {
    12. result["img"] = img;
    13. }
    14. void TestSIFT()
    15. {
    16. Ptr sift = SIFT::create();
    17. sift->detect(img, point);
    18. drawKeypoints(img, point, result["SIFT"], Scalar(255, 0, 255));
    19. }
    20. void Show()
    21. {
    22. for (auto& v : result)
    23. {
    24. imshow(v.first, v.second);
    25. }
    26. waitKey(0);
    27. }
    28. protected:
    29. Mat img;
    30. vector point;
    31. map result;
    32. };
    33. int main()
    34. {
    35. unique_ptr p(new SIFTFeature);
    36. p->TestSIFT();
    37. p->Show();
    38. return 0;
    39. }

    效果图:

    7cbe859b2ef44a07b864e928728a95b4.webp 

     

  • 相关阅读:
    找实习之从0开始的后端学习日记【9.14】
    Angular 配置开发环境
    JavaWeb基础之Servlet
    【多线程】阻塞队列 详解
    linux系统下操作I2C总线外设(imx6ull的oled显示屏i2c驱动笔记)
    2023软件测试高频面试题
    HTML Emmet语法
    【stm32芯片设置解惑】:stm32F103系列的开漏输出和推挽输出的区别
    [附源码]计算机毕业设计基于web的羽毛球管理系统
    基于SpringBoot的医疗预约服务管理系统
  • 原文地址:https://blog.csdn.net/qq_39312146/article/details/134408886