matlab 图像分割 提取人像_图像中的直线提取与匹配(LSD,code/c++,matlab可用)

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))

___________________________打_完_收_工___________________

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值