本人在做目标跟踪方面的编程。以下是我对目标设计的一个类。该类会被经常使用到,且用于vector,list,map三种容器中,赋值,查找,添加,遍历都会用到。现在分析每一帧耗时不满足要求,分辨率大时无法达到实时的需求。
我一直在改进,使用引用,指针,std::move等等。已经优化不下去了。请各位帮忙研究研究:看这个类设计能不能再改进,有什么可优化的地方?
另外:对于编程中程序性能的提高,有什么好方法,也可讨论讨论。
#ifndef MOVING_OBJECT_H
#define MOVING_OBJECT_H
#include <list>
#include <opencv2/core/core.hpp>
class MovingObject
{
public:
explicit MovingObject(const int ID, const cv::Rect rc);
MovingObject(const MovingObject &object);//拷贝构造函数
MovingObject& operator = (const MovingObject& object);//赋值函数
bool operator ==(const MovingObject &rth) const;
bool operator !=(const MovingObject &rth) const;
bool operator <(const MovingObject &rth) const;
//move构造函数
MovingObject(MovingObject&& object);
MovingObject& operator=(MovingObject&& object);
~MovingObject(void);
private:
int id_;//目标标识,大于0表示活跃目标,小于0表示休眠目标
cv::Rect rect_;//目标区域,每帧更新
cv::Point point_;//目标中心点,每帧更新
std::list<cv::Point> trajectory_;//目标轨迹 //三个属性值,用于跟踪
int active_val_;//活跃值
int dormancy_val_;//休眠值
int life_val_;//生命期
bool is_match_;//当前帧是否匹配成功(由object_tracking类调用)
public:
void UpdataTrack(const cv::Rect rc);//更新轨迹
void UpdataAttributeValue(bool isobjectexist);//更新属性值 int get_active_val(void) const { return active_val_ ;}
int get_dormancy_val(void) const { return dormancy_val_ ;}
int get_life_val(void) const { return life_val_ ;}
int get_id(void) const { return id_; }
cv::Rect get_rect(void) const { return rect_; }
cv::Point get_point(void) const { return point_; }
std::list<cv::Point> get_trajectory(void)const { return trajectory_; };
bool get_ismatch(void) const { return is_match_; } void set_ismatch(bool ismatch){is_match_=ismatch; }
void set_id(int id){id_=id;}
void DrawTrajectory(cv::Mat img, int len=10, double rate=1., cv::Scalar color=cv::Scalar(0,0,255)) const;
};
#endif //MOVING_OBJECT_H
#include "movingobject.h"#define MAX_TRAJECTORY 150 //轨迹最大长度
#define ACTIVE_THRE 5//大于此值目标为活跃
MovingObject::MovingObject(const int ID, const cv::Rect rc )
    :active_val_(1)
    ,dormancy_val_(0)
    ,life_val_(1)
    ,is_match_(true)
{
    this->id_=ID;
    this->rect_=rc;
    this->point_=cv::Point(rc.x+rc.width/2,rc.y+rc.height/2);
    this->trajectory_.push_front(this->point_);
}MovingObject::MovingObject( const MovingObject &object )
{
    id_=object.get_id();
    point_=object.get_point();
    rect_=object.get_rect();
    trajectory_=object.get_trajectory();
    active_val_=object.get_active_val();
    dormancy_val_=object.get_dormancy_val();
    life_val_=object.get_life_val();
    is_match_=object.get_ismatch();
}MovingObject::MovingObject( MovingObject&& object )
:id_(std::move(object.get_id()))
,point_(std::move(object.get_point()))
,rect_(std::move(object.get_rect()))
,trajectory_(std::move(object.get_trajectory()))
,active_val_(std::move(object.get_active_val()))
,dormancy_val_(std::move(object.get_dormancy_val()))
,life_val_(std::move(object.get_life_val()))
,is_match_(std::move(object.get_ismatch()))
{}MovingObject& MovingObject::operator=(MovingObject&& object){
if (this == &object) {
return *this;
}
id_=std::move(object.get_id());
point_=std::move(object.get_point());
rect_=std::move(object.get_rect());
trajectory_=std::move(object.get_trajectory());
active_val_=std::move(object.get_active_val());
dormancy_val_=std::move(object.get_dormancy_val());
life_val_=std::move(object.get_life_val());
is_match_=std::move(object.get_ismatch());
return *this;
}MovingObject& MovingObject::operator=( const MovingObject& object )
{
    if (this == &object) {
        return *this;
    }
    id_=object.get_id();
    point_=object.get_point();
    rect_=object.get_rect();
    trajectory_=object.get_trajectory();
    active_val_=object.get_active_val();
    dormancy_val_=object.get_dormancy_val();
    life_val_=object.get_life_val();
    is_match_=object.get_ismatch();
    return *this;
}bool MovingObject::operator ==(const MovingObject  &rth) const
{
    return id_==rth.get_id();
}
bool MovingObject::operator !=(const MovingObject &rth) const
{
    return id_!=rth.get_id();
}bool MovingObject::operator<( const MovingObject &rth ) const
{
    return id_<rth.get_id();
}MovingObject::~MovingObject(void)
{
}void MovingObject::UpdataTrack(const cv::Rect rc )
{
    this->is_match_=true;//更新轨迹意味着匹配成功
    this->rect_=rc;
    this->point_=cv::Point(rc.x+rc.width/2,rc.y+rc.height/2);
    trajectory_.push_front(this->point_);
    if (trajectory_.size()>=MAX_TRAJECTORY) {
        trajectory_.pop_back();
    }
}void MovingObject::UpdataAttributeValue( bool isobjectexist )
{
    if (isobjectexist) {
        ++active_val_;
        dormancy_val_=0;
        ++life_val_;
    } else {
        active_val_=0;
        ++dormancy_val_;
    }
}//画轨迹:img画布,color颜色,len轨迹最长点数
void MovingObject::DrawTrajectory( cv::Mat img, int len/*=10*/ , double rate/*=1.*/,cv::Scalar color/*=Scalar(0,0,255)*/)const
{
    if (trajectory_.size()<ACTIVE_THRE) {
        return;
    }
    cv::Point start,end;
    std::list<cv::Point>::const_iterator it=trajectory_.cbegin();
    std::list<cv::Point>::const_iterator it_end=trajectory_.cend();
    start=(*it)*rate;
    ++it;
    int index=0;
    while(it!=it_end && index<len) {
        end=(*it)*rate;
        line(img,start,end,color);
        start=end;
        ++it;
        ++index;
    }
}类设计优化目标类目标跟踪

