当前位置: 首页 > news >正文

9.传统的轨道画线算法()

轨道画线分为以下步骤:

1.读取摄像头图片

2.图片灰度处理,截取轨道区域的图片

3.中值滤波处理,并区域取均值后做期望差的绝对值。本人通过一些轨道图片实验,用这种方法二值化得到的效果比caany算子等方法的效果好

4.二值化后再用DBSAN聚类算法对图片分类

5.对分好类的坐标在图片中画图

具体代码如下:

import numpy as np
import cv2colors = [ (0, 0, 0), (128, 0, 0), (0, 128, 0), (128, 128, 0), (0, 0, 128), (128, 0, 128), (0, 128, 128),(128, 128, 128), (64, 0, 0), (192, 0, 0), (64, 128, 0), (192, 128, 0), (64, 0, 128), (192, 0, 128),(64, 128, 128), (192, 128, 128), (0, 64, 0), (128, 64, 0), (0, 192, 0), (128, 192, 0), (0, 64, 128),(128, 64, 12)]def cluster(points, radius=100):"""points: pointcloudradius: max cluster range"""print("................", len(points))items = []while len(points)>1:item = np.array([points[0]])base = points[0]points = np.delete(points, 0, 0)distance = (points[:,0]-base[0])**2+(points[:,1]-base[1])**2#获得距离infected_points = np.where(distance <= radius**2)#与base距离小于radius**2的点的坐标item = np.append(item, points[infected_points], axis=0)border_points = points[infected_points]points = np.delete(points, infected_points, 0)#print("................",len(points))#print(border_points)while len(border_points) > 0:border_base = border_points[0]border_points = np.delete(border_points, 0, 0)border_distance = (points[:,0]-border_base[0])**2+(points[:,1]-border_base[1])**2border_infected_points = np.where(border_distance <= radius**2)#print("/",border_infected_points)item = np.append(item, points[border_infected_points], axis=0)for k in border_infected_points:if points[k] not in border_points:border_points=np.append(border_points,points[k], axis=0)#border_points = points[border_infected_points]points = np.delete(points, border_infected_points, 0)items.append(item)return items#2.图像的灰度处理、边缘分割
def mean_img(img):# gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#1.图片的灰度,截取处理gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)imgss=img[540:743, 810:1035]gray_img = gray_img[540:741, 810:1030]#[540:741, 810:1080]img2=gray_imgprint(img2.mean())#中值滤波gray_img = cv2.medianBlur(gray_img, ksize=3)cv2.imshow("Dilated Image", gray_img)cv2.waitKey(0)#2.行做期望差,3个值取均值再做差for i in range(gray_img.shape[0]):for j in range(gray_img.shape[1]-2):ss1=gray_img[i, j:j+2].mean()m=abs(gray_img[i][j]-ss1)if m>13:img2[i][j] =255else:img2[i][j] =0img2[:,-3:]=0cv2.imshow("img_mean", img2)cv2.waitKey(0)# 3.腐蚀膨胀消除轨道线外的点kernel = np.uint8(np.ones((5, 2)))# 膨胀图像.....为了使得轨道线更粗,且补足轨道线缺失的地方dilated = cv2.dilate(img2, kernel)#显示膨胀后的图像#dilated[:, -6:] = 0cv2.imshow("Dilated Image", dilated)cv2.waitKey(0)ss=np.argwhere(dilated>0)print(ss)cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\img\\120.jpg",dilated)#聚类算法items = cluster(ss, radius=5)print(len(items))i=0for item in items:print("====>", len(item))if len(item)>500:for k in item:imgss[k[0]][k[1]]=colors[i]i+=1cv2.imshow("ss",imgss)cv2.waitKey(0)cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\img\\121.jpg", imgss)return ss#3.画图
def draw_line(items):print(123)if __name__ == '__main__':img_path=r"D:\AI\project\eye_hand_biaoding\railways\img\1.jpg"img=cv2.imread(img_path)ss=mean_img(img)ss=np.array(ss)items=cluster(ss, radius=25)

