Part 1.项目背景

许多城市历史悠久,排水系统老旧、结构复杂,在暴雨频发的时期,因破损或淤积不畅,造成城市道路内涝频发,不仅对交通造成严重阻塞,还大大增加了发生安全事故的风险。人工清淤工作环境恶劣,在排水管道内存在毒气、尖锐杂物等不可控的危险因素,因此,能取代人工操作进行清淤工作的清淤机器人的应用前景广泛而需求迫切。本课程设计对清淤机器人的图像识别与淤积物分拣技术进行研究,以软件的形式实现对硬质积淤物和有色垃圾的分拣处理,达到减少清淤仪器损害并高效、低成本清淤的目的。

Part 2.整体设计

本清淤机器人的用途为检查小口径管道内部情况(通过传感器和图像识别技术反馈有毒气体、内部淤积物形态、管道结构等信息),将其运动方向前方的淤积物铲入机身,在机身内将淤积物进行初步拆解分散,识别易沉积、体积较大的固体物质(如石块、泥沙集团),并将其分拣入存储室内,将易流通的杂质(如可溶有机物、细小泥沙)排至机器人运动方向的后方。待机器人走向另一端井口时,工作人员将其取上地面,然后对管道剩余淤积物进行冲刷,在机器人的存储室经过清理后方可继续使用。

机器人大致结构图如下所示,手绘较丑,可以凑合看看(说来惭愧,初中差点走上美术生的道路):

然后让同组的Partner用CAD画了一张正经点的图:

OK,机器人到手了,可以开始干活了,本文主要讲解机器人检测横截面为方形或者可以近似方形的下水管道的横截面积,系统根据横截面积大小,结合工作人员(软件用户)对积淤物分拣的要求(指令)进行分拣,对硬质积淤物含量和白色垃圾含量在设定分拣范围内的积淤物分拣入机器人存储室内,对含量不在设定分拣范围内的积淤物直接排放回管道。

刚开始接触这份课设,本想将题目定为基于深度学习的分拣识别系统(名字高大上,看起来牛逼),然后基于图像识别,使用深度学习技术找出符合要求的积淤物特征,然后通过训练、拟合……(老方法啦)。然鹅,对于我们课设所关注的硬质积淤物,上面往往覆盖油污、泥土等物质,怎么能够通过视觉的方式去检测呢?对于有色垃圾,尤其是城市排水管道常见的有色塑料袋,在混杂与其他积淤物的情况下,形态都是未知数,即使是人脸,如果只用一张照片作为训练集,想通过同一个人不同夸张表情的照片确定他的身份,也是有难度的,更何况垃圾的形态跟人的表情相比,更是千奇百怪,难以捕捉特征。

所以,最终选定的方案无需使用深度学习这么麻烦 ,系统也是越简单越好:

首先是测量工作:清淤机器人中部有摄像机,它具有接收光学信息的作用,定义机器人进入的垂直管道口一端为始端,机器人走过行径路线之后被工作人员捞取的垂直管道口为终端。当机器人进入始端的横向管道口后,工作人员在终端管道口插入一个激光发射装置,如图所示,在发出激光后,若清淤机器人的摄像头没有接收到光源信息,则说明管道存在高度超过管道半径50%的堆积物,将此信息和有毒有害气体监测信息传给地面工作人员,工作人员可根据摄像头拍摄到的管道具体情况酌情发送指令给机器人,让其继续操作或者停止操作。若清淤机器人可接收激光信息,则说明管道不存在高度超过管道半径50%的堆积物,工作人员使用机械装置将堵塞装置塞入始端和末端的横向管道,避免流入污水和淤积物干扰清理工作。

1).大型硬质积淤物(砖头、钢筋等)的识别:基于接触式传感识别方法,采用的传感器是一个矩形板,板上附有密集的弹簧击针,传感器位于机身顶面,在积淤物进入机身后,传感器向下压积淤物,直至压至最大限度,若是软质物,弹簧击针很少发生弹性形变,而硬质物会使弹簧击针发生较大形变。记录传感器每个弹簧击针该次下压所得到的最大形变位移(硬物高度),多个弹簧击针所组成的形状即为硬物俯视图面积,由此,可计算出硬物的体积,若淤积物中硬物体积偏大,则将此次收集到的积淤物通过机械臂推入分拣物存储器;体积小则可忽视存在硬物的因素。使用这种类似蒙特卡洛法的检测手段,不仅可大致得到整体的硬物体积信息,同时,也具有松散泥沙的作用,有助于被排出泥沙的高压冲洗工作。

