在openmv中有一个巡线的功能,在我刨根问底以后发现是一段C 的函数完成的这个功能,看完源码准备写Python的实现。
这个是第一个找到的关键词
我们整体思路还是按照关键字来找
这里是在源码中搜索到的所有的关于线性回归的东西
我们还是先看第一个demo吧,主要是导入的三个库,最重要的是这个image这个库,怎么说呢,承担了大部分的算法任务
这个地方也可以看到是img的方法
这个地方是我们在Openmv里面调用的地方
可以找到的是一份头文件,在里面是统计学的实现
这个是我们关心的函数
我加了一下注释,我们先去看看实现
刚刚看头,现在看实现
但是又没有函数,emmmm奇怪
我们进去看看有什么,看到了核函数
真正的实现在这里
可以看到几千行的代码就是写了几个算法
先看最上面,就是一些版权信息.我大哥教育我给别人的代码的时候一定要写上自己的版权,但是不要留自己的联系方式.这个文件就是实现一下数学上面的一些统计功能.下面有一个是结构体,我们开始看这个代码.
先看代码的小地图,他有这么多~
大概三百多行的程序,首先就是函数签名,已经写好了
一开始就是这两句,第一个是一个结果的布尔变量,一开始认为是关闭的
因为我C 不熟悉,这些函数我只能就看就查.可以看到是申请了一个find这个变量大小的内存空间,随便一找就找到了
第一个是line,不清不楚的一个东西,继续找
在正式的进入分析之前,我们在看一下这个函数的概览
这个地方的翻译很奇怪
百度也是
可以这样翻译吧?就是说这个地方不是感兴趣的区域,所以直接把ram的内容清空?
对不起,我滑错地方了emmmm
这个地方我们就认为打开这个开关了,下面进行了公式计算的所有的变量
具体也应该就是这个函数了,先不看
->这个符号是指针的指向运算符,通常与结构体一起使用。
代码语言:javascript复制
#include<stdio.h>
struct stu // 定义一个结构体
{
char name[10]; // 姓名
int num; // 学号
int age; // 年龄
};
void main()
{
struct stu *s; // 定义一个结构体指针
char str[]="ZhangLi";
s->name = str; // 对结构体中的成员变量name进行赋值
s->num = 2015120; // 对结构体中的成员变量num进行赋值
s->age = 18; // 对结构体中的成员变量age进行赋值
}
image.get_regression(
thresholds,invert=False,
roi,
x_stride=2,
y_stride=1,
area_threshold=10,
pixels_threshold=10,
robust=False)
函数返回回归后的线段对象line,有x1(), y1(), x2(), y2(), length(), theta(), rho(), magnitude()参数。
x1 y1 x2 y2分别代表线段的两个顶点坐标,length是线段长度,theta是线段的角度。magnitude表示线性回归的效果,它是(0, ∞)范围内的一个数字,0代表一个圆。如果场景线性回归的越好,这个值越大。
对图像所有阈值像素进行线性回归计算。这一计算通过最小二乘法进行,通常速度较快,但不能处理任何异常值。
若 robust 为True,则使用Theil-Sen线性回归算法,它计算图像中所有阈值像素的斜率的中位数。若在阈值处理后有太多像素,即使在80x60的图像上,这个O(N^2)操作也可能将您的FPS降到5帧以下。但是,只要阈值转换后的像素数量较少,即使在高达30%的阈值像素是异常值的情况下也依然有效,鲁棒性好。
thresholds 是元组列表。
[(lo, hi), (lo, hi), ..., (lo, hi)] 定义你想追踪的颜色范围.对于灰度图像,每个元组需要包含两个值 - 最小灰度值和最大灰度值.仅考虑落在这些阈值之间的像素区域. 对于RGB565图像,每个元组需要有六个值(l_lo,l_hi,a_lo,a_hi,b_lo,b_hi) - 分别是LAB通道的最小值和最大值,如果元组大于六个值,则忽略其余值。相反,如果元组太短则假定其余阈值处于最大范围。
invert 反转阈值操作,像素在已知颜色范围之外进行匹配,而非在已知颜色范围内。
roi 是感兴趣区域的矩形元组(x,y,w,h)。如果未指定,ROI即整个图像的图像矩形。操作范围仅限于 roi 区域内的像素。
x_stride 是调用函数时要跳过的x像素数。
y_stride 是调用函数时要跳过的y像素数。
如果回归后的边界框区域小于 area_threshold ,则返回None。
如果回归后的像素数小于 pixel_threshold ,则返回None。
啊
整个代码,我们可以分为5部分其实:
- 一开始是进行代码的初始段,进行内存的申请,变量的创建
- 然后去自动来判断传进来的img是什么类型的,需要去转换
- 注意的一点是需要传入二值化的图像
- 接着就是看这个鲁棒性的参数
- 假的话,直接最小二乘法,但是要求图像很干净
- 真的话,会用Theil-Sen线性回归算法,它计算图像中所有阈值像素的斜率的中位数。
即使是开了第二个算法也还是要进行算法的处理
这个是我们处理的一些注意的事项
开始正式的看,是一个for循环.下面是要不停执行的代码
这个是一个可迭代的函数,其实这些函数是通用的数据结构
我怕C 和其他的语言不一样,就看了看语法
看这个地方,开始对传入的图像要进行处理了.现在来看图像的种类