精华内容
下载资源
问答
  • 指纹图像特征提取是指纹识别的关键,而指纹匹配通常基于细节点匹配。指纹特征提取是从细化后的指纹图中得到细节特征点(即端点和分叉点),此特征点含有大量的伪特征,既耗时又影响匹配精度。本章采用了边缘去伪和...
  • 各位看官,最近在线特征相关的研究,本文把直线特征提取匹配的源码贴一下,希望对大家有所帮助,在下使用 OpenCV下的LSD 提取特征,LBD进行特征描述, KNNMatch做特征描述。同时,还有特征质量的简单筛选。#...

    19年1月份的慕尼黑,大雪纷飞...

    各位看官,最近在线特征相关的研究,本文把直线特征的提取和匹配的源码贴一下,希望对大家有所帮助,在下使用 OpenCV下的LSD 提取特征,LBD进行特征描述, KNNMatch做特征描述。同时,还有特征质量的简单筛选。

    #include <iostream>
    #include <chrono>
    #include <cv.h>
    #include <opencv2/core/core.hpp>
    #include <opencv2/core/utility.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/imgcodecs.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/line_descriptor/descriptor.hpp>
    #include <opencv2/features2d/features2d.hpp>
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    using namespace cv::line_descriptor;
    struct sort_descriptor_by_queryIdx
    {
        inline bool operator()(const vector<DMatch>& a, const vector<DMatch>& b){
            return ( a[0].queryIdx < b[0].queryIdx );
        }
    };
    struct sort_lines_by_response
    {
        inline bool operator()(const KeyLine& a, const KeyLine& b){
            return ( a.response > b.response );
        }
    };
    void ExtractLineSegment(const Mat &img, const Mat &image2, vector<KeyLine> &keylines,vector<KeyLine> &keylines2);
    int main(int argc, char**argv)
    {
        if(argc != 3)
            {
                cerr << endl << "Usage: ./Line path_to_image1 path_to_image2" << endl;
                return 1;
            }
        string imagePath1=string(argv[1]);
        string imagePath2=string(argv[2]);
        cout<<"import two images"<<endl;
        Mat image1=imread(imagePath1);
        Mat image2=imread(imagePath2);
    
        imshow("ima1",image1);
        imshow("ima2",image2);
        waitKey(0);
        if(image1.data==NULL)
        {
            cout<<"the path is wrong"<<endl;
        }
    
        vector<KeyLine> keylines,keylines2;
    
    
        ExtractLineSegment(image1,image2,keylines,keylines2);
    
            return 0;
    
    }
    void ExtractLineSegment(const Mat &img, const Mat &image2, vector<KeyLine> &keylines,vector<KeyLine> &keylines2)
    {
        Mat mLdesc,mLdesc2;
    
        vector<vector<DMatch>> lmatches;
    
        Ptr<BinaryDescriptor> lbd = BinaryDescriptor::createBinaryDescriptor();
        Ptr<line_descriptor::LSDDetector> lsd = line_descriptor::LSDDetector::createLSDDetector();
    
        cout<<"extract lsd line segments"<<endl;
        lsd->detect(img, keylines, 1.2,1);
        lsd->detect(image2,keylines2,1.2,1);
        int lsdNFeatures = 50;
        cout<<"filter lines"<<endl;
        if(keylines.size()>lsdNFeatures)
        {
            sort(keylines.begin(), keylines.end(), sort_lines_by_response());
            keylines.resize(lsdNFeatures);
            for( int i=0; i<lsdNFeatures; i++)
                keylines[i].class_id = i;
        }
        if(keylines2.size()>lsdNFeatures)
        {
            sort(keylines2.begin(), keylines2.end(), sort_lines_by_response());
            keylines2.resize(lsdNFeatures);
            for(int i=0; i<lsdNFeatures; i++)
                keylines2[i].class_id = i;
        }
        cout<<"lbd describle"<<endl;
        lbd->compute(img, keylines, mLdesc);
        lbd->compute(image2,keylines2,mLdesc2);//计算特征线段的描述子
        BFMatcher* bfm = new BFMatcher(NORM_HAMMING, false);
        bfm->knnMatch(mLdesc, mLdesc2, lmatches, 2);
        vector<DMatch> matches;
        for(size_t i=0;i<lmatches.size();i++)
        {
            const DMatch& bestMatch = lmatches[i][0];
            const DMatch& betterMatch = lmatches[i][1];
            float  distanceRatio = bestMatch.distance / betterMatch.distance;
            if (distanceRatio < 0.75)
                matches.push_back(bestMatch);
        }
    
        cv::Mat outImg;
        std::vector<char> mask( lmatches.size(), 1 );
        drawLineMatches( img, keylines, image2, keylines2, matches, outImg, Scalar::all( -1 ), Scalar::all( -1 ), mask,
                         DrawLinesMatchesFlags::DEFAULT );
    
        imshow( "Matches", outImg );
        waitKey();
    
    }
    

    CMakeLists.txt的代码如下。实际上,如果只是线提取 没有必要写这个复杂,里面的内容大家可以自行删减,在下就不改了:

    cmake_minimum_required(VERSION 2.8)
    project(BaseExperimentForPLSLAM)
    
    IF(NOT CMAKE_BUILD_TYPE)
      SET(CMAKE_BUILD_TYPE Release)
    ENDIF()
    
    MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
    
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  -Wall  -O3 -march=native ")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall   -O3 -march=native")
    
    # Check C++11 or C++0x support
    include(CheckCXXCompilerFlag)
    CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
    CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
    if(COMPILER_SUPPORTS_CXX11)
       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
       add_definitions(-DCOMPILEDWITHC11)
       message(STATUS "Using flag -std=c++11.")
    elseif(COMPILER_SUPPORTS_CXX0X)
       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
       add_definitions(-DCOMPILEDWITHC0X)
       message(STATUS "Using flag -std=c++0x.")
    else()
       message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
    endif()
    
    LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
    
    find_package(OpenCV 3.0 QUIET)
    if(NOT OpenCV_FOUND)
       find_package(OpenCV 2.4.3 QUIET)
       if(NOT OpenCV_FOUND)
          message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
       endif()
    endif()
    
    include_directories(
    ${PROJECT_SOURCE_DIR}
    ${PROJECT_SOURCE_DIR}/include
    )
    
    
    
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
    
    add_library(${PROJECT_NAME} SHARED
    src/Blur.cc
    
    )
    
    target_link_libraries(${PROJECT_NAME}
    ${OpenCV_LIBS}
    
            )
    # Build examples
    
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/example/)
    
    add_executable(Line example/baseExperiment.cc)
    target_link_libraries(Line ${PROJECT_NAME})

    最后提取的结果是下图展示的。最后大家觉得这种线提取方式,有什么优缺点,可以在下方评论或私信我,一起交流讨论。

    f51fe1121adab64b3401d365646e3939.png

    ————————————C++(上),matlab(下)————————————————

    在MATLAB中,我们调用OpenCV同样可以做图像处理,一些非计算机专业的同学可能有这样的需求。这里我们介绍一个matlab使用lsd的repo。

    这是github上开源项目,可以自行下载

    guiyuliu/lsd

    (1)编译(ubuntu下的,windows我不熟)

    如果你之前在matlab平台上使用过Opencv,你一定下载过mexopencv-x (x表示版本),为matlab做opencv库就不介绍了,大家可以去找教程。会做OpenCV之后,就简单了

    cd lsd-1.6

    mex -O -output lsd lsd_matlab.c lsd.c

    就可以了。

    (2)调用

    add('~/xx/lsd-1.5')%你自己的路径

    lines=lsd(double(Image))

    ___________________________打_完_收_工___________________

    展开全文
  • 基于 matlab图像识别与匹配 摘 要 图像的识别与匹配是立体视觉的一个重要分支该项技术被广泛应用在航空 测绘星球探测机器人导航以及三维重建等领域 本文意在熟练运用图像的识别与匹配的方法为此本文使用一个包装...
  • https://github.com/MichaelBeechan/VisualOdometry_BasedOnSURF %% Name:Michael Beechan %% School:Chongqing University of Technology %% Time:2018.12.11 %% Function:Extract image features 原图像: %% ...

    了解博主更多项目查看

    github:https://github.com/MichaelBeechan

    CSDN:https://blog.csdn.net/u011344545

    ====================================================================

    代码下载:https://github.com/MichaelBeechan/VisualOdometry_BasedOnSURF

    %% Name:Michael Beechan
    %% School:Chongqing University of Technology
    %% Time:2018.12.11
    %% FunctionExtract image features

    原图像:

    %% read image
    boxImage = imread('1.jpg');
    boxImage = rgb2gray(boxImage);
    %{
    figure;
    imshow(boxImage);
    title('Image of a box');
    %}
    sceneImage = imread('2.jpg');
    sceneImage = rgb2gray(sceneImage);
    %{
    figure;
    imshow(sceneImage);
    title('Image of cluttered scene');
    %}

    %% detect image feature points
    boxPoints = detectSURFFeatures(boxImage);
    scenePoints = detectSURFFeatures(sceneImage);
    figure(1);
    imshow(boxImage);
    title('100 Feature Points');
    hold on;
    plot(selectStrongest(boxPoints, 100));
     

    figure(2);
    imshow(sceneImage);
    title('300 Feature Points');
    hold on;
    plot(selectStrongest(scenePoints, 300));

    %% Extract feature descriptor
    [boxFeatures, boxPoints] = extractFeatures(boxImage, boxPoints);
    [sceneFeatures, scenePoints] = extractFeatures(sceneImage, scenePoints);

    %% find Putative point matches
    boxPairs = matchFeatures(boxFeatures, sceneFeatures);

    %% display matched features
    matchedBoxPoints = boxPoints(boxPairs(:, 1), :);
    matchedScenePoints = scenePoints(boxPairs(:, 2), :);
    figure(3);
    showMatchedFeatures(boxImage, sceneImage, matchedBoxPoints, matchedScenePoints, 'montage');
    title('Putatively Matched Points(Including Outliers)');

    %% Locate the Object in Scene Using Putative Matches
    [tform, inlierBoxPoints, inlierScenePoints] = ...
        estimateGeometricTransform(matchedBoxPoints, matchedScenePoints, 'affine');
    figure(4);
    showMatchedFeatures(boxImage, sceneImage, inlierBoxPoints, inlierScenePoints, 'montage');
    title('Matched Points(Inliers Only)');
     

    %% Get the bounding polygon(多边形)of the reference image
    boxPolygon = [1, 1;...                              %top-left
            size(boxImage, 2), 1;...                    %top-right
            size(boxImage, 2), size(boxImage, 1);...    %bottom-right
            1, size(boxImage, 1);...                    %bottom-left
            1, 1];                                      %top-left again to close the polygon
    %% Transform the polygon into the coordinate system of the target image
    %% The transformed polygon indicates the location of the object in scene

    newBoxPolygon = transformPointsForward(tform, boxPolygon);
    figure(5);
    imshow(sceneImage);
    hold on;
    line(newBoxPolygon(:, 1), newBoxPolygon(:, 2), 'Color', 'y');
    title('Detected Box');

     

    展开全文
  • 各位看官,最近在线特征相关的研究,本文把直线特征提取匹配的源码贴一下,希望对大家有所帮助,在下使用 OpenCV下的LSD 提取特征,LBD进行特征描述, KNNMatch做特征描述。同时,还有特征质量的简单筛选。#...

    19年1月份的慕尼黑,大雪纷飞...

    各位看官,最近在线特征相关的研究,本文把直线特征的提取和匹配的源码贴一下,希望对大家有所帮助,在下使用 OpenCV下的LSD 提取特征,LBD进行特征描述, KNNMatch做特征描述。同时,还有特征质量的简单筛选。

    #include #include #include #include #include #include #include #include #include #include #include

    using namespace cv;

    using namespace std;

    using namespace cv::line_descriptor;

    struct sort_descriptor_by_queryIdx

    {

    inline bool operator()(const vector& a, const vector& b){

    return ( a[0].queryIdx < b[0].queryIdx );

    }

    };

    struct sort_lines_by_response

    {

    inline bool operator()(const KeyLine& a, const KeyLine& b){

    return ( a.response > b.response );

    }

    };

    void ExtractLineSegment(const Mat &img, const Mat &image2, vector &keylines,vector &keylines2);

    int main(int argc, char**argv)

    {

    if(argc != 3)

    {

    cerr << endl << "Usage: ./Line path_to_image1 path_to_image2" << endl;

    return 1;

    }

    string imagePath1=string(argv[1]);

    string imagePath2=string(argv[2]);

    cout<

    Mat image1=imread(imagePath1);

    Mat image2=imread(imagePath2);

    imshow("ima1",image1);

    imshow("ima2",image2);

    waitKey(0);

    if(image1.data==NULL)

    {

    cout<

    }

    vector keylines,keylines2;

    ExtractLineSegment(image1,image2,keylines,keylines2);

    return 0;

    }

    void ExtractLineSegment(const Mat &img, const Mat &image2, vector &keylines,vector &keylines2)

    {

    Mat mLdesc,mLdesc2;

    vector> lmatches;

    Ptr lbd = BinaryDescriptor::createBinaryDescriptor();

    Ptr<:lsddetector> lsd = line_descriptor::LSDDetector::createLSDDetector();

    cout<

    lsd->detect(img, keylines, 1.2,1);

    lsd->detect(image2,keylines2,1.2,1);

    int lsdNFeatures = 50;

    cout<

    if(keylines.size()>lsdNFeatures)

    {

    sort(keylines.begin(), keylines.end(), sort_lines_by_response());

    keylines.resize(lsdNFeatures);

    for( int i=0; i

    keylines[i].class_id = i;

    }

    if(keylines2.size()>lsdNFeatures)

    {

    sort(keylines2.begin(), keylines2.end(), sort_lines_by_response());

    keylines2.resize(lsdNFeatures);

    for(int i=0; i

    keylines2[i].class_id = i;

    }

    cout<

    lbd->compute(img, keylines, mLdesc);

    lbd->compute(image2,keylines2,mLdesc2);//计算特征线段的描述子 BFMatcher* bfm = new BFMatcher(NORM_HAMMING, false);

    bfm->knnMatch(mLdesc, mLdesc2, lmatches, 2);

    vector matches;

    for(size_t i=0;i

    {

    const DMatch& bestMatch = lmatches[i][0];

    const DMatch& betterMatch = lmatches[i][1];

    float distanceRatio = bestMatch.distance / betterMatch.distance;

    if (distanceRatio < 0.75)

    matches.push_back(bestMatch);

    }

    cv::Mat outImg;

    std::vector mask( lmatches.size(), 1 );

    drawLineMatches( img, keylines, image2, keylines2, matches, outImg, Scalar::all( -1 ), Scalar::all( -1 ), mask,

    DrawLinesMatchesFlags::DEFAULT );

    imshow( "Matches", outImg );

    waitKey();

    }

    CMakeLists.txt的代码如下。实际上,如果只是线提取 没有必要写这个复杂,里面的内容大家可以自行删减,在下就不改了:

    cmake_minimum_required(VERSION 2.8)

    project(BaseExperimentForPLSLAM)

    IF(NOT CMAKE_BUILD_TYPE)

    SET(CMAKE_BUILD_TYPE Release)

    ENDIF()

    MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")

    # Check C++11 or C++0x support

    include(CheckCXXCompilerFlag)

    CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)

    CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)

    if(COMPILER_SUPPORTS_CXX11)

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

    add_definitions(-DCOMPILEDWITHC11)

    message(STATUS "Using flag -std=c++11.")

    elseif(COMPILER_SUPPORTS_CXX0X)

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")

    add_definitions(-DCOMPILEDWITHC0X)

    message(STATUS "Using flag -std=c++0x.")

    else()

    message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")

    endif()

    LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

    find_package(OpenCV 3.0 QUIET)

    if(NOT OpenCV_FOUND)

    find_package(OpenCV 2.4.3 QUIET)

    if(NOT OpenCV_FOUND)

    message(FATAL_ERROR "OpenCV > 2.4.3 not found.")

    endif()

    endif()

    include_directories(

    ${PROJECT_SOURCE_DIR}

    ${PROJECT_SOURCE_DIR}/include

    )

    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)

    add_library(${PROJECT_NAME} SHARED

    src/Blur.cc

    )

    target_link_libraries(${PROJECT_NAME}

    ${OpenCV_LIBS}

    )

    # Build examples

    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/example/)

    add_executable(Line example/baseExperiment.cc)

    target_link_libraries(Line ${PROJECT_NAME})

    最后提取的结果是下图展示的。最后大家觉得这种线提取方式,有什么优缺点,可以在下方评论或私信我,一起交流讨论。

    ————————————C++(上),matlab(下)————————————————

    在MATLAB中,我们调用OpenCV同样可以做图像处理,一些非计算机专业的同学可能有这样的需求。这里我们介绍一个matlab使用lsd的repo。

    这是github上开源项目,可以自行下载

    (1)编译(ubuntu下的,windows我不熟)

    如果你之前在matlab平台上使用过Opencv,你一定下载过mexopencv-x (x表示版本),为matlab做opencv库就不介绍了,大家可以去找教程。会做OpenCV之后,就简单了

    cd lsd-1.6

    mex -O -output lsd lsd_matlab.c lsd.c

    就可以了。

    (2)调用

    add('~/xx/lsd-1.5')%你自己的路径

    lines=lsd(double(Image))

    ___________________________打_完_收_工___________________

    展开全文
  • 基于matlab的特征匹配的英文...采用字符的归一化和细化处理方法,通过二值化和字体类型特征相结合的处理方法完成特征提取,建立了字符标准特征库,合理的模版匹配算法实现了印刷体字符的识别,matlab仿真代码亲测可用。
  • matlab学习:SIFT特征提取

    千次阅读 2012-11-21 13:51:00
    1.推荐/引用 博客 SIFT算法研究:http://underthehood.blog.51cto.com/2531780/658350 SIFT特征提取算法总结:... 图像特征提取与匹配之SIFT算法:http://blog.csdn.net/v_JULY_v/a...

    1.推荐/引用 博客

    SIFT算法研究:http://underthehood.blog.51cto.com/2531780/658350

    SIFT特征提取算法总结:http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html

    图像特征提取与匹配之SIFT算法:http://blog.csdn.net/v_JULY_v/article/details/6186942

    一些公式推导来自实验室师兄的笔记,感谢。

    论文:David G. Lowe, "Distinctive image features from scale-invariant keypoints,"
        International Journal of Computer Vision, 60, 2 (2004), pp. 91-110

                                  SIFT算法学习

    1.算法流程

     

    2.具体实现

    (1)构造高斯差分尺度空间

    高斯函数是唯一的尺度变换核,则图像的尺度空间就可以看做是尺度变换的高斯函数与输入图像的卷积。

    其中,尺度可变的高斯核为

    其中,(x,y)是空间坐标,σ是尺度坐标。σ 的大小决定图像的平滑程度,大尺度对应图像的概貌特征(低分辨率),小尺度对应图像的细节特征(高分辨率)。

    为了有效在尺度空间检测到稳定的关键点,提出用不同尺度的高斯差分核与图像卷积:

    其中k为常数,用来区分两相邻尺度乘积因子。

    选择高斯差分尺度空间DOG的原因:

    ① 容易计算,为求出不同尺度上的图像特征,只需要作差就可以了;

    ② 高斯差分函数DOG近似于尺度归一化的LOG,相比于其他特征,LOG的最大最小值产生的特征更加稳定。

    关于DOG近似归一化LOG的证明:

    利用有限差分逼近:

    在所有尺度上,k-1是常数,不影响极值点的位置,k越接近1,近似误差越接近0.但实际中发现这种近似对极值检测的稳定性和位置几乎不存在影响,甚至在尺度上发生较大变化时也一样。

    高斯差分尺度空间的构造:

    首先是构建图像的高斯金字塔。原始图像递增地与高斯函数卷积来生成新尺寸的图像,尺度空间中的图像由常数因子K来区别。

    关于尺度空间的理解说明:上图是必须的,尺度空间是连续的。在Lowe的论文中 ,在最开始建立高斯金字塔时,要预先模糊输入图像来作为第0个组的第0层的图像,这样就会丢失高频信息。因此,为了充分利用输入图像可以首先对原始图像长宽扩展一倍,来增加特征点数量。尺度越大图像越模糊。 我们利用线性插值将图像扩大为原来2倍,作为金字塔的第一层。

    图像金字塔共分O组,一组称为一个Octave,每组又分为多层,层间隔数为S,因此有S+3(S+1+22代表在上下再各添一层图像,搜索极值只在中间的S+1层图像上搜索)层图像,下一组的第一层图像由上一组的倒数第三层(如果层索引从0开始,则为第S层)图像按照隔点采样(试验中用3个尺度采样)得到,可减少卷积运算的工作量。

    DoG是通过高斯金字塔中的每组上下相邻两层的高斯尺度空间图像相减得到。

     

    (2)寻找尺度空间极值点

     

      同一组中的相邻尺度(由于k的取值关系,肯定是上下层)之间进行寻找:在极值比较的过程中,每一组图像的首末两层是无法进行极值比较的,为了满足尺度变化的连续性,在每一组图像的顶层继续用高斯模糊生成了 幅图像,高斯金字塔有每组S+3层图像。DOG金字塔每组有S+2层图像.

     

               

    (3)精确定位极值点

     

    ① 对检测到的极值点进行三维二次函数拟合,精确定位极值点的位置和尺度,达到亚像素精度。

    极值点的搜索是在离散空间中进行的,检测到的极值点并不是真正意义上的极值点。二维函数离散空间得到的极值点与连续空间极值点有差别。利用已知的离散空间点插值得到的连续空间极值点的方法叫做子像素插值.

    插值的方法是根据泰勒级数展开:

    求导,并令其为0,得到极值点位置的偏移量:

    x^代表相对于插值中心的偏移量,当它在任一维度上的偏移量大于0.5时(即xy或σ),意味着插值中心已经偏移到它的邻近点上,所以必须改变当前关键点的位置(加上x^)同时在新的位置上反复插值直到收敛;也有可能超出所设定的迭代次数或者超出图像边界的范围,此时这样的点应该删除。

     

    ② 去除低对比度的点

    极值点的函数值:

    回代:

    得:

    极值点的函数值可以用来去除由低对比度造成的不稳定极值,在该文章中,若极值点函数值小于0.03,则表明其响应值过小易受噪声影响而变得不稳定,要去除.

    ③ 去除边缘相应

    高斯差分函数DOG对边缘有着很强的响应,边缘上的点对于小的噪声不稳定。根据Harris角点可以知道,一个角点在任何方向上平移都应该保证局部窗口内的像素值的剧烈变化,而边缘上的点沿着边缘方向移动时局部窗口内的像素值基本没有什么变化。

    一个平坦的(边缘点)DoG响应峰值往往在横跨边缘的地方有较大的主曲率,而在垂直的方向有较小的主曲率。所以利用主曲率比的大小来排除边缘响应的点。而主曲率可以通过2×2Hessain矩阵H求出:

    H的特征值与D的主曲率成正比例。我们只关心比例,可以不必明确地计算特征值,可以由H的迹和行列式的积来计算特征值的和。令α为大的特征值,β为小的特征值,则主曲率的比值大小可由特征值所表示的比值式来计算:

    试验中,该比例大于10的点被认为是边缘点,应去除。

     

    (4)给每个关键点分配主方向

     

    利用关键点邻域像素的梯度方向分布特性(幅值和方向)为每个关键点指定方向参数,使算子具备旋转不变性。

    其中L所用的尺度为每个关键点各自所在的尺度。

    在完成特征点邻域的高斯图像的梯度计算后,使用直方图统计邻域内像素的梯度方向和幅值。梯度方向直方图的横轴是梯度方向角,纵轴是梯度方向角对应的梯度幅值累加。梯度方向直方图将0-360度的范围分为36个柱(bins),每10度一个柱。

    高斯加权函数(o为描述子窗宽的一半)用来对每个采样点的幅值进行加权,距离描述子中心越远的领域对直方图的贡献也响应也越小,可以避免窗口位置变化引起的描述子突变。

    直方图的峰值代表该特征点处邻域内图像梯度的主方向,也即该特征点的主方向。

    当存在一个相当于主峰值能量80%能量的峰值时,会产生一个具有该主方向的极值点。因此,对于具有相似幅值的多峰位置点,会在一个位置上产生多个关键点。只有15%的点会有多个方向,但是这对匹配影响很大。最终,用抛物线来拟合3个接近峰值的直方图的值进行峰值点位置插值,获得更好的准确性。

    (5)特征描述子生成

     

    每一个小格都代表了特征点邻域所在的尺度空间的一个像素 ,箭头方向代表了像素梯度方向,箭头长度代表该像素的幅值。然后在4×4的窗口内计算8个方向的梯度方向直方图。绘制每个梯度方向的累加可形成一个种子点。

    每个直方图有8方向的梯度方向,每一个描述符包含一个位于关键点附近的四个直方图数组.这就导致了SIFT的特征向量有128.(先是一个4×4的来计算出一个直方图,每个直方图有8个方向。所以是4×4×8=128维)

    为避免边界影响,采用三线性插值,将每一个梯度样本值分配到相邻的直方图块中。每一个直方图块在每个维上乘以权重1-dd是样本到直方图块中心值的距离。

    &实现光照不变性

    ① 处理线性变化(对比度/亮度):归一化到单位向量

    为了降低光照变化的影响:首先,特征向量归一化到单位长度,每个像素值乘以一个常数引起图像对比度的改变,会使梯度乘以相同的常数。所以归一化后会撤销常数的改变。亮度变化引起的每个像素值增加一个常数,不会影响梯度值。因此该描述子具有光照不变性。

    ② 处理非线性变化(饱和度/光照):归一化+阈值化+归一化

    相机饱和度或光照变化影响3D表面的方向变化,这些影响会使梯度幅值有大的改变,但不太会影响梯度方向。因此要降低大的梯度幅值的影响,将单位特征向量进行阈值化:对于中值大于0.2的要进行截断,即大于0.2的值只取0.2,再进行一次归一化处理,其目的是提高特征的鉴别性。

    展开全文
  • 一、局部特征提取 二、特征匹配 三、图像拼接 一、局部特征提取 检测SURF特征点 points = detectSURFFeatures(I); 提取特征描述子 [features,validPoints] = extractFeatures(I,points); 二、...
  • 采用字符的归一化和细化处理方法,通过二值化和字体类型特征相结合的处理方法完成特征提取,建立了字符标准特征库,合理的模版匹配算法实现了印刷体字符的识别,matlab仿真代码亲测可用。 二、源代码 function ...
  • matlab实现图像拼接

    2020-08-17 16:41:42
    图像的拼接技术包括三大部分:特征提取与匹配图像配准、图像融合。图像拼接是一项应用广泛的图像处理技术。根据特征点的相互匹配,可以将多张小视角的图像拼接成为一张大视角的图像,在广角照片合成、卫星照片...
  • 针对电气设备同一场景的红外可见光图像间一致特征难以提取匹配的问题,提出了一种基于斜率一致性的配准方法。首先通过数学形态学方法分别提取红外可见光图像的边缘,得到粗边缘图像;然后通过SURF算法提取两幅...
  • 采用字符的归一化和细化处理方法,通过二值化和字体类型特征相结合的处理方法完成特征提取,建立了字符标准特征库,合理的模版匹配算法实现了印刷体字符的识别,matlab仿真代码亲测可用。 二、源代码 clear all ...
  • 采用字符的归一化和细化处理方法,通过二值化和字体类型特征相结合的处理方法完成特征提取,建立了字符标准特征库,合理的模版匹配算法实现了印刷体字符的识别,matlab仿真代码亲测可用。 二、源代码 function ...
  • 针对电气设备同一场景的红外可见光图像间一致特征难以提取匹配的问题,提出了一种基于斜率一致性的配准方法。首先通过数学形态学方法分别提取红外可见光图像的边缘,得到粗边缘图像;然后通过SURF算法提取两幅...
  • 红外可见光图像配准算法--MATLAB

    万次阅读 多人点赞 2016-03-11 16:39:07
    2016-07-08更新总体方法简述:针对电气设备同一场景的红外可见光图像间一致特征难以提取匹配的问题,提出了一种基于斜率一致性的配准方法。首先通过数学形态学方法分别提取红外可见光图像的边缘,得到粗边缘...
  • 指纹图像的预处理、图像...对上述算法研究的基础上,实现了指纹识别算法与Matlab中图形界面相结合,最后在图形界面内显示了指纹预处理过程、指纹特征提取图像以及特征匹配的实验结果,并对各算法进行了系统性的总结分析
  • 指纹图像细化 matlab程序源代码

    热门讨论 2008-08-04 10:45:12
    使用OPTA细化算法,对指纹图像进行细化,为后面的特征提取与匹配打下坚实的基础
  • 双目视觉系统标定与匹配的研究与实现.pdf MATLAB,VC++ 图像获取、摄像机标 定、特征提取、立体匹配
  • //一定要记得这里路径的斜线方向,这与Matlab里面是相反的 if(!img_1.data || !img_2.data)//如果数据为空 { cout; return -1; } cout; // 第一步,用SIFT算子检测关键点 SiftFeatureDetector detector...
  • 基于MATLAB的PCA SIFT算子的实现

    热门讨论 2011-09-11 00:56:54
    基于MATLAB的数字图像处理特征提取 配准 PCA Sift 基于 主成份分析 尺度不变特征转换的图像特征匹配
  • 1. 给定一对图像,利用提取好的SIFT特征文件,根据距离阈值准则(跨图像的局部SIFT特征距离小于0.4),得到图像间的初始局部特征匹配关系; 2. 基于上述初步匹配结果,实现spatial coding方法,进行匹配校验,确定...
  • VC与Matlab混合编程实现成组图像边缘的连续提取.pdf VC与MATLAB混合编程实现方法及具体实例研究.pdf VC与Matlab混合编程的研究实现.pdf VCSTK的集成及在****数字可视化仿真中的应用.pdf VC中应用MSComm控件...
  • 字符识别方法目前主要有基于模板匹配算法和基于人工神经网络算法。 基于模板匹配算法:首先将分割后的字符二值化,并...另一种是直接把待处理图像输入网络,由网络自动实现特征提取直至识别出结果。 本节所介绍的字符...
  • 第 9 章 基于特征匹配的英文印刷字符识别  第 10 章 基于不变矩的数字验证码识别  第 11 章 基于小波技术进行图像融合  第 12 章 基于块匹配的全景图像拼接  第 13 章 基于霍夫曼图像压缩重建  第 14 章 基于...
  • VC与Matlab混合编程实现成组图像边缘的连续提取.pdf VC与MATLAB混合编程实现方法及具体实例研究.pdf VC与Matlab混合编程的研究实现.pdf VCSTK的集成及在****数字可视化仿真中的应用.pdf VC中应用MSComm控件...
  • VC与Matlab混合编程实现成组图像边缘的连续提取.pdf VC与MATLAB混合编程实现方法及具体实例研究.pdf VC与Matlab混合编程的研究实现.pdf VCSTK的集成及在****数字可视化仿真中的应用.pdf VC中应用MSComm控件...
  • VC与Matlab混合编程实现成组图像边缘的连续提取.pdf VC与MATLAB混合编程实现方法及具体实例研究.pdf VC与Matlab混合编程的研究实现.pdf VCSTK的集成及在****数字可视化仿真中的应用.pdf VC中应用MSComm控件...

空空如也

空空如也

1 2 3
收藏数 58
精华内容 23
关键字:

matlab图像特征提取与匹配

matlab 订阅