2).白色垃圾(有色塑料袋等)的识别:仅有淤泥、石块等天然物质的淤积物颜色往往呈褐色、黑色、灰色或土黄色,而塑料袋、瓶罐包装等塑料制品会因消费美观的营销考量,被设计为色彩丰富的亮色,如红色、蛋黄色、蓝色、绿色等,对于非自然物带有的特征颜色,将它们转化为RGB值范围。在机身上方四周布置白光照射装置,淤积物反射光线到摄像装置形成图像,读取图像每个像素的RGB值,若其RGB值在特征颜色的RGB值范围,考虑到噪声干扰,符合特征颜色的像素还要具有面积大的特点时,才能认定含有塑料垃圾,若在大型淤积物识别时未将积淤物推入存储室,则将此次收集的淤积物分拣入存储室。

Part 3.C语言代码实战

上文已写出大致设计思路,但我们还需要一个模型去模拟积淤物的形态特性,考虑到正态分布有极其广泛的实际背景,生产与科学实验中很多随机变量的概率分布都可以近似地用正态分布来描述,因此我们采用高斯(正态)分布模型对单位面积硬质积淤物的高度进行随机模拟。首先上场的是我们的C语言,下面参照这个博客的老哥写的高斯分布随机数生成函数:

https://blog.csdn.net/z_feng12489/article/details/102861094?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160662342719724818076376%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160662342719724818076376&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~baidu_landing_v2~default-3-102861094.pc_v2_rank_blog_default&utm_term=C%E8%AF%AD%E8%A8%80%E7%94%9F%E6%88%90%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83

这个博客上的高斯函数代码写的非常好,美中不足的是,您在不改变期望值、标准差的前提下多次运行后会发现——数据咋都是一样哒???其实是因为这位老哥忘了使用种子随机数,随着程序运行时间的不同而产生不同随机数,我们在写C语言代码的时候要加上。

首先放上头文件,声明高斯模型的两个子函数,声明两个宏定义——矩形传感器上的击针点分布是40*50的,对应矩形板尺寸是40cm*50cm,即每个传感击针负责1cm^2单位面积的检测

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
const int N = 40; //宽边取40个单位检测点
const int n = 50; //长边取50个单位检测点
float gaussrand_NORMAL();
float gaussrand(float Ex, float sigma);

OK,准备把机器人放入管道了,进入管道前,清淤机器人内部弹簧压缩至最小,进入管道后,弹簧伸长至机器人上下滑动轮分别紧贴管道上下内壁 ,根据弹簧伸展情况,测量机器人分拣室高度h,加上机器人外壳的高度30cm,则管道的高度为(30+h)cm。然后用机器人内在的红外激光测量仪测量管道宽度和管道长度(在程序中使用随机数模拟),并将测量结果传输给地面工作人员。