通过以上聚类的方法处理后的图片如下:

        接下来对两类点进行处理。在这里目前想到的处理方式有两种:一是:首先对每个类取行的中值或者均值,即每个类的每行只保留一个坐标(均值或者中间值),去除掉了每行两边的坐标。但这个效果不太好,后面会附加代码和处理的图片结果;二是根据霍夫曼求直线的方法,自己重新写个获取直线。

一、取均值或者中值的代码如下:

import numpy as np
import cv2
from sklearn.linear_model import LinearRegression
import time#https://blog.csdn.net/L888666Q/article/details/127209464
#霍夫曼取直线原理:https://blog.csdn.net/fengjiexyb/article/details/78075888colors = [ (0, 0, 0), (128, 0, 0), (0, 128, 0), (128, 128, 0), (0, 0, 128), (128, 0, 128), (0, 128, 128),(128, 128, 128), (64, 0, 0), (192, 0, 0), (64, 128, 0), (192, 128, 0), (64, 0, 128), (192, 0, 128),(64, 128, 128), (192, 128, 128), (0, 64, 0), (128, 64, 0), (0, 192, 0), (128, 192, 0), (0, 64, 128),(128, 64, 12)]def cluster(points, radius=100):"""points: pointcloudradius: max cluster range"""print("................", len(points))items = []while len(points)>1:item = np.array([points[0]])base = points[0]points = np.delete(points, 0, 0)distance = (points[:,0]-base[0])**2+(points[:,1]-base[1])**2#获得距离infected_points = np.where(distance <= radius**2)#与base距离小于radius**2的点的坐标item = np.append(item, points[infected_points], axis=0)border_points = points[infected_points]points = np.delete(points, infected_points, 0)#print("................",len(points))#print(border_points)while len(border_points) > 0:border_base = border_points[0]border_points = np.delete(border_points, 0, 0)border_distance = (points[:,0]-border_base[0])**2+(points[:,1]-border_base[1])**2border_infected_points = np.where(border_distance <= radius**2)#print("/",border_infected_points)item = np.append(item, points[border_infected_points], axis=0)if len(border_infected_points)>0:for k in border_infected_points:if points[k] not in border_points:border_points=np.append(border_points,points[k], axis=0)#border_points = points[border_infected_points]points = np.delete(points, border_infected_points, 0)items.append(item)return itemsdef k_mean(out):print("........................开始计算图片的均值.....................")median = {}i = 1for items in out:median[str(i)] = []result = items[:, :-1]ss = result.shaperesult = result.reshape(ss[1], ss[0])result = result[0].tolist()result = list(set(result))  # 去掉result重复的值for m in result:#print("...............", m, "...............................")item = np.where(items[:, :-1] == m)[0]# median[str(i)].append(items[item[len(item)//2]].tolist()) #中位数,有用median[str(i)].append([m, int(items[item][:, -1:].mean())])  # 均值i += 1return median#直线的拟合
def lines(median,distances):print("...................直线的拟合......................")for items in median:n_m=np.array(median[items])#转换为array数据means=n_m[:,1:]#取坐标的第二列lens=n_m[-1][0]+1#总共多少个坐标,即坐标个数#print(lens)#1.获取x1,x2的坐标if lens%4>2:x10=lens//4+1else:x10 = lens // 4x20=x10*3x=lens//2#print("x1,x2:  ",x10,x20)#2.获取y1,y2的坐标y10=means[:lens//2].mean()y20 = means[lens // 2-1:].mean()y=means.mean()#print("y1,y2:  ", y10, y20)#3.获取直线斜率k k=(y1-y2)/(x1-x2)k=(y10-y20)/(x10-x20)#print("k:  ",k)#print("x,y:      ",x,y)#4.预测某个点的y值 y-pred=k*(x_pred-x)+y  n_m[i]for i in range(len(n_m)):y_pred = k * (n_m[i][0] - x) + y#print("===>",y_pred,n_m[i][0],n_m[i][1])if abs(y_pred-n_m[i][1])>distances:n_m[i][1]=y_pred#median[items][i][1]=int(y_pred)median[items]=n_m.tolist()return median#2.图像的灰度处理、边缘分割
def mean_img(img,x1,x2,y1,y2):imgs=img.copy()img4 = img.copy()#1.图片的灰度,截取处理gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray_img = gray_img[x1:x2, y1:y2]#[540:741, 810:1080],截取轨道画线的区域,对该区域识别轨道img2=gray_img#2.中值滤波gray_img = cv2.medianBlur(gray_img, ksize=3)# cv2.imshow("Dilated Image", gray_img)# cv2.waitKey(0)st=time.time()for i in range(gray_img.shape[0]):for j in range(gray_img.shape[1]-2):ss1 = gray_img[i, j:j + 2].mean()m=abs(gray_img[i][j]-ss1)if m>9:img2[i][j] =255else:img2[i][j] =0img2[:,-3:]=0et = time.time()print("kmeans时间",et-st)# cv2.imshow("img_mean", img2)# cv2.waitKey(0)# 3.腐蚀膨胀消除轨道线外的点st1=time.time()kernel = np.uint8(np.ones((2, 1)))# 膨胀图像.....为了使得轨道线更粗,且补足轨道线缺失的地方dilated = cv2.dilate(img2, kernel)#显示膨胀后的图像# cv2.imshow("Dilated Image", dilated)# cv2.waitKey(0)kernel = np.ones((2, 2), np.uint8)dilated = cv2.erode(dilated, kernel)cv2.imshow("ss",dilated)cv2.waitKey(0)ss=np.argwhere(img2>0)#dilatedcv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\img\\120.jpg",dilated)#聚类算法items = cluster(ss, radius=3)print(len(items))i=0out=[]#获得大于300个坐标的类for item in items:if len(item)>300:out.append(item)print("====>", len(item))for k in item:img[k[0]+x1][k[1]+y1]=colors[i]#[540:743, 810:1035]i+=1# cv2.imshow("ss",img)# cv2.waitKey(0)cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\img\\121.jpg", img)et1 = time.time()print("聚类时间:", et1 - st1)#求聚类的每类每行的中位数median=k_mean(out)#根据中位数画图j=0for item in median:for k in median[item]:#print(k[0],k[1])imgs[k[0]+x1][k[1]+y1] = colors[j]  # [540:743, 810:1035]j+=1cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\img\\122.jpg", imgs)et3=time.time()print("中位数时间:", et3 - et1)print(".....................................","\n")#用直线拟合,首先用两个均值得到初始线的斜率及均值坐标,然后不断对远离的坐标点拟合distances=4while distances>0:median=lines(median,distances)distances-=1#画图j = 0for item in median:for k in median[item]:# print(k[0],k[1])img4[k[0] + x1][k[1] + y1] = colors[j]  # [540:743, 810:1035]j += 1cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\img\\123.jpg", img4)et4=time.time()print("直线拟合消耗时间:",et4-et3)return outif __name__ == '__main__':start=time.time()img_path=r图片路径"img=cv2.imread(img_path)out=mean_img(img,x1=650,x2=741,y1=825,y2=1025)#x1=540,x2=741,y1=810,y2=1030end=time.time()print("time:",end-start)

        上述的直线拟合没有用最小二乘法,处理后的画图结果如下:

