carla中lka实现(一)

前言:

对于之前项目中工作内容进行总结,使用Carla中的车辆进行lka算法调试,整体技术路线:

①在Carla中生成车辆,并在车辆上搭载camera,通过camera采集图像数据;

②使用图像处理lka算法,对于camera数据进行计算分析;

③对于分析的结果输出为偏移图像中心的线的距离,并以这个距离做为车辆控制方向盘的数值。

其中第一步比较简单,不做记录,从第二步,lka算法实现开始。

需要对于输入的图像进行边缘检测提取出车道线

一、边缘检测

车道线一般为黄线和白线,与车道线旁的公路的颜色有很大的差异,通过这种差异,就是车道线与公路之间颜色变化,可以找到车道线的边缘,找到这个边缘的过程为边缘检测。

1.1 使用sobel进行边缘检测

直接使用cv2中Sobel包来进行边缘检测:

测试源码如下:

def abs_sobel_thresh(image,orient='x',sobel_kernel=3,thresh=(0,255)):
    # generating the gray image.
    gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
    # 计算x方向和y方向的梯度上强度值的图像
    if orient == 'x':
        abs_sobel = np.absolute(cv2.Sobel(gray,cv2.CV_64F,1,0,ksize=sobel_kernel))
    if orient == 'y':
        abs_sobel = np.absolute(cv2.Sobel(gray,cv2.CV_64F,0,1,ksize=sobel_kernel))
    # 利用归一化获得
    scaled_sobel = np.uint8(255*abs_sobel/np.max(abs_sobel))
    # 创建出一个同尺寸的数组
    grad_binary = np.zeros_like(scaled_sobel)
    grad_binary[ ( scaled_sobel >= thresh[0] ) & ( scaled_sobel <= thresh[1] ) ] = 1
    return grad_binary

主要功能实现在abs_sobel_thresh函数中,

首先使用cv2.cvtColor函数将原始图像转化为灰度图,

然后计算x方向和y方向上的梯度强度值上的图像,

利用归一化获得一个数组,这个数组记录了图像中所有的点的强度值,然后新建一个同样size的图像数组,将数组中强度信息在0到255之间的值设置为1。

输出x和y方向梯度的图像对比:

    ksize = 15
    gradx = abs_sobel_thresh(image,orient='x',sobel_kernel=ksize,thresh=(50,180))
    grady = abs_sobel_thresh(image,orient='y',sobel_kernel=ksize,thresh=(30,90))

    fig1 = plt.figure()
    plt.imshow(gradx,cmap="gray")
    fig2 = plt.figure()
    plt.imshow(grady,cmap="gray")
    plt.show()

1.2 使用颜色阈值检测

使用图像中的rgb中不同数字进行检测提取。

def rgb_select(img,r_thresh,g_thresh,b_thresh):
    r_channel = img[:,:,0]
    g_channel = img[:,:,1]
    b_channel = img[:,:,2]
    
    
    r_binary = np.zeros_like(r_channel)
    r_binary[(r_channel > r_thresh[0]) & (r_channel <= r_thresh[1])] = 1
    
    g_binary = np.zeros_like(g_channel)
    g_binary[(g_channel > g_thresh[0]) & (g_channel <= g_thresh[1])] = 1

    b_binary = np.zeros_like(b_channel)
    b_binary[(b_channel > b_thresh[0]) & (b_channel <= b_thresh[1])] = 1
    #
    combined = np.zeros_like(r_channel)
    combined[((r_binary == 1) & (g_binary == 1) & (b_binary == 1))] = 1
    return combined

在函数rbg_select中分别划分不同的rgb通道的数组,然后创建不同的新的数组,并将符合阈值内的点设置为1,最后将它们合并起来输出为图像combined。

 1.3 融合sobel和rgb的边缘检测

就是将两个图像中值为1的合并起来,容易实现。