int main(){srand((unsigned)time(NULL));//设定种子随机数,使随机数随时间改变//分拣室具体高度h往往为浮点数,取20cm<=h<=50cmfloat h = 20.0+(rand()%3)*10+rand()%10+(rand()%10)/(float)10+(rand()%10)/(float)100;//管道宽度40cm<=wide<70cmfloat wide = 40.0+(rand()%3)*10+rand()%10+(rand()%10)/(float)10+(rand()%10)/(float)100;//用随机数模拟机器人分拣室高度h,20cm<=h<50cmfloat length = 1000.0+(rand()%2)*1000+(rand()%10)*100+(rand()%10)*10+rand()%10+(rand()%10)/(float)10+(rand()%10)/(float)100;//管道长度10m<=length<30m printf("———----—-—管道数据——-—----—---\n"); printf("分拣室高度:%.3f cm\n",h);printf("管道长度:%.3f cm\n",length);printf("管道高度:%.3f cm\n",h + 30.0); //管道高度=分拣室高度+30cmprintf("管道宽度:%.3f cm\n",wide);printf("管道横截面积:%.3f cm^2\n",(h + 30.0)*wide);float V = 0.0; //初始化硬物总体积//单位面积为1cm^2

然后,先列一下刚才提到的高斯分布生成随机数函数,值得注意的是,这两个函数是写在main函数外面的:

float gaussrand_NORMAL() {static float V1, V2, S;static int phase = 0;float X;if (phase == 0) {do {float U1 = (float) rand() / RAND_MAX;float U2 = (float) rand() / RAND_MAX;V1 = 2 * U1 - 1;V2 = 2 * U2 - 1;S = V1 * V1 + V2 * V2;} while (S >= 1 || S == 0);X = V1 * sqrt(-2 * log(S) / S);} elseX = V2 * sqrt(-2 * log(S) / S);phase = 1 - phase;return X;
}
float gaussrand(float Ex, float sigma) {return Ex + gaussrand_NORMAL() * sigma;
}

基于这两个函数,系统用户可以选择直接让计算机模拟正态分布,或者用户手动输入期望值(硬质积淤物平均高度)和标准差值,计算机根据用户设定的参数运行。既然符合正态分布,那么模拟的过程中总会有负数或者超出分拣室高度的数字吧?不必担心,首先,系统里有防呆措施,即如果所输的期望值超出当前符合实际的范围,系统会提醒用户“输入错误,请重新输入!”,对于生成的所有随机数,均会在取绝对值后,取分拣室高度(强制转化为int型)余数,这样就保证了模拟结果均在实际范围内。

printf("———----—-—模型参数——-—----—---\n");//生成符合高斯分布、期望值为Ex、标准差为sigma、长度为N*n的一维数组Zbool Foolproof = false; //防呆判别变量int choice;float Ex,sigma; //期望值,标准差 printf("请选择模拟方式:\n1.计算机模拟 2.手动输入数据\n");scanf("%d",&choice); if(choice==1){Ex = 20.0+(rand()%2)*10+rand()%10+(rand()%10)/(float)10+(rand()%10)/(float)100; //Ex在20~40之间取随机值sigma = rand()%10+(rand()%10)/(float)10+(rand()%10)/(float)100; //sigma在0~10之间取随机值printf("期望值Ex:%.3f\n",Ex);printf("标准差sigma:%.3f\n",sigma);}else{while(Foolproof==false){printf("请输入硬质积淤物高度期望值(<=h):");scanf("%f",&Ex);if(Ex < 0.0||Ex > h)printf("输入错误,请重新输入!\n");else Foolproof = true;}printf("请输入标准差值:");scanf("%f",&sigma);} Foolproof = false;//初始化

1).全程由计算机模拟:

2).用户手动输入数据:

由于使用Dev C++并无法将数据可视化,因此我们将运行结果导入一个很常用的数据库中——EXCEL表格:

//按照计算机随机值或用户输入参数进行模拟float Z[N][n]; //生成的图像中Z轴高度,即每个检测点检测到的硬质积淤物高度 FILE *fp;fp=fopen("积淤物数据采集.xls","w");for(int i=0; i<N; i++){for(int j=0; j<n; j++){Z[i][j] = abs((int)gaussrand(Ex, sigma)%(int)h) + (rand()%10)/(float)10 + (rand()%10)/(float)100+ (rand()%10)/(float)1000;//单位面积所检测到的硬物高度Z收敛于hV +=Z[i][j]; //计算硬质积淤物总体积//每个机针测量范围近似面积为1cm^2,则对应面积硬物的体积可近似为每个点硬物高度的总和(1cm^3)fprintf(fp,"%f\t",Z[i][j]);}fprintf(fp,"\n");}fclose(fp); //保存并关闭xls文件 printf("———----—积淤物形态模型———----—\n");printf("详见表格:积淤物数据采集.xls\n");printf("硬质积淤物总体积:%.3f cm^3\n",V);

打开cpp文件同一目录下的文档/桌面,选择“积淤物数据采集.xls”文件:

打开后全选里面的数据,插入图表,考虑到可视化程度,推荐选择以下2种图表:

1).三维直方图:

2). 三维曲面图:

最后,用户输入分拣条件:

printf("———----—请输入分拣条件———----—\n");float scale,h_max; while(Foolproof == false){printf("直接排放的体积占比上限(0.0~1.0):");scanf("%f",&scale);if(scale >= 0.0 && scale <= 1.0)Foolproof = true;else printf("输入错误,请重新输入!\n");}Foolproof = false; //初始化//考虑到某些硬物体积小但长度大的情况while(Foolproof == false){printf("允许直接排放的最大高度:");scanf("%f",&h_max);if(h_max >= 0.0 && h_max <= h)Foolproof = true;else printf("输入错误,请重新输入!\n");}

同样,当用户输入参数时,系统都会有防呆措施:

最后,根据用户要求的分拣条件,机器人选择将积淤物分拣入存储室,或者直接将积淤物排放至其行进方向的后方。

    printf("———----—-—处理方案———----—-—\n");bool Judge = false; //判断条件,True表示分拣入室,False表示直接排放for(int i=0;i<N;i++)for(int j=0;j<n;j++)if(h_max < Z[i][j]&&V >= (h+30) *wide *N *scale)Judge = true;//硬物最大高度小于设定高度界限,且硬物体积占比小于管道横截面积*机器人分拣室长度*设定比重 if(Judge == true)printf("分拣入室\n");else printf("直接排放\n"); //硬质淤积物体积占管道比例过小,不至于造成阻塞则直接排放return 0;
}

1).直接将积淤物排放至其行进方向的后方:

2).将积淤物分拣入存储室:

Part 4.Python语言代码实战

C语言运行是蛮快的,但复杂程度也比脚本语言高很多,比如生成符合高斯分布的随机数时,Python直接可以省略那30多行函数代码,直接调用函数几行代码就能解决。更何况,本渣使用的C语言IDE并无法实现读取图像RGB值的功能,还是不得不使用Python。

首先,将刚才的硬质积淤物分拣程序直接放上吧,思路基本一致,不过绘图不必导入EXCEL那么麻烦,直接导入matplotlib库的绘图函数Axes3D,然后将X、Y、Z轴检测到的高度点数组作为形参传入函数,接着加一句plt.show()就能画出散点图。考虑到散点图的看起来比较散乱,因此我们对分拣室高度的0~1/3、1/3~2/3、2/3~3/3分别采用黄色、蓝色、红色进行标记,将可视化的效果变得更好。在程序运行过程中会弹出散点图,若想继续执行程序,关闭散点图弹框即可。

