漫水填充法

漫水填充法是一种用特定的颜色填充联通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果的方法。漫水填充经常被用来标记或分离图像的一部分以便对其进行进一步处理或分析,也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或只处理掩码指定的像素点,操作的结果总是某个连续的区域。

阅读更多...

SLAM概述

SLAM首先要解决自主运动的两大基本问题

  1. 我在什么地方?——定位
  2. 周围环境是什么子?——建图

SLAM与定位与建图又有着联系:内外兼修 ;定位侧重对自身的了解,建图侧重对外在的了解;它与两者又相互关联;准确的定位需要精确的地图;精确的地图来自准确的定位。

阅读更多...

处理H自由度的不同方法

视觉-惯性状态估计过程中有四个自由度需要进行额外处理,它们是一个平移变量(3个自由度)和绕重力轴方向的旋转(1个自由度)。

视觉惯性状态估计最多可以达到四自由度的转换(围绕重力的旋转和平移),因此必须正确处理额外的自由度 。尽管在实践中使用了不同方法处理多余自由度,但没有任何研究来系统地分析它们的差异。本文介绍了在基于优化的视觉惯性状态估计中处理量测自由度的不同方法的对比分析。通过实验比较了三种常用方法:

  1. 将不可观察的状态固定为给定值,
  2. 在这些状态上设置先验
  3. 在优化过程中让状态自由地优化。

实验表明:

  1. 三种方法的准确性和计算时间相似,自由量测方法稍快一些;
  2. 自由优化法的协方差估计似乎有很大的不同,但实际上与其他方法紧密相关。
阅读更多...

OpenCV_Function

图像操作

遍历图像的四种方式

  1. at<typename>(i,j)

Mat类提供了一个at的方法用于取得图像上的点,它是一个模板函数,可以取到任何类型的图像上的点。下面我们通过一个图像处理中的实际来说明它的用法。

1
2
3
4
5
6
7
8
9
void colorReduce(Mat& image,int div){
for(int i=0;i<image.rows;i++){
for(int j=0;j<image.cols;j++){
image.at<Vec3b>(i,j)[0]=image.at<Vec3b>(i,j)[0]/div*div+div/2;
image.at<Vec3b>(i,j)[1]=image.at<Vec3b>(i,j)[1]/div*div+div/2;
image.at<Vec3b>(i,j)[2]=image.at<Vec3b>(i,j)[2]/div*div+div/2;
}
}
}
  1. 用指针来遍历图像

我们实际喜欢把原图传进函数内,但是在函数内我们对原图像进行了修改,而将原图作为一个结果输出,很多时候我们需要保留原图,这样我们需要一个原图的副本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 1 void colorReduce(const Mat& image,Mat& outImage,int div)
2 {
3 // 创建与原图像等尺寸的图像
4 outImage.create(image.size(),image.type());
5 int nr=image.rows;
6 // 将3通道转换为1通道
7 int nl=image.cols*image.channels();
8 for(int k=0;k<nr;k++){
10 // 每一行图像的指针
11 const uchar* inData=image.ptr<uchar>(k);
12 uchar* outData=outImage.ptr<uchar>(k);
13 for(int i=0;i<nl;i++){
15 outData[i]=inData[i]/div*div+div/2;
16 }
17 }
18 }
  1. 使用迭代器来遍历图像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 1 void colorReduce(const Mat& image,Mat& outImage,int div)
2 {
3 outImage.create(image.size(),image.type());
4 MatConstIterator_<Vec3b> it_in=image.begin<Vec3b>();
5 MatConstIterator_<Vec3b> itend_in=image.end<Vec3b>();
6 MatIterator_<Vec3b> it_out=outImage.begin<Vec3b>();
7 MatIterator_<Vec3b> itend_out=outImage.end<Vec3b>();
8 while(it_in!=itend_in)
9 {
10 (*it_out)[0]=(*it_in)[0]/div*div+div/2;
11 (*it_out)[1]=(*it_in)[1]/div*div+div/2;
12 (*it_out)[2]=(*it_in)[2]/div*div+div/2;
13 it_in++;
14 it_out++;
15 }
16 }
  1. 最高效的方法

当不对行进行填补的时候,图像可被视为一个长为W x H的一维数组。用isContinuous来判断是否对行进行的填补。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int n1 = image.rows;
int nc = image.cols * image.channels();
ifimage.isContinuous())//判断是否对行有额外的填补像素,返回值为真,则没有填补。
{
nc = nc * n1;
n1 = 1;
}
forint i = 0; i <n1; i ++)//若图像是连续的,则只循环一次
{
uchar * data = image.ptr <uchar>(i);
forint j = 0; j <nc; j ++)
{
data [j] = 0;
}
}
  • © 2019-2022 guoben
  • PV: UV:

微信