显然,拟合的结果并不好。下面用霍夫曼求直线的方法拟合。

二、霍夫曼圆找直线

相关文章:

9.传统的轨道画线算法()

轨道画线分为以下步骤&#xff1a; 1.读取摄像头图片 2.图片灰度处理&#xff0c;截取轨道区域的图片 3.中值滤波处理&#xff0c;并区域取均值后做期望差的绝对值。本人通过一些轨道图片实验&#xff0c;用这种方法二值化得到的效果比caany算子等方法的效果好 4.二值化后再…...

F (1164) : B DS二叉排序树_有效的二叉排序树

Description 给你一个二叉树&#xff0c;判断其是否是一个有效的二叉排序树。 有效的二叉排序树定义如下&#xff1a; 1. 结点的左子树只包含小于当前结点的数。 2. 结点的右子树只包含大于当前结点的数。 3. 所有左子树和右子树自身必须也是二叉排序树。 Input 第一行输…...

结合el-upload修改支持上传图片、视频并预览

结合element plus的el-upload标签&#xff0c;实现上传图片和视频&#xff0c;并支持在线预览和放大 1、html部分 <el-form-item label"活动照片、视频"><el-uploadv-model:file-list"state.photoList":action"state.uploadUrl"accept…...

1.SQL - 概述

