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

#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. AFP溢出攻击模块afp/loginext

    AFP溢出攻击模块afp/loginext   在苹果Mac OS X 10.3.3及以前版本,AFP服务存在缓存区溢出漏洞CVE-2004-0430.利用该漏洞,用户可以基于LoginExt包执行任 ...

  2. L1 与 L2 正则化

    参考这篇文章: https://baijiahao.baidu.com/s?id=1621054167310242353&wfr=spider&for=pc https://blog. ...

  3. struts2标签在jsp页面中构建map集合,循环显示

    <s:radio name="gender" list="{'男', '女'}"></s:radio> <s:select nam ...

  4. 关于Android studio团队协同开发连接到已有项目

    当团队中已经有人创建好项目的时候,队员想把自己的as与码云上项目相互连接时,有两种方法: 方法一: 进入as初始页面: 分别点击:check out project from Version cont ...

  5. 如何调整eclipse中代码字体大小

    找到windows--->preferences---->General------>Appearance---->color   and fonts   ---->ba ...

  6. saltstack 命令2

    在Salt主机上,可以快速查看所有Salt minion连接,并查看连接是否被接受,拒绝或挂起 [root@node1 ~]# salt-key -L 接受所有的key [root@node1 ~]# ...

  7. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) B - Bear and Friendship Condition 水题

    B. Bear and Friendship Condition 题目连接: http://codeforces.com/contest/791/problem/B Description Bear ...

  8. 域名DNS解析工具ping/nslookup/dig/host

    常见 DNS 记录的类型 类型 目的 A 地址记录,用来指定域名的 IPv4 地址,如果需要将域名指向一个 IP 地址,就需要添加 A 记录. AAAA 用来指定主机名(或域名)对应的 IPv6 地址 ...

  9. 前端框架React Js入门教程【精】

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...

  10. Java int转string 长度不足左补0

    最近项目中用到这个需求,我试了两个方法都可以实现 方法一:(推荐) String s=String.format("%010d", 123)//123为int类型,0代表前面要补的 ...