最近遇到一个函数,在调用的时候出现问题,记录下实现过程。

#ifndef MLS_DEFORMATION_H
#define MLS_DEFORMATION_H #include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp> using namespace cv;
using namespace std; class MLSDeformation//父类
{
public:
virtual bool InitMLSD(const cv::Mat& oriImg,const std::vector<cv::Point2i>&src_pt,int alpha=, int gridsize=);//定义成虚函数是为了方便子类改写
virtual cv::Mat Deformation(const std::vector<cv::Point2i> &dst_pt)=;//=0说明这个函数没有实现完
explicit MLSDeformation();// 指定这个构造器只能被明确的调用/使用, 不能作为类型转换操作符被隐含的使用。
virtual ~MLSDeformation();
protected:
cv::Mat getDeformationImg();
void meanMat(cv::Mat& mat, int i, int j);//对mat(i,j)进行gridsize的中值(当mean为空时),不包括像素为空的坐标
void repairMat(cv::Mat& mat);//变形后的mat有些位置没有像素点,使用中值滤波填补
int gridsize_;
int alpha_;///weight_计算相关
int n_point_;///控制点数
cv::Mat src_img_;//原图像
int src_width_;
int src_height_;
std::vector<cv::Point2d> pi_point_;//原控制点
std::vector<cv::Point2d> qi_point_;//变形后的控制点
///参数信息
double*weight_;//权重w*h*pt
double*sum_weight_;//w*h
cv::Point2d*deformation_pt_;//对应目标坐标
cv::Point2d pstart_, qstart_;
std::vector<cv::Point2d> pdiff_, qdiff_;
}; class MLSDAffine :public MLSDeformation//继承主类的子类
{
public:
virtual bool InitMLSD(const cv::Mat& oriImg,const std::vector<cv::Point2i>&src_pt,int alpha=, int gridsize=);//写成virtual完全是因为从主类拷贝过来的,也可以认为方便接下来的子类继承他
virtual cv::Mat Deformation(const std::vector<cv::Point2i> &dst_pt);
explicit MLSDAffine();
virtual~MLSDAffine();
private:
double*a_affine_;///affine A参数
}; class MLSDSimilarity :public MLSDeformation
{
public:
virtual bool InitMLSD(const cv::Mat& oriImg,const std::vector<cv::Point2i>&src_pt,int alpha=, int gridsize=);
virtual cv::Mat Deformation(const std::vector<cv::Point2i> &dst_pt);
explicit MLSDSimilarity();
virtual~MLSDSimilarity();
private:
double*us_;//us参数
cv::Matx22d*a_similarity_;///similarity A参数
}; class MLSDRigid :public MLSDeformation
{
public:
virtual bool InitMLSD(const cv::Mat& oriImg,const std::vector<cv::Point2i>&src_pt,int alpha=, int gridsize=);
virtual cv::Mat Deformation(const std::vector<cv::Point2i> &dst_pt);
explicit MLSDRigid();
virtual~MLSDRigid();
private:
double*ur_;//us参数
cv::Point2d*pstart_rigid_;//
cv::Matx22d*a_rigid_;///similarity A参数
};
#endif // MLS_DEFORMATION_H

从上面的实现可以看出,实现了一个MLS变形的方法,里面有两个函数,分别是init和deformation,然后三个子类开始继承这个父类,然后分别实现了MLS的仿射变换,相似变换,刚性变化。

这里顺便扩展下几个变换的意义。

仿射变换:主要包括平移变换、旋转变换、缩放变换(也叫尺度变换)、倾斜变换(也叫错切变换、剪切变换、偏移变换)、翻转变换,有六个自由度。

仿射变换保持二维图形的“平直性”和“平行性”,但是角度会改变。 
“平直性”:变换后直线还是直线、圆弧还是圆弧。 
“平行性”:平行线还是平行线,直线上点的位置顺序不变

相似变换:相当于是等距变换和均匀缩放的一个复合,用S表示变换矩阵,即为

左上角2×2矩阵为旋转部分,tx和ty为平移因子,它有4个自由度,即旋转,x方向平移,y方向平移和缩放因子s。相似变换前后长度比,夹角,虚圆点I,J保持不变。相似变换其实与相似三角形之间是有类似的。

在调用这些方法的时候,主要可以有以下几种方式。

刚性变换:只有物体的位置(平移变换)和朝向(旋转变换)发生改变,而形状不变。

调用上述类的方法:

第一,直接调用子类:

MLSDRigid mlsr;
mlsr.InitMLSD(<#const cv::Mat &oriImg#>, <#const std::vector<cv::Point2i> &src_pt#>);

第二,调用父类,然后指针操作

    MLSDeformation *mls;
mls = new MLSDAffine;
mls->InitMLSD(src,src_pt,alpha, gridsize);

甚至可以写成switch case语句,不同的条件下,mls new不同的子类,然后调用他的method。

c++ 一个h文件里面定义一个主类,然后定义多个子类的更多相关文章

  1. fatal error LNK1169: 找到一个或多个多重定义的符号或多个.c/.cpp文件想同时调用定义在.h文件里面的全局变量,防止重定义变量问题。

    为什么.h文件中不能定义全局变量? 原因: 存在多次创建变量.如果头文件中可以定义全局变量,那么每个包含该头文件的文件里都会有该全局变量的定义.因为C语言的include是直接将文件嵌入到includ ...

  2. 一个Java文件至多包含一个公共类

    编写一个java源文件时,该源文件又称为编译单元.一个java文件可以包含多个类,但至多包含一个公共类,作为编译时该java文件的公用接口,公共类的名字和源文件的名字要相同,源文件名字的格式为[公共类 ...

  3. PyCharm在同一个包(package)下,如何把一个.py文件导入另外一个.py文件下

    PyCharm在同一个包(package)下,如何把一个.py文件导入另外一个.py文件下 在同一个包下只需要用import 掉以后就可以找到模块所在的位置,但是如果不在同一个包下,在需要返回父级调用 ...

  4. Java中主类中定义方法加static和不加static的区别

     Java中主类中定义方法加static和不加static的区别(前者可以省略类名直接在主方法调用(类名.方法),后者必须先实例化后用实例调用) 知识点:1.Getter and Setter 的应用 ...

  5. 解决Android studio生成H文件时报找不到类文件错误

    今天整理思路时觉得在native直接调用java的方法显示这个办法挺不错 于是就用到了生成H文件 可能我的编译环境和他们的不一样 网上的教程如下 javah -d ../jni com.jm.prom ...

  6. 编辑一个.bat文件来启动一个.erl的程序?

    新建文本输入:"D:\DY\erl\erl5.10.2\bin\erl.exe" -noshell -s convert get_request   保存为xx.bat.. 解释: ...

  7. Java基础(42):Java中主类中定义方法加static和不加static的区别(前者可以省略类名直接在主方法调用,后者必须先实例化后用实例调用)

    package lsg.ap.april4th2; /* 知识点:1.Getter and Setter 的应用 2.局部变量与成员变量(也可叫做全局变量) 3.Static关键字的用法 a.成员变量 ...

  8. 定义类Human,具有若干属性和功能;定义其子类Man、Woman; 在主类Test中分别创建子类、父类和上转型对象,并测试其特性。

    package com.hanqi.test; public class Humen { private String speak; private String read; private Stri ...

  9. C++学了这么多年,你也许不知道为什么类定义要放在.h文件,类实现放在cpp文件。它们如何关联?

    原文  http://blog.csdn.net/ithzhang/article/details/8119286 主题 C++  C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类 ...

随机推荐

  1. Web大前端面试题-Day8

    1. 说说你对作用域链的理解? 作用域链的作用是保证执行环境里 有权访问的变量和函数是有序的, 作用域链的变量只能向上访问, 变量访问到window对象即被终止, 作用域链向下访问变量是不被允许的; ...

  2. PlantUML windows android

    dot执行程序. 渲染 url 连接(花费大量时间) 错误 和 语法注释 (是还在实验的) 缓存大小 5 在键入和渲染之间的延迟 (毫秒) 100

  3. LOJ.115.[模板]无源汇有上下界可行流(Dinic)

    题目链接 参考:http://blog.csdn.net/clove_unique/article/details/54884437 http://blog.csdn.net/wu_tongtong/ ...

  4. python3基础之文件对象操作

    1.向文本文件中写入内容 s = 'Hello world\n文本文件的读取方法\n文本文件的写入方法\n' # 需要写入文件的字符串 print('显示需要写入的内容:\n{0:s}'.format ...

  5. [HAOI2016]食物链

    OJ题号:BZOJ4562.洛谷3183 思路:记忆化搜索. 本体可以转化成“求有向图中入度为0的结点到出度为0的结点的路径数”. 每次加边时记录每个结点的入度和出度,然后从入度为0的结点开始搜索,搜 ...

  6. js签名

    <!doctype html><html lang="en"> <head> <meta charset="UTF-8" ...

  7. SSH三大框架的原理和核心(转)

    一.Struts2的工作流程:1.用户在客户端发起请求,客户端会初始化一个servlet容器请求:2.servlet容器把请求会传递给context容器,context容器找到目标web工程.3.进行 ...

  8. Voltage Level-Shifter Output Waveform

    http://www.cypress.com/knowledge-base-article/interfacing-sram-jtag-signals-using-voltage-level-shif ...

  9. mui 总结

    出框框 js内容 mui(".mui-popover").popover('toggle');         点击“弹出框框”就会弹出这个有class="mui-pop ...

  10. kubeadm安装kubernetes V1.11.1 集群

    之前测试了离线环境下使用二进制方法安装配置Kubernetes集群的方法,安装的过程中听说 kubeadm 安装配置集群更加方便,因此试着折腾了一下.安装过程中,也有一些坑,相对来说操作上要比二进制方 ...