def color_gradient_threshold(image):
    ksize = 15
    gradx = abs_sobel_thresh(image,orient='x',sobel_kernel=ksize,thresh=(50,180))
    rgb_binary = rgb_select(image,r_thresh=(225,255),g_thresh=(180,255),b_thresh=(0,255))
    combined_binary = np.zeros_like(image)
    combined_binary[((gradx==1)|(rgb_binary==1))] = 255
    color_binary = combined_binary
    return color_binary

 1.4 小结

边缘检测效果完成,因为是基于Carla做的车道线边缘检测,而Carla中输出的图像输出的效果比较理想,所以直接使用sobel和rgb边缘检测融合就可以达到很好的效果所以没有做过多的研究,实际情况比较复杂可能并不适用。

二、选择车道线的区域

这里要注意用数组表示图像的时候原点一般是左上角,向右为x轴正方向,向下为y轴正方向。

所以先选择出左下角,右下角:

    ksize = 15
    img_color = color_gradient_threshold(image)
    
    left_bottom = [0, img_color.shape[0]]
    right_bottom = [img_color.shape[1],img_color.shape[0]]

选择另外一个顶点:

    apex = [ img_color.shape[1]/2, 420 ]
    vertices = np.array([ left_bottom, right_bottom, apex ],np.int32)

其中vertices存储的是三个点,分别是左下角、右下角和顶点。

接下来使用刚刚选择的点与边缘检测后的图像按位与得到选择车道线的区域:

def region_of_interest(img,vertices):
    mask = np.zeros_like(img)
    cv2.fillPoly(mask,[vertices],[255,255,255])
    masked_image = cv2.bitwise_and(img,mask)
    return masked_image

其中函数fillPoly函数第一个参数表示为原始图像,第二个参数为选择的点,第三个参数表示为赋值为白色。

而bitwise_and是将两个参数按位与。

最后输出按位与后的图像。

 效果还可以。

三、投影变换

将原先小的三角形区域利用投影变换成大的区域。

主要运用cv中的透视变换:

def perspective_transform(image):
    # give 4 points as original coordinates.
    top_left =[590,460]
    top_right = [750,460]
    bottom_left = [330,650]
    bottom_right =  [1130,650]
    # give 4 points to project.
    proj_top_left = [250,100]
    proj_top_right = [1150,100]
    proj_bottom_left  =  [330,650]
    proj_bottom_right =  [1130,650]
    # to get image size.
    img_size = (image.shape[1],image.shape[0])
    # 
    pts1 = np.float32([top_left,top_right,bottom_left,bottom_right])
    pts2 = np.float32([proj_top_left,proj_top_right,proj_bottom_left,proj_bottom_right])
    matrix_K = cv2.getPerspectiveTransform(pts1,pts2)
    img_k = cv2.warpPerspective(image,matrix_K,img_size)
    return img_k

先划定四个点分别是左上、右上、左下和右下,为原始图像区域,

在划定投影区域。

运用函数getPerspectiveTransform它的第一个参数为平面1,第二个参数为平面2,求出平面1上的点要映射到平面2上所需要的变换的矩阵。

函数warpPerspective它的第一个参数为原始图像,第二个参数为投影变换矩阵,第三个参数为输出图像的大小,这里使用的就是原始图像的大小,需要注意一般为宽在前,长在后。

最后输出的就是变换后的图像信息。

 四、车道线提取

4.1 直方图显示

使用直方图来显示前面拉伸后的图像信息。

def histogram_img(image):
    histogram_binary = np.zeros((image.shape[0],image.shape[1]),dtype=np.int)
    histogram_binary[image[:,:,0]>0] = 1
    histogram = np.sum(histogram_binary[:,:],axis=0)
    print("histogram: ",histogram)
    print("histogram shape: ",histogram.shape)
    return histogram 

代码比较容易理解,设置一个同输入图像同尺寸的数组,将原来图像中任一rgb信息大于0的位置赋值为1,其实设置为255也可以,因为前面设置的就是255。之后就将它按列累加起来,返回这一行累加的数组(1*n)。

 4.2 车道线定位

