编码小技巧
1,根据类里面的某个参数排序类
sort(vpKFs.begin(),vpKFs.end(), KeyFrame::lId);
static bool lId(KeyFrame* pKF1, KeyFrame* pKF2)
{
return pKF1->mnId < pKF2->mnId;
}
//类的排序也可以用Lam的方式
//返回所有关键帧
vector<KeyFrame*> vpKFs = mpMap->GetAllKeyFrames();
void GetAllKeyFrames()
{
return vector<KeyFrame*>(mspKeyFrames.begin(),mspKeyFrames.end());
}
sort(vpKFs.begin(),vpKFs.end(), KeyFrame::lId); //返回的关键帧进行排序
//初始化地图点
std::vector<MapPoint*> mvpMapPoints ;
mvpMapPoints = vector<MapPoint*>(N, static_cast<MapPoint*>(NULL));
1.1 map存储key和value,现在想根据value对map里面的key进行排序。
map<KeyFrame*,int>KFcounter;
vector<pair<int,KeyFrame*> > vPairs; //将map转为vector,用vector来排序
for(map<KeyFrame*,int>::iterator mit = KFcounter.begin(), mend=KFcounter.end(); mit!=mend; mit++)
{
vPairs.push_back(make_pair(mit->second,mit->first));
}
sort(vPairs.begin(),vPairs.end()); // sort函数默认升序排列
// 将排序后的结果用list存储,方便查找
list<KeyFrame*> lKFs;
list<int> lWs;
for(size_t i=0; i < vPairs.size();i++)
{
// push_front 后变成了从大到小顺序
lKFs.push_front(vPairs[i].second);
lWs.push_front(vPairs[i].first);
}
//与当前帧的共视关键帧中权重从大到小排序后的关键帧
std::vector<KeyFrame*> mvpOrderedConnectedKeyFrames = vector<KeyFrame*>(lKFs.begin(),lKFs.end());
std::vector<int> mvOrderedWeights = vector<int>(lWs.begin(), lWs.end());
2,sleep() Sleep() unsleep()
#include <unistd.h> //头文件
功 能: usleep() ,能把进程挂起一段时间, 单位是微秒
Sleep() ,执行挂起指定的毫秒()
sleep(),执行挂起指定的秒
1s = 1000ms
1ms = 1000us
3,使用Opencv读取和写入文件,新建一个文档编写。
4,
//cvRound : 返回个参数最接近的整数值
//cvFloor返回不大于参数的最大整数值,cvCeil返回不小于参数的最小整数值,cvRound则是四舍五入
mnFeaturesPerLevel[level] = cvRound(nDesiredFeaturesPerScale);
5,std::copy(start, end, std::back_inserter(container));
copy只负责复制,不负责申请空间,所以复制前必须有足够的空间
添加链接描述看这个说明。
eg1:
int a[3] = {1, 2, 3};
int b[3];
std::copy(a, a+3, b);
for(int j=0; j<3; j++)
cout<< b[j] << endl;
eg2:
vector temp(3);
int a[3] = {1, 2, 3};
std::copy(a, a+3, &temp.front());
for(int j=0; j<3; j++)
cout<< temp[j] << endl;
eg3:
const int npoints = 512;
const Point* pattern0 = (const Point*)bit_pattern_31_;
std::vector<cv::Point> pattern;
//使用std::back_inserter的目的是可以快覆盖掉这个容器pattern之前的数据
//其实这里的操作就是,将在全局变量区域的、int格式的随机采样点以cv::point格式复制到当前类对象中的成员变量中
std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
6
// 存储所有的特征点,注意此处为二维的vector,第一维存储的是金字塔的层数,第二维存储的是那一层金字塔图像里提取的所有特征点
vector < vector<KeyPoint> > allKeypoints;
allKeypoints.resize(nlevels);
vector<KeyPoint> & keypoints = allKeypoints[level];
// 这样子存入keypoints 这个vector就好了。
7 cv::KeyPoint 的一些特性
cv::KeyPoint* pKP = &vNodeKeys[0];
float maxResponse = pKP->response; //特征点的响应值。
vector<KeyPoint> & keypoints = allKeypoints[level];
keypoints[i].pt.x //像素坐标u
keypoints[i].pt.y //像素坐v
keypoints[i].octave=level; //金字塔第几层
keypoints[i].size = scaledPatchSize; //记录计算IC_angle方向的patch半径(灰度质心法的半径)
keypoint[i].angle ;//IC_angle方向 angle是角度制
cv::Point2f p//描述一个特征点
p.x p.y //特征点x坐标,y坐标
8,ICangle计算的是角度
//获得这个特征点所在的图像块的中心点坐标灰度值的指针center
const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));
image.at<uchar> (cvRound(pt.y), cvRound(pt.x)) //获得改点的灰度值。
//如果是Point的点获取该点的灰度值
cv::Point2f p;
float pp = image.at<uchar>(p); //p就已经包含了x ,y信息。
cv::KeyPoint q;
for (int u = -HALF_PATCH_SIZE; u <= HALF_PATCH_SIZE; ++u)
{
//注意这里的center下标u可以是负的!中心水平线上的像素按x坐标(也就是u坐标)加权
//先存第0行,这一行的v为0;
m_10 += u * center[u];
}
int step = (int)image.step1();
for (int v = 1; v <= HALF_PATCH_SIZE; ++v)
{
//本来m_01应该是一列一列地计算的,但是由于对称以及坐标x,y正负的原因,可以一次计算两行
int v_sum = 0;
// 获取某行像素横坐标的最大范围,注意这里的图像块是圆形的!
int d = u_max[v];
//在坐标范围内挨个像素遍历,实际是一次遍历2个
// 假设每次处理的两个点坐标,中心线下方为(x,y),中心线上方为(x,-y)
// 对于某次待处理的两个点:m_10 = Σ x*I(x,y) = x*I(x,y) + x*I(x,-y) = x*(I(x,y) + I(x,-y))
// 对于某次待处理的两个点:m_01 = Σ y*I(x,y) = y*I(x,y) - y*I(x,-y) = y*(I(x,y) - I(x,-y))
for (int u = -d; u <= d; ++u)
{
//得到需要进行加运算和减运算的像素灰度值
//val_plus:在中心线下方x=u时的的像素灰度值
//val_minus:在中心线上方x=u时的像素灰度值
int val_plus = center[u + v*step], val_minus = center[u - v*step];
//在v(y轴)上,2行所有像素灰度值之差
v_sum += (val_plus - val_minus);
//u轴(也就是x轴)方向上用u坐标加权和(u坐标也有正负符号),相当于同时计算两行
m_10 += u * (val_plus + val_minus);
}
//将这一行上的和按照y坐标加权
m_01 += v * v_sum;
}
return fastAtan2((float)m_01, (float)m_10); //fastAtan2计算得出的是角度 atan2计算得出的是弧度,openCV存储的angle是角度
9,计算时间
#include <chrono>
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
cout << "extract ORB cost = " << time_used.count() << " seconds. " << endl;
10 Mat
//这里的step1表示这个图像一行包含的字节总数。参考[https://blog.csdn.net/qianqing13579/article/details/45318279]
int step = (int)image.step1();
//Mat的博客
https://blog.csdn.net/giantchen547792075/article/details/9107877
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。