历史上的今天
今天是:2024年08月26日(星期一)
2021年08月26日 | 飞思卡尔--Matlab图像矫正估算赛道长度
2021-08-26 来源:eefocus
由于参加飞思卡尔智能车比赛,铺赛道变成了一个重要的环节。而此次铺赛道用了过去留下的赛道进行拼接,导致赛道的长度不好计算,因此,博主与小伙伴想了一些办法估算长度,下面介绍Matlab图像矫正估算赛道长度的方法。
首先由于赛道过长的原因,无法获得整个赛道的图,俯视图则更不为可能。因此,本次方法为采集两张图片进行分别处理计算再相加。图片如下图所示。代码在文末链接,供参考改进。

接着我们截取我们需要的部分(以下以一边赛道为例)。

1.然后我们取该赛道的灰度值

2.接着再进行图像的矫正

3.进行初次的去噪(补充横线的白点)

4.对全黑的矩阵用双线法进行补充。(此处为关键,也可用最近邻插值法,由于博主在此处的算法较为粗略,因此算法复杂度高,且处理效果一般,改进空间较大)

5.对改图进行二值化

6.观察图像,再次去噪

7.最终效果图(该图左边反光较大,可再次进行处理)

PS:下图为用PS矫正后的图像(效果更好)。

用同样的方法可以得出另一半赛道的图片。
得出了二值化的矩阵之后,可利用面积法算出赛道的长度。首先计算出所有白点的个数。由于赛道的宽度是已知的(去掉两边的路肩共40cm),于是可以取一小段直道取其行的平均值,就可以算出赛道的宽度共占多少个像素点,也就可以算出一个像素点占多大的长度,再用总像素点除以每行所占像素点再乘以每个像素点的长度,即可大致得出赛道长度(由于再某些地方(十字和环岛)白像素点重叠了,因此最后再加上这些值即为赛道总长度。
用改方法算出的赛道长度大约为55米左右,用PS矫正后的图片则算出57米左右,而用车跑圈,利用编码器计数则算出56米左右。可见该方法还是存在一定的可行性的。
clear clc
point = 1.5;
point_long = 5;
value = 0.38 * 255;%初次去噪阈值
value2 = 0.45;%二次去噪阈值
%%%%%%%%%%%%%%%%读图%%%%%%%%%%%%%%%%
img= imread('2222.jpg?imageView2/2/w/550');
img = rgb2gray(img);%求灰度值
imshow(img);
[left,down] = size(img);%读取图像大小
left1 = 800;%定义新矩阵长度
down1 = ceil((down / 2) * point * 2);%定义矩阵长度
img2 = uint8(zeros(left1,down1));%创建全黑矩阵
flag = down / 2;
flag2 = down1 / 2;
left_last = 1;
left_ans = 1;
%%%%%%%%%%%%%%%%图像透视变换%%%%%%%%%%%%%%%%
for n = 1:left
point_left = ((left - n) * ((point - 1) / (left - 1))) + 1;
if n == 1
else
dis_bet = (point_long / (left - 1)) * (left - n) * 1 + 1;
left_ans = round(left_last + dis_bet);
left_last = left_ans;
end
for m = (down/2) : down
down_flag = (m - flag) * point_left + flag2;
down_ans = round(down_flag);
img2(left_ans,down_ans) = img(n,m);
end
for m = 1 : (down/2)
down_flag = flag2 - (flag - m) * point_left;
down_ans = round(down_flag);
img2(left_ans,down_ans) = img(n,m);
end
end
figure
imshow(img2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%初次去噪,将黑点变全白%%%%%%%%%%%%%%%%
for n = 1:(left_last)
for m = 3:(down1)
if (img2(n,m-2) >= value ) && (img2(n,m-1)
img2(n,m-1) = 255;
end
end
end
figure
imshow(img2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%双线性填充图像%%%%%%%%%%%%%%%%
for n = 5:(left_last - 2)
for m = 5:(down1 - 2)
if img2(n,m) == 0
sum = img2(n-1,m-1) + img2(n+1,m+1) + img2(n-1,m+1) + img2(n+1,m-1);
point_num = sum / 2;
img2(n,m) = point_num;
end
end
end
figure
imshow(img2);
I2 = im2bw(img2,value2);%二值化
figure
imshow(I2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%二次去噪1%%%%%%%%%%%%%%%%
for n = 3:(left_last)
for m = 3:(down1)
if (I2(n-2,m) == 0) && (I2(n-1,m) == 1) && (I2(n,m) == 0)
I2(n-1,m) = 0;
end
end
end
figure
subplot(2,2,1);imshow(I2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%二次去噪2%%%%%%%%%%%%%%%%
for n = 3:(left_last)
for m = 3:(down1)
if (I2(n,m-2) == 0) && (I2(n,m-1) == 1) && (I2(n,m) == 0)
I2(n,m-1) = 0;
end
end
end
subplot(2,2,2);imshow(I2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%二次去噪3%%%%%%%%%%%%%%%%
for n = 3:(left_last)
for m = 3:(down1)
if (I2(n,m-2) == 1) && (I2(n,m-1) == 0) && (I2(n,m) == 1)
I2(n,m-1) = 1;
end
end
end
subplot(2,2,3);imshow(I2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%二次去噪4%%%%%%%%%%%%%%%%
for n = 3:(left_last)
for m = 3:(down1)
if (I2(n-2,m) == 0) && (I2(n-1,m) == 1) && (I2(n,m) == 0)
I2(n-1,m) = 0;
end
end
end
subplot(2,2,4);imshow(I2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure
imshow(I2);
white = 0;
for n = 1:left_ans
for m = 1:down1
if I2(n,m) == 1
white = white + 1;
end
end
end
上一篇:飞思卡尔运动小车前方道路识别
史海拾趣
|
1.登陆EEWORLD论坛,进入旧版首页,在右上角找到“控制面板”,点击控制面板,如下图: 2.点击“访问推广”,进入如下图所示界面: 按照提示操作,将您的推广链接1或者2均可,发送给您的朋友,当您的朋友访问该链接,并注册成为新会员, ...… 查看全部问答> |
|
驱动加载程序中,在StartService()后,通过GetLastError()返回3错误(〖3〗-系统找不到指定的路径。) 驱动加载程序中,在StartService()后,通过GetLastError()返回3(〖3〗-系统找不到指定的路径。) 在虚拟机运行的,一开始是好的,暂停第二次打开 ,无论如何加载时运行到StartService()后的GetLastError()返回都是 ...… 查看全部问答> |
|
也来秀一下DIY,160*80带触摸液晶模块做的多功能时钟~~~~~~ 哈哈,其实这个屏是去年电赛的时候买的,正好也用上了,不过用得比较简单,感觉有点可惜了就干脆做了一个完整的模块,估计有的朋友还记得之前小弟发的第一次做PCB的帖子吧,就是给这个做的,这个是当时的链接 https://bbs.eeworld.com.cn/thre ...… 查看全部问答> |
|
我按照图上的电路做了一个充电器(图中的r12,r20我改为两个0.1/5w的电阻了),充10AH/24V的镍氢动力电池,但是在试验中发现随着充电电压的升高,电流在慢慢下降,达不到恒流,例如:24v电池理论充电终止电压是29v,但是在电 ...… 查看全部问答> |