import random
import numpy as np
#进入管道前,清淤机器人内部弹簧压缩至最小
#进入管道后,弹簧伸长至机器人上下滑动轮分别紧贴管道上下内壁
#根据弹簧伸展情况,测量机器人分拣室高度h
#分拣室具体高度h往往为浮点数,取20cm<=h<=50cm
h=random.uniform(20.0,50.0) #分拣室高度
wide=random.uniform(40.0,70.0) #管道宽度
length=random.uniform(1000.0,3000.0)
print("———----—-—管道数据——-—----—---")
print("管道长度:",round(length,3),"cm")
print("分拣室高度:",round(h,3),"cm")
print("管道高度:",round(h,3)+30.0,"cm") #管道高度=分拣室高度+30cm
print("管道横截面积:",round(length*(round(h,3)+30.0),3),"cm")
V = 0.0 #初始化硬物总体积
N = 40 #宽边取40个单位检测点
n = 50 #长边取50个单位检测点
#单位面积为1cm^2
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#定义坐标轴
fig = plt.figure()
ax1 = plt.axes(projection='3d')
#定义三维数据
X = np.zeros(N*n)
Y = np.zeros(n*N)
Z = np.zeros(N*n)
k=0
for i in range(0, N, 1):for j in range(0, n, 1):X[k] = ik=k+1
k=0
for i in range(0, N, 1):for j in range(0, n, 1):Y[k] = jk=k+1
print("———----—-—模型参数——-—----—---")
#生成符合高斯分布、期望值为Ex、标准差为sigma、长度为N*n的一维数组Z
Foolproof = False #防呆判别变量
print("请选择模拟方式:1.计算机模拟 2.手动输入数据")
choice = int(input())
if choice == 1:Ex = random.uniform(20.0, h) #Ex在20~40之间取随机值print("期望值Ex:",round(Ex,3))sigma = random.uniform(0, 10.0) #sigma在0~10之间取随机值print("标准差sigma:",round(sigma,3))
else:while Foolproof == False:Ex = float(input("请输入硬质积淤物高度期望值(<=h):"))if Ex < 0.0 or Ex > h:print("输入错误,请重新输入!")else:Foolproof = Truesigma = float(input("请输入标准差值:"))
Foolproof = False #初始化
#按照计算机随机值或用户输入参数进行模拟
Z = np.random.normal(Ex,sigma,N*n)%int(h) + np.random.randn(N*n)%10/10
#生成的高度值收敛于50
print("———----—积淤物形态模型———----—")
#单位面积所检测到的硬物高度Z收敛于h
#作图
for i in range(0, N*n, 1):if Z[i]<h/3:ax1.scatter(X[i], Y[i], Z[i], c='yellow')elif Z[i]<2*h/3:ax1.scatter(X[i], Y[i], Z[i], c='blue')else:ax1.scatter(X[i], Y[i], Z[i], c='red')
plt.show()
V = Z.sum() #计算硬质积淤物总体积
print("硬质积淤物总体积:",round(V,3),"cm^2")
print("———----—请输入分拣条件———----—")
while Foolproof == False:scale = float(input("直接排放的体积占比上限(0.0~1.0):"))if scale >= 0.0 and scale <= 1.0:Foolproof = Trueelse:print("输入错误,请重新输入!")
Foolproof = False #初始化
#硬质淤积物体积占管道比例过小,不至于造成阻塞则直接排放
while Foolproof == False:h_max = float(input("允许直接排放的最大高度:"))if h_max >= 0.0 and h_max <= h:Foolproof = Trueelse:print("输入错误,请重新输入!")
#考虑到某些硬物体积小但长度大的情况
print("———----—-—处理方案———----—-—")
Judge = False #判断条件,True表示分拣入室,False表示直接排放
for i in range(0, N*n, 1):if h_max < Z[i]:Judge = True
if V >= (h+30) * wide * scale: #管道高度=分拣室高度+30cmJudge = True
if Judge == True:print("分拣入室")
else:print("直接排放")

接着,就要加上识别白色垃圾的代码了,本文不直接提供白色垃圾的识别代码,给读者更多的发挥空间去思考程序设计方案。识别的大致思路可谓朴实无华且枯燥:对色彩鲜艳的颜色,如红色、蛋黄色、蓝色、绿色等非自然物带有的特征颜色,读取图像的每个像素的RGB值,若像素值在这些特征颜色的像素值范围,则纳入统计,若统计出来的“人造颜色”像素数量与图片总像素量之比足够大,则可以排除出现这些颜色是因为噪声干扰等原因,从而将该次识别结果判定为“白色垃圾”占比过大,并将积淤物分拣入存储室而不直接排放。

可以参考处理图像RGB值的博客:

C++版本:Opencv图像处理:判断图片里某个颜色值占的比例_xiaolong1126626497的专栏-CSDN博客

Python版本:Python3 识别判断图片主要颜色,提取指定颜色的方法_python深度学习笔记,一起学习的加QQ2737499951-CSDN博客_python颜色识别

最后,感谢耐心观看,祝所有阅读者快乐且暴富QAQ~