获得的前面的直方图后,求出它的两个波峰的位置来获得车道线的大概位置。

def lane_position(histogram):
    histogram_size = histogram.shape
    middle_point = int(histogram_size[0]/2)
    print("middle_point: ",middle_point)
    #
    left_point = [0,0]
    for i in range(middle_point):
        # 寻找直方图中的波峰即顶点
        if histogram[i] > left_point[1]:
            left_point[1] = histogram[i]
            left_point[0] = i
    #
    right_point = [0,0]
    for j in range(middle_point,histogram_size[0]):
        if histogram[j] > right_point[1]:
            right_point[1] = histogram[j]
            right_point[0] = j
    
    result_points = [left_point,right_point]           
        
    print("result_points: ",result_points)
    return result_points

输出位置:
result_points:  [[342, 566], [1014, 291]]

说明两个车道线大概在这两个点附近。

4.3 滑动窗口

将前面求得的两个坐标为起点来构建滑动窗口将车道线包裹在内。

def sliding_window(image,lanes_pos):
    # starting original points for windows.
    left_x_current = lanes_pos[0][0]
    right_x_current = lanes_pos[1][0]
    nWindows = 10
    window_height = np.int(image.shape[0]//nWindows)
    window_width = 80
    # to get the non-zero data in the input image.
    nonzero = image.nonzero() 
    nonzero_y = nonzero[0]
    nonzero_x = nonzero[1]
    #
    # create a empty list to receive left/right line pixel.
    left_lane_inds = []
    right_lane_inds = []
    # create window by window
    for window in range(nWindows):
        # window size.
        win_y_top = image.shape[0] - (window +1)*window_height
        win_y_bottom = image.shape[0] - window*window_height
        win_x_left_left = left_x_current - window_width
        win_x_left_right = left_x_current + window_width 
        win_x_right_left = right_x_current - window_width
        win_x_right_right = right_x_current + window_width
        # define a rectangle for left+right lane.
        # and add the rectangle to the input image.
        cv2.rectangle(image,(win_x_left_left,win_y_top),(win_x_left_right,win_y_bottom),(0,255,0),2)
        cv2.rectangle(image,(win_x_right_left,win_y_top),(win_x_right_right,win_y_bottom),(0,255,0),2)
        good_left_inds = ((nonzero_y >= win_y_top)&(nonzero_y < win_y_bottom)&(nonzero_x >= win_x_left_left)&(nonzero_x < win_x_left_right)).nonzero()[0]
        good_right_inds = ((nonzero_y >= win_y_top)&(nonzero_y < win_y_bottom)&(nonzero_x >= win_x_right_left)&(nonzero_x < win_x_right_right)).nonzero()[0]
        #print(good_left_inds)
        left_lane_inds.append(good_left_inds)
        right_lane_inds.append(good_right_inds)
        #
        #print("nonzero_x_left:",nonzero_x[good_left_inds])
        #print("non_zero_x_right:",nonzero_x[good_right_inds])
        if len(good_left_inds)>50:
            left_x_current = np.int(np.mean(nonzero_x[good_left_inds]))
        if len(good_right_inds)>50:
            right_x_current = np.int(np.mean(nonzero_x[good_right_inds]))
    # ending of lop.
    #print("left_lane_inds",left_lane_inds)
    # to transfom a list of list to a list.
    left_lane_inds = np.concatenate(left_lane_inds)
    right_lane_inds = np.concatenate(right_lane_inds)
    #print("left_lane_inds",left_lane_inds)
    left_x = nonzero_x[left_lane_inds]

    left_y = nonzero_y[left_lane_inds]
    right_x = nonzero_x[right_lane_inds]
    right_y = nonzero_y[right_lane_inds]
    #
    results = [image,left_x,left_y,right_x,right_y]
    #print("sliding windows results: ",results)
    return results

代码写的很明白,首先去输入的坐标为左边的车道线x坐标和右边车道线y坐标,

然后计算滑动窗口的高度和宽度,

算出图像中所有不唯1的坐标,将它们放入nonzero数组中,

分别取行数为nonzero_y和列数为nonzero_x,

之后就是在for循环不断的画出矩形,利用rectangle函数进行绘制图像。

然后计算这个窗口里面大于1的数的位置平均值为下一个窗口的中间值,

最后保存所有的大于1的坐标,并于图像一并返回。

 4.4 曲线拟合

构建出一条曲线来表示车道线,方便之后利用曲线的曲率来控制车辆的转向信息。

具体实现为将之前获得的图像中所有的白色点的坐标,将它们进行拟合成曲线。

def fit_polynominal(img_sliding_window):
    image = img_sliding_window[0]
    left_x = img_sliding_window[1]
    left_y = img_sliding_window[2]
    right_x = img_sliding_window[3]
    right_y = img_sliding_window[4]

    left_fit = np.polyfit(left_y,left_x,2)
    right_fit = np.polyfit(right_y,right_x,2)

    # to generate x and y values for plotting.
    ploty = np.linspace(0,image.shape[0]-1,image.shape[0])
    left_fitx = left_fit[0]*ploty**2 + left_fit[1]*ploty + left_fit[2]
    right_fitx = right_fit[0]*ploty**2 + right_fit[1]*ploty + right_fit[2]

    plt.plot(left_fitx,ploty,color='yellow')
    plt.plot(right_fitx,ploty,color='red')
    return 0

其中主要函数为polyfit函数它将参数一和参数二进行二次曲线拟合,拟合后得到三个参数存在返回值里面。

之后依据高度进行划分点,然后更具拟合后的参数构造曲线方程,最后输出到图像上。

 4.5 添加蒙版

通过前面获得的两条曲线的坐标点,在两条曲线之间添加一层蒙版,表示车道位置。

def drawing_poly(img_ori, img_fit):
    # create an image to draw the lines on.
    #
    left_fitx = img_fit[0]
    right_fitx = img_fit[1]
    ploty = img_fit[2]
    #
    img_zero = np.zeros_like(img_ori)
    #
    #print("left_fitx:",left_fitx)
    #print("ploty:",ploty)
    pts_left = np.transpose(np.vstack([left_fitx,ploty]))
    #print("pts_left:",pts_left)
    # print("pts_left shape:",pts_left.shape)
    pts_right = np.transpose(np.vstack([right_fitx,ploty]))
    pts_right = np.flipud(pts_right)
    #print("pts_right:",pts_right)
    #print("pts_right shape:",pts_right.shape)
    pts = np.vstack((pts_left,pts_right))
    #print("pts_left+right:",pts)
    #print("pts_left+right shape:",pts.shape)
    img_mask = cv2.fillPoly(img_zero,np.int_([pts]),(0,255,0))
    #print("img_mask:",img_mask)
    #print("img_mask shape:",img_mask.shape)
    return img_mask

主要是对于右侧坐标的反转,

pts_right = np.flipud(pts_right)是为了后面绘制多边形的时候连线准确,

pts = np.vstack((pts_left,pts_right))

img_mask = cv2.fillPoly(img_zero,np.int_([pts]),(0,255,0))

 4.6 反向映射

将之前的处理后的图像反向映射回原始图像。

将之前的代码中的参数变换位置就可以获得反过来的变换矩阵。

getPerspectiveTransform

def drawing_poly_perspective_back(img_ori, img_fit,matrix_K_back):
    # create an image to draw the lines on.
    #
    left_fitx = img_fit[0]
    right_fitx = img_fit[1]
    ploty = img_fit[2]
    #
    img_zero = np.zeros_like(img_ori)
    #
    #print("left_fitx:",left_fitx)
    #print("ploty:",ploty)
    pts_left = np.transpose(np.vstack([left_fitx,ploty]))
    #print("pts_left:",pts_left)
    #print("pts_left shape:",pts_left.shape)
    pts_right = np.transpose(np.vstack([right_fitx,ploty]))
    pts_right = np.flipud(pts_right)
    #print("pts_right:",pts_right)
    #print("pts_right shape:",pts_right.shape)
    pts = np.vstack((pts_left,pts_right))
    #print("pts_left+right:",pts)
    #print("pts_left+right shape:",pts.shape)
    img_mask = cv2.fillPoly(img_zero,np.int_([pts]),(0,255,0))
    #print("img_mask:",img_mask)
    #print("img_mask shape:",img_mask.shape)
    # to get image size.
    img_size = (img_ori.shape[1],img_ori.shape[0])
    img_mask_back = cv2.warpPerspective(img_mask,matrix_K_back,img_size)
    return img_mask_back

五、视频输入

 车道线检测变换基本完成,在将单帧图像修改为视频进行计算。

    # video input.
    video_input = "./test_video/project_video.mp4"
    cap = cv2.VideoCapture(video_input)
    # output setting.
    video_output = "./test_video/project_video_output_v2.mp4"
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    width = 1280
    height = 720
    fps = 20
    video_out = cv2.VideoWriter(video_output,fourcc,fps,(width,height))
    # add some text to the output video.
    content = "this is frame: "
    pos = (64,90)
    color = (0,255,0)
    font = cv2.FONT_HERSHEY_SIMPLEX
    weight = 2
    size = 1
    count = 0
    #
    # prcessing frame by frame. 
    while True:
        ret,frame = cap.read()
        if not ret:
            print("video read error, exited...")
            break
        if cv2.waitKey(25) & 0xFF == ord('q'):
            print(" you quit the program by clicking 'q'...")
            break
        image = frame
        ksize = 15
        img_color = color_gradient_threshold(image)
        #
        left_bottom = [0, img_color.shape[0]]
        right_bottom = [img_color.shape[1],img_color.shape[0]]
        apex = [ img_color.shape[1]/2, 420 ]
        vertices = np.array([ left_bottom, right_bottom, apex ],np.int32)
        img_interest = region_of_interest(img_color,vertices)
        img_perspective,matrix_K_back = perspective_transform(img_interest)
        img_histogram = histogram_img(img_perspective)
        lanes_pos = lane_position(img_histogram)
        img_sliding_window = sliding_window(img_perspective,lanes_pos) 
        img_fit_list = fit_polynominal(img_sliding_window)
        ## to set the transparency of img.
        img_mask_back = drawing_poly_perspective_back(image,img_fit_list,matrix_K_back)
        #img_mask_back_result = img_mask_back*0.5 + image*0.5
        img_mask_back_result = cv2.addWeighted(image,1,img_mask_back,0.3,0)
        results = img_mask_back_result
        contents = content + str(count)
        cv2.putText(results,contents,pos,font,size,color,weight,cv2.LINE_AA)
        cv2.imshow("frame",results)
        video_out.write(results)
        #
        count += 1
    cap.release()
    cv2.destroyAllWindows()

容易理解,不做解读,

但只能达到一个简单的车道线识别效果,而且处理速度很慢,遇到颜色变化不明显的会直接error,在具体的项目应用中需要改进,改进在后面的文章中体现。

参考文章:

(六)高级车道线识别 - 知乎在之前的文章中,我们介绍了利用opencv进行简单的车道线识别项目,本文将更进一步,对相对复杂场景下的车道线进行识别。具体来讲,本文在简单车道线项目的基础上增加了如下知识点:颜色空间,透视变换,滑移窗,弯…https://zhuanlan.zhihu.com/p/56712138实操:自动驾驶的车道识别原理及演练(附代码下载)大家五一快乐呀,我是李慢慢。前情提要距离上一次正儿八经发文,貌似已经过去两个月了,因为疫情原因我一直都是居家https://mp.weixin.qq.com/s/9ykWyXsCnTVqyojRlb7H9A

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/64032.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python入门自学进阶-Web框架——38、redis、rabbitmq、git

缓存数据库redis&#xff1a; NoSQL&#xff08;Not only SQL&#xff09;泛指非关系型的数据库。为了解决大规模数据集合多重数据类的挑战。 NoSQL数据库的四大分类&#xff1a; 键值&#xff08;Key-Value&#xff09;存储数据库列存储数据库文档型数据库图形&#xff08;…

STM32基础入门学习笔记:核心板 电路原理与驱动编程

文章目录&#xff1a; 一&#xff1a;LED灯操作 1.LED灯的点亮和熄灭 延迟闪烁 main.c led.c led.h BitAction枚举 2.LED呼吸灯&#xff08;灯的强弱交替变化&#xff09; main.c delay.c 3.按键控制LED灯 key.h key.c main.c 二&#xff1a;FLASH读写程序(有…

C语言预处理命令 #error 学习

#error命令是C/C语言的预处理命令之一&#xff0c;当预处理器预处理到#error命令时将停止编译并输出用户自定义的错误消息。 如下代码输出数字1000&#xff0c;如果加了 #error&#xff0c;构建时不会通过&#xff0c;提示出错如下&#xff1b; 这可能在大型项目中比较有用&am…

Ubuntu 22.04安装和使用ROS1可行吗

可行。 测试结果 ROS1可以一直使用下去的&#xff0c;这一点不用担心。Ubuntu会一直维护的。 简要介绍 Debian发行版^_^ AI&#xff1a;在Ubuntu 22.04上安装ROS1是可行的&#xff0c;但需要注意ROS1对Ubuntu的支持只到20.04。因此&#xff0c;如果要在22.04上安装ROS1&am…

使用webpack插件webpack-dev-server 出现Cannot GET/的解决办法

问题描述 文档地址深入浅出webpack 使用 DevServer运行webpack&#xff0c;跑起来之后提示Cannot GET/&#xff1a; 解决方案&#xff1a; 查阅官方文档 根据目录结构修改对应的配置&#xff1a; 然后就可以成功访问&#xff1a;

帆软设计器报表加载不出折线图的原因

最近在用帆软设计器做可视化图表。偶有遇到因为数据集的字段类型导致加载不出折线&#xff0c;现记录如下。做报表的同行可以参考。 数据库使用了 Oracle 11g。数据集的 SQL 代码片是之前用在另一个单元格报表里面的。页面上有一个率是直接计算得出&#xff0c;我为了方便、就…

Java开发 - Redis事务怎么用?

前言 最近博主感觉捅了Redis窝&#xff0c;从Redis主从&#xff0c;哨兵&#xff0c;集群&#xff0c;集群原理纷纷讲了一遍&#xff0c;不知道大家都学会了多少&#xff0c;想着送佛送到西&#xff0c;不如再添一把火&#xff0c;所以今天带给大家的博客是Redis事务&#xff…

Linux基本开发工具(一)

文章目录 Linux基本开发工具&#xff08;一&#xff09;Linux安装和卸载软件Linux 软件包管理器 yum关于sudo命令关于yum源的换源问题 vim编辑器的使用vim三种模式&#xff08;常见&#xff09;vim的基本操作vim配置 Linux基本开发工具&#xff08;一&#xff09; Linux安装和…

探秘手机隐藏的望远镜功能:开启后,观察任何你想看的地方

当今的智能手机不仅仅是通信工具&#xff0c;它们蕴藏着各种隐藏的功能&#xff0c;其中之一就是让你拥有望远镜般的观察能力。是的&#xff0c;你没有听错&#xff01;今天我们将探秘手机中隐藏的望远镜功能&#xff0c;这项神奇的功能可以让你打开后&#xff0c;轻松观察任何…

/usr/bin/ld: 找不到 can‘t find -xxx++

ld是一个链接器文件&#xff0c;后面报错一般都是什么库找不到&#xff0c;so文件 我们去根目录下全局找一下该文件 cd / find -name *libstdc.so*一般都会在lib64下面找到&#xff0c;注意后面带版本号的是实际文件 我们需要把他复制到lib文件下&#xff0c;ld找的是软连接文…

3.01 用户在确认订单页收货地址操作

用户在确认订单页面&#xff0c;可以针对收货地址做如下操作&#xff1a; 1. 查询用户的所有收货地址列表 2. 新增收货地址 3. 删除收货地址 4. 修改收货地址 5. 设置默认地址步骤1&#xff1a;创建对应用户地址BO public class AddressBO {private String addressId;private…

封装上传文件组件(axios,onUploadProgress,取消请求)

目录 定时模拟进度条 方法 A.axios B.xhr 取消请求​​​​​​​ 完整代码 A.自定义上传组件 B.二次封装组件 情况 增加cancelToken不生效&#xff0c;刷新页面 进度条太快->设置浏览器网速 定时模拟进度条 startUpload() {if (!this.file) return;const totalS…

flink kafka消费者如何处理kafka主题的rebalance

背景&#xff1a; 我们日常使用kafka客户端消费kafka主题的消息时&#xff0c;当消费者退出/加入消费者组&#xff0c;kafka主题分区数有变等事件发生时&#xff0c;都会导致rebalance的发生&#xff0c;此时一般情况下&#xff0c;如果我们不自己处理offset&#xff0c;我们不…

Vue3+Vite+Pinia+Naive后台管理系统搭建之九:layout 动态路由布局

前言 如果对 vue3 的语法不熟悉的&#xff0c;可以移步Vue3.0 基础入门&#xff0c;快速入门。 1. 系统页面结构 由 menu&#xff0c;面包屑&#xff0c;用户信息&#xff0c;页面标签&#xff0c;页面内容构建 ​ 2. 创建页面 创建 src/pages/layout.vue 布局页 创建 sr…

python 封装sql 增删改查连接MySQL

select * from Teacher limit 10 连接字符串配置MysqlConfig.py class MysqlConfig:HOST 192.168.56.210PORT 3306USER rootPASSWORD 1qaz0987654321DBStudentDBCHARSET utf8封装增删改查MysqlConnection.py Author: tkhywang 2810248865qq.com Date: 2023-06-19 15:44:48 Las…

VMware Workstation及CentOS-7虚机安装

创建新的虚机&#xff1a; 选择安装软件&#xff08;这里选的是桌面版&#xff0c;也可以根据实际情况进行选择&#xff09; 等待检查软件依赖关系 选择安装位置&#xff0c;自主配置分区 ​​​​​​​ 创建一个普通用户 安装完成后重启 点击完成配置&#xff0c;进入登陆界面…

Vue3 列表渲染简单应用

去官网学习→列表渲染 | Vue.js 运行示例&#xff1a; 代码&#xff1a;HelloWorld.vue <template><div class"hello"><h1>Vue 列表渲染</h1><p v-for"item in dataList">{{item}}</p><p v-for"(item,index)…

ros tf

欢迎访问我的博客首页。 tf 1. tf 命令行工具1.1 发布 tf1.2 查看 tf 2.参考 1. tf 命令行工具 1.1 发布 tf 我们根据 cartographer_ros 的 launch 文件 backpack_2d.launch 写一个 tf.launch&#xff0c;并使用命令 roslaunch cartographer_ros tf.launch 启动。该 launch 文件…

认识所有权

专栏简介&#xff1a;本专栏作为Rust语言的入门级的文章&#xff0c;目的是为了分享关于Rust语言的编程技巧和知识。对于Rust语言&#xff0c;虽然历史没有C、和python历史悠远&#xff0c;但是它的优点可以说是非常的多&#xff0c;既继承了C运行速度&#xff0c;还拥有了Java…

zookeeper的部署

一 先下载zookeeper 二 解压包 三 修改配置文件 四 把配好文件传到其他的节点上面 五 在每个节点的dataDir指定的目录下创建一个 myid 的文件 六 配置zook的启动脚本 七 设置开机自启 八 分别启动 九查看当前状态service zookeeper status 十 总结 一 先下载zookeeper …