1. SQL语句分类 • 数据定义语言&#xff1a;简称DDL(Data Definition Language)&#xff0c;用来定义数据库对象&#xff1a;数据库&#xff0c;表&#xff0c;列等。关键字&#xff1a;create&#xff0c;alter&#xff0c;drop等 • 数据操作语言&#xff1a;简称DML(Data …...

GaussDB数据库表创建行访问控制策略

目录 一、前言 二、GaussDB中的行访问控制 1、CREATE ROW LEVEL SECURITY POLICY语法 2、ALTER ROW LEVEL SECURITY POLICY语法 3、ROW LEVEL SECURITY策略与适配SQL语法关系 三、GaussDB中的行访问控制策略示例 1、实现GaussDB行访问控制的一般步骤 2、行访问控制策略…...

提升设备巡检效率的关键:易点易动设备管理系统的应用

随着互联网技术的发展,智慧设备管理已成为各行各业提升运营效率的重要选择。相比传统的手动巡检方式,采用设备管理系统可以实现物联网技术给企业带来更高效的运营方式。其中,易点易动作为一款成熟的设备管理系统,其广泛应用于提升设备巡检效率这一领域发挥了很好的作用。 采用易…...

【C++】STL 容器 - list 双向链表容器 ① ( 容器特点 | 容器操作时间复杂度 | 构造函数 )

文章目录 一、 list 双向链表容器简介1、容器特点2、容器操作时间复杂度3、遍历访问5、头文件 二、 list 双向链表容器 构造函数1、默认无参构造函数2、创建包含 n 个相同元素的 list 双向链表3、使用初始化列表构造 list 双向链表4、使用另外一个 list 容器 构造 list 双向链表…...

[C/C++]数据结构 希尔排序

&#x1f966;前言: 希尔排序也称 “缩小增量排序”&#xff0c;它也是一种插入类排序的方法,在学习希尔排序之前我们首先了解一下直接插入排序. 一: &#x1f6a9;直接插入排序 1.1 &#x1f31f;排序思路 直接插入排序的基本原理是将一条记录插入到已排好的有序表中&#x…...

SQL进阶:子查询

一般情况下,我们都是直接对表进行查询,但有时候,想要的数据可能通过一次select 获取不到,需要嵌套select,这样就形成了子查询。 子查询可以位于查询语句的任意位置,主要的注意点在于用于不同的位置,和不同的关键字一起使用时,需要注意返回的列的数量和行的数量。 位于…...

5、IDEA集成Git

IDEA集成Git 1. 配置Git忽略文件2. 定位Git程序3. 初始化本地库、添加暂存区、提交到本地库4. 切换版本5. 创建分支和切换分支6. 合并分支7. 解决冲突 1. 配置Git忽略文件 问题1&#xff1a;为什么要忽略他们&#xff1f; 与项目的实际功能无关&#xff0c;不参与服务器上部署…...

oracle数据库sqlplus登录卡顿

