opencv特征线检测与应用

1.前言

我之前写过一个系列的文章讲述基于Opencv的图像拼接,拼接流水线中最重要的一步就是特征点识别以及特征点匹配,特征点的好坏直接决定了最终的拼接效果,但对于医疗图像而言,加之如果图像质量不好,则提取的特征点区分度并不高,如下图所示,很多特征点都匹配错了。

opencv特征线检测与应用_第1张图片

那有没有什么办法呢?这时不如换个思路[换个角度看问题],既然特征点不行,那就找特征线,Opencv中提供了两种线特征提取器,接下来就让我们分别看看Opencv是如何实现特征线的识别与匹配的。

2.Opencv二值描述符特征线识别与匹配

特征线提取:

/* 从命令行中获取输入图像路径,至少两张图像 */

CommandLineParser parser(argc, argv, keys );

String image_path1 = parser.get<String>( 0 );
String image_path2 = parser.get<String>( 1 );

if( image_path1.empty() || image_path2.empty() )
{
   
  help();
  return -1;
}

/* 使用opencv接口读取图像 */
cv::MatimageMat1 = imread( image_path1, 1 );
cv::MatimageMat2 = imread( image_path2, 1 );

/* 用来告诉opencv特征线识别接口从哪些区域去识别,哪些区域不需要处理 */
cv::Mat mask1 =Mat::ones( imageMat1.size(), CV_8UC1 );
cv::Mat mask2 =Mat::ones( imageMat2.size(), CV_8UC1 );

/* BinaryDescriptor就是用来提取特征线并生成二进制描述符*/
Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor(  );

/* 特征线坐标 */
std::vector<KeyLine> keylines1, keylines2;
/* 特征线描述符 */
cv::Mat descr1, descr2;
/* 特征线识别 */
(*bd )( imageMat1, mask1, keylines1, descr1, false, false );
(*bd )( imageMat2, mask2, keylines2, descr2, false, false );

通过上面的操作我们获取到了所有特征线,每个特征线由KeyLine表示,里面有每个特征线的ID,两个端点坐标,角度等信息,同时也得到了所有特征线的描述符,并且保存到了一个Mat中。

特征线匹配:

得到特征线后,接下来就要进行特征线匹配了:

/* create a BinaryDescriptorMatcher object */
Ptr<BinaryDescriptorMatcher> bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();

/* require match */
std::vector<DMatch> matches;
bdm->match( left_lbd, right_lbd, matches );

/* select best matches */
std::vector<DMatch> good_matches;

for ( int i = 0; i < (int) matches.size(); i++ )
{
   
  if( matches[i].distance < MATCHES_DIST_THRESHOLD )
      good_matches.push_back( matches[i] );
}

/* plot matches */
cv::Mat outImg;
cv::Mat scaled1, scaled2;
std::vector<char> mask( matches.size(), 1 );
drawLineMatches( imageMat1, lbd_octave1, imageMat2, lbd_octave2, good_matches, outImg, Scalar::all( -1 ), Scalar::all( -

你可能感兴趣的:(计算机视觉,opencv,图像处理)