解决方案 »

  1.   

    现在有个想法是对数据成员改为public,赋值时直接=,不使用成员函数。但这破坏了类的封装性
      

  2.   

    #pragma once// CDemo 命令目标class CDemo : public CObject
    {
    int a;
    public:
    CDemo& CDemo::operator=( const CDemo& object )
    {
    if (this == &object) {
    return *this;
    }
    this->a = object.a;
      return *this;
    }
    CDemo();
    virtual ~CDemo();
    };编译通过
      

  3.   

    容器中是指使用程序中会使用vector<MovingObject>,list<map>,map<MovingObject,int>这样的变量,这些变量在插入等操作中会产生MovingObject的赋值操作。故怀疑这些操作多会耗时,可优化。
    其他函数也在优化,现在优化到这个类,拿出来让大家看有没有可能再优化。
      

  4.   

    你滥用对象,存在很多对象构造销毁拷贝复制的开销,可以优化的余地很多,比如
        this->point_=cv::Point(rc.x+rc.width/2,rc.y+rc.height/2);
        trajectory_.push_front(this->point_);
    两个地方都保留同一个对象,可以考虑一个地方改成指针;
    void MovingObject::DrawTrajectory( cv::Mat img, int len/*=10*/ , double rate/*=1.*/,cv::Scalar color/*=Scalar(0,0,255)*/)const
    第一个参数应该改成引用
      

  5.   

    void MovingObject::DrawTrajectory( cv::Mat img, int len/*=10*/ , double rate/*=1.*/,cv::Scalar color/*=Scalar(0,0,255)*/)const
    Scalar color参数也是对象,应该改成引用