问题描述 新安装了一套oracle 11.2.0.1 版本的数据库服务器&#xff0c;出现了在服务器本地通过sqlplus / as sysdba登录的时候很快&#xff0c;但是通过监听登录的时候就非常的慢&#xff0c;卡顿&#xff0c;大概需要1分钟多的时间才能登进数据库。 之前安装了好几套oracle …...

【C#】Visual Studio 2022 远程调试配置教程

在某些特殊的情况下&#xff0c;开发机和调试机可能不是同一台设备&#xff0c;此时就需要远程调试了。 开发机配置 首先需要确保两台机器在同一局域网下。 创建共享文件夹 随便找个地方新建一个文件夹&#xff0c;用来放编译结果。例如我这里是 D:\DebuggingWorkspace\。 …...

LSTM的记忆能力实验

长短期记忆网络&#xff08;Long Short-Term Memory Network&#xff0c;LSTM&#xff09;是一种可以有效缓解长程依赖问题的循环神经网络&#xff0e;LSTM 的特点是引入了一个新的内部状态&#xff08;Internal State) 和门控机制&#xff08;Gating Mechanism&#xff09;&am…...

Unity之ShaderGraph如何实现瓶装水效果

前言 有一个场景在做效果时,有一个水瓶放到桌子上的设定,但是模型只做了个水瓶,里面是空的,所以我就想办法,如何做出来瓶中装睡的效果,最好是能跟随瓶子有液体流动的效果。 如下图所示: 水面实现 水面效果 液体颜色设置 因为液体有边缘颜色和内里面颜色,所以要分开…...

【python与机器学习3】感知机和门电路:与门,或门,非门等

目录 1 电子和程序里的与门&#xff0c;非门&#xff0c;或门&#xff0c;与非门 &#xff0c;或非门&#xff0c;异或门 1.1 基础电路 1.2 所有的电路情况 1.3 电路的符号 1.4 各种电路对应的实际电路图 2 各种具体的电路 2.1 与门&#xff08;and gate&#xff09; 2…...

关键字:extends关键字

在 Java 中&#xff0c;extends 是一个关键字&#xff0c;用于表示继承关系。当一个类使用 extends 关键字时&#xff0c;它表示该类是一个子类&#xff0c;并且继承了父类的属性和方法。 以下是 extends 关键字的解析&#xff1a; 语法&#xff1a; 描述&#xff1a; ChildC…...

KEPServerEX 6 之【外篇-1】PTC-ThingWorx服务端软件安装 Tomcat10本地安装

本文目标: 安装 Java 和 Apache Tomcat ,为ThingWorx安装做基础。 ----------------------------------------------------------------------- 安装重点 --------------------------------------------------------------------- 1. 安装 Java 11 / JDK 11 添加系…...

(Mac上)使用Python进行matplotlib 画图时,中文显示不出来

【问题描述】 ①报错确缺失字体&#xff1a; ②使用matplotlib画图&#xff0c;中文字体显示不出来 【问题思考】 在网上搜了好多&#xff0c;关于使用python进行matplotlib画图字体显示不出来的&#xff0c;但是我试用了下&#xff0c;对我来说都没有。有些仅使用于windows系…...

万能刷题小程序源码系统:功能强大+试题管理+题库分类+用户列表 附带完整的搭建教程

随着互联网技术的不断进步&#xff0c;线上学习已成为越来越多人的选择。刷题作为提高学习效果的重要方式&#xff0c;一直受到广大学生的喜爱。然而&#xff0c;市面上的刷题软件虽然繁多&#xff0c;但功能各异&#xff0c;质量参差不齐&#xff0c;使得很多用户在选择时感到…...

5.2 显示窗口的内容(二)

三,显示器几何形状管理 只有显示管理器被允许更改显示器的几何形状。窗口管理器也是显示管理器。 3.1 当显示器显示其自身内容时 当显示器显示其自身内容时,适用以下属性: 显示属性描述SCREEN_PROPERTY_PROTECTION_ENABLE表示显示目标窗口是否需要内容保护。只要显示器上…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...