由于我对这个问题(关于此类系统的实施)的系统设计有一些负面评价,我希望如果我提出问题,我可以得到一些更好的建议。
我正在尝试设计一个模块化应用程序,用于视频帧中的特征匹配(例如,匹配电影或视频的非常接近的帧,如Sivic,Zisserman的这篇文章中的“产品”)。
这个想法是允许在不同的特征检测算法以及不同的匹配过程之间轻松切换。另外,根据我的研究,我的理解是只有几个基本的匹配过程,而新的匹配方法主要侧重于对不良匹配的额外剪枝过程(例如同一篇文章中的空间一致性)。所有剪枝过程都需要完成初始匹配,然后对从匹配耦合的基础图像和查询图像中提取的特征做一些额外的工作,拒绝错误的匹配。
我对设计的想法如下:
- 实现一个基本接口
featureDetector
- 所有具体的特征检测算法都继承自
featureDetector
接口(例如siftDetector
) - 实现一个基本接口
featureMatcher
- 所有具体的匹配方法都从
featureMatcher
接口继承(例如class bruteForceMatcher
,或 OpenCV 匹配器的包装器,如cvMatcher
) imageMatcher
实现一个实现策略模式的基本接口,以允许选择featureDetector
和featureMatcher
- 对于所有匹配的修剪过程,实现一个继承基本匹配接口的装饰器接口:
class matcherDecorator : public imageMatcher
- 每个额外的修剪/过滤过程都实现了
matcherDecorator
接口(例如spatialConsistencyFilter
)并且只包含imageMatcher*
作为(唯一)参数的构造函数(表示要装饰的组件)
在这个问题中向我指出的问题来自于特征检测和匹配过程的具体结果,它们涉及设计的装饰器部分。每个都imageMatcher
应该包含从两个图像(基本和查询)中提取的特征,以及提取的特征之间的匹配。特征的内部表示与通过以下公共访问功能提供给用户的特征描述符略有不同imageMatcher
:
class imageMatcher{
private: // or protected:
...
...
std::vector <internalFeatureDescriptor> feats[2];
// no more than 500 - 1000 features can be expected
std::vector <std::pair <int, int> > matches;
// size is the same order of magnitude as the number of features
...
public:
std::vector <userFriendlyFeatures> getFeatures(int baseOrQuery);
const std::vector <std::pair<int, int> > &getMatches();
...
};
现在,由于特征向量(以及匹配向量)非常“重”,我不想在使用它们时将它们复制到每个嵌套的装饰器(过滤器)中。我对向量没有任何问题matches
,因为它为用户提供了一个公共接口,允许装饰器访问引用并省略复制数据的需要。feats
另一方面,向量不提供这样的接口,它们的访问功能要求我不仅要进行复制,还要重新计算特征的内部表示。这反过来导致装饰器需要访问内部超类指针的私有(或受保护)变量。
我设法在不违反任何隐私限制的情况下授予我对所需向量的自我访问权限(我(认为)我没有做任何邪恶的实施),但有人建议访问超类的私有成员的想法违反了装饰器模式的想法。
综上所述,我对有关如何重构代码、对当前实现的评论以及与我的应用程序设计有关的任何其他建议感兴趣。