一种清淤机器人分拣识别系统的C/Python语言实现相关推荐

  1. 一种基于语音识别的机器人语义识别系统的制作方法

    本发明涉及机器人语义识别,尤其涉及一种基于语音识别的机器人语义识别系统. 背景技术: 目前,很多家庭都拥有机器人,但是很多时候机器人并不能准确识别用户对其发出的指示,使用户操作机器人不方便,这样的机器 ...

  2. c语言编程文章排版,一种简单英文词典排版系统的实现 C语言编程

    一种简单英文词典排版系统的实现 C语言编程 答案:2  信息版本:手机版 解决时间 2019-10-06 18:43 已解决 2019-10-06 03:21 1. 一种简单的英语词典排版系统的实现 ...

  3. 人脸识别系统OpenCV+dlib+python(含数据库)Pyqt5界面设计 项目源码 毕业设计

    一.项目主要技术 Python语言.dlib.OpenCV.Pyqt5界面设计.sqlite3数据库 本系统使用dlib作为人脸识别工具,dlib提供一个方法可将人脸图片数据映射到128维度的空间向量 ...

  4. python人脸识别系统界面设计_基于卷积神经网络的人脸识别系统的设计(Python)

    基于卷积神经网络的人脸识别系统的设计(Python)(论文10000字,外文翻译,参考代码,流程图,人脸图像库) 摘要:随着社会的进步与发展,个人信息的保护变得十分重要.传统的密码保护方式已经不再满足 ...

  5. 车牌识别系统三:python+tensorflow实现车牌字符的识别

    字符识别 在前面两篇博客中分别介绍了车牌定位以及字符分割的代码实现,那么在这篇文章中,我主要想介绍一下车牌识别系统的最后一个模块:字符识别.字符识别可以说是整个系统的核心部分了,这一部分可以有很多中实 ...

  6. python能做机器人吗_最火的Python语言也能做机器人仿真,你会不?

    原标题:最火的Python语言也能做机器人仿真,你会不? 最近接到好多刚踏出大学的学弟学妹们的问候,面临人生中的第一次求职,可有感觉自己没在学校学到一技之长,但又不想随便找份工作将就,那这种情况下该怎 ...

  7. 【Python基础学习一】在OSX系统下搭建Python语言集成开发环境 附激活码

    Python是一门简单易学,功能强大的编程语言.它具有高效的高级数据结构和简单而有效的面向对象编程方法.Python优雅的语法和动态类型以及其解释性的性质,使它在许多领域和大多数平台成为编写脚本和快速 ...

  8. python条形码识别系统_基于Python与Zbar的无人机盘点条形码识别研究

    2018 年 第 6 期 第 4 0 卷 总 第 2 8 8 期 物流工程与管理 LOGISTICS ENGINEERING AND MANAGEMENT 物流技术 doi :10.3969/ j . ...

  9. 【毕业设计】深度学习昆虫识别系统 - 图像识别 opencv python

    文章目录 0 前言 1 课题背景 2 具体实现 3 数据收集和处理 3 卷积神经网络 2.1卷积层 2.2 池化层 2.3 激活函数: 2.4 全连接层 2.5 使用tensorflow中keras模 ...

最新文章

  1. 北京智源行动计划发布,北京智源人工智能研究院揭牌成立
  2. tortosiegit github
  3. (三)Window的特色学习笔记
  4. 给oracle用户赋权限导入导出,Oracle常用命令-用户、表空间、赋权限、导入导出...
  5. ReactJS学习笔记八:动画
  6. 农村信用社招聘考试计算机,农村信用社招聘考试题:计算机(一)
  7. javafx 调用java_Java“地铁”表(JavaFX)
  8. Bailian2966 时区转换【时区计算】
  9. 【难点+重点BFS】LeetCode 126. Word Ladder II
  10. php异步通知并查询,服务器异步通知的接收by php
  11. R语言读取(加载)txt格式数据为dataframe、依据学号字段从dataframe随机抽取10位同学的数据
  12. 硬件探索——数字钟的设计与制作
  13. 39.安装PH5\PH7
  14. Chromecast 播放电脑本地视频
  15. bzoj 4246: 两个人的星座 计算几何
  16. 多多情报通:拼多多什么软件可以看到大数据?拼多多大数据分析软件有哪些?
  17. arcgis api 4.13 —— Layer详细介绍
  18. Allegro PCB Design GXL (legacy) - 铺网格铜
  19. 以Edge浏览器为例演示清除浏览器的缓存
  20. 节日祝福 html,节日祝福语大全

热门文章

  1. 海润光伏88亿交易陷“罗生门”
  2. EditPlus 横竖转换
  3. 适合初学Altium Designer的教学视频
  4. 华为手环b6可以升级鸿蒙,华为手环b6怎么样 配置和操作体验升级
  5. 实验3-11 计算油费 (15 分)
  6. 在线教育的内容研发和技术的迭代创新
  7. LC463. 岛屿的周长
  8. PMOS和NMOS在开关应用中高侧和低侧驱动的对比
  9. PL/SQL Developer 登录报错(ORA-12547)解决方案
  10. AntV可视化图表G2-柱状图