OpenCV 3.0.0 beta で Dense samplingする
さて,先日の記事OpenCV 3.0.0 alpha で Dense samplingする - のどあめを書いたと思ったら,すぐにOpenCV 3.0.0 betaが出てしまいました.
(リリース予定くらいは確認すべきでした)
もちろん,研究室のうちのグループ(の私だけ)は,早速OpenCV 3.0.0 betaに切り替えました.しかし,先日実装したDenseSamplingのコードは,betaではコンパイルが通りません.
そこで,今回は先日の記事と同じようにOpenCV 3.0.0 betaでもDense Samplingの実装をしたいと思います.
Dense Samplingの実装(OpenCV 3.0.0 beta版)
前回のdetectImpl関数をdetectAndComputeに変更します.
detectなどはこの関数を内部で呼んでいるみたいです.
compute関数(DescriptorExtractor的な関数?)をoverrideしてassertを吐かせる方がいい気もしますが,今回は省略.
DenseFeatureDetector.h
#pragma once #include <opencv2/opencv.hpp> namespace cv { class DenseFeatureDetector : public cv::FeatureDetector { public: struct Param{ int xStep = 4; int yStep = 4; float initFeatureScale = 1.0f; int scaleLevels = 1; float featureScaleMul = 1.2f; int imgBoundX = 0; int imgBoundY = 0; bool varyXyStepWithScale = true; bool varyImgBoundWithScale = false; Param(){} }param; DenseFeatureDetector(){} DenseFeatureDetector(const Param& p) :param(p) { } static cv::AlgorithmInfo& _info(); virtual cv::AlgorithmInfo* info()const override; virtual void detectAndCompute( cv::InputArray image, cv::InputArray mask, std::vector<cv::KeyPoint>& keypoints, cv::OutputArray descriptors, bool useProvidedKeypoints=false ); static cv::Ptr<FeatureDetector> create(const Param& p=Param()){ return cv::Ptr<FeatureDetector>(new DenseFeatureDetector(p)); } }; }
DenseFeatureDetector.cpp
#include "DenseFeatureDetector.h" namespace cv{ #define CV_INIT_ALGORITHM(classname, algname, memberinit) \ static inline ::cv::Algorithm* create##classname##_hidden() \ { \ return new classname; \ } \ \ static inline ::cv::Ptr< ::cv::Algorithm> create##classname##_ptr_hidden() \ { \ return ::cv::makePtr<classname>(); \ } \ \ static inline ::cv::AlgorithmInfo& classname##_info() \ { \ static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname##_hidden); \ return classname##_info_var; \ } \ \ static ::cv::AlgorithmInfo& classname##_info_auto = classname##_info(); \ \ ::cv::AlgorithmInfo* classname::info() const \ { \ static volatile bool initialized = false; \ \ if( !initialized ) \ { \ initialized = true; \ classname obj; \ memberinit; \ } \ return &classname##_info(); \ } CV_INIT_ALGORITHM(DenseFeatureDetector, "Dense",); void DenseFeatureDetector::detectAndCompute( cv::InputArray image, cv::InputArray mask, std::vector<cv::KeyPoint>& keypoints, cv::OutputArray descriptors, bool useProvidedKeypoints) { if (!useProvidedKeypoints) keypoints.clear(); cv::Mat maskMat = mask.empty() ? cv::Mat(image.size(), CV_8UC1, cv::Scalar(255)) : mask.getMat(); cv::Mat imageMat = image.getMat(); int width = imageMat.cols; int height = imageMat.rows; int nowBoundX = param.imgBoundX; int nowBoundY = param.imgBoundY; int nowXStep = param.xStep; int nowYStep = param.yStep; float nowFeatureSize = param.initFeatureScale; for (int s = 0; s < param.scaleLevels; s++){ for (int y = nowBoundY; y < height; y += nowYStep){ unsigned char* maskline = maskMat.ptr<unsigned char>(y); for (int x = nowBoundX; x < width; x += nowYStep){ if (maskline[x] > 128){ cv::KeyPoint kp; kp.pt = cv::Point(x, y); kp.size = nowFeatureSize; kp.response = 100.0f; keypoints.push_back(kp); } } } if (param.varyImgBoundWithScale){ nowBoundX *= param.featureScaleMul; nowBoundY *= param.featureScaleMul; } if (param.varyXyStepWithScale){ nowXStep *= param.featureScaleMul; nowYStep *= param.featureScaleMul; } nowFeatureSize *= param.featureScaleMul; } } }
基本的には関数名以外変える必要はありません.
これで,先日の記事のコードを動かすことで同様の結果が得られます.
今回のまとめ
- 大きな仕様変更がなくてよかった.