从车道检测项目入门open cv
从车道检测项目入门open cv
前提声明:非常感谢b站up主 嘉然今天吃带变,感谢其视频的帮助。同时希望各位大佬积积极提出宝贵的意见。😊😊😊(❁´◡`❁)(●’◡’●)╰(°▽°)╯
github地址:https://github.com/lizhongzheng13/openCV_Lane_Detection/tree/main
视频地址:从车道检测项目入门open cv
基础知识
cv2.imread & cv2.imshow & cv2.imwrite
import cv2 as cvimg = cv.imread("img.png", cv.IMREAD_GRAYSCALE) #将图片转为灰度图
但是当前会存在一些问题,图片会闪一下,看不清楚,所以我们可以加上阻塞
cv2.waitKey()
函数
#完整版
import cv2 as cvimg = cv.imread("img.png", cv.IMREAD_GRAYSCALE)
print(type(img))
print(img.shape)
cv.imshow('image', img)
k = cv.waitKey(0) # 阻塞 #k相当于检测你的输入的ascii值
print(k)
# while True:
# if cv.waitKey(0) == ord('q'):
# cv.destroyAllWindows()
# else:
# img = cv.imread("img.png", cv.IMREAD_GRAYSCALE)cv.imwrite("img_gray.png", img)#生成img图片,保存到当前目录中~
效果展示
原始图像:
![]()
灰度图:
![]()
Canny边缘检测
通过求取图像上每一个像素点周边图像像素变化的梯度,来确定这个点是否是边缘。

梯度的方向一般总是与边界垂直,梯度的方向被归为四类:垂直、水平和两个对角线(即,0度、45度、90度和135度四个方向)。

我们现在的想法是设置一个阈值,当梯度大于阈值时,我们可以认为该点是边缘。但是随之而来的是,图片会产生一些毛边或者光线,角度等问题,导致可能会误判。

为了解决这个问题,我们采用双阈值的方法,一个上阈值,一个下阈值。

我们认为高于上阈值的点为强边缘,在上阈值和下阈值之间的我们认为是弱边缘。
我们认为只有弱边缘与强边缘相连的话,才是边缘。B不认为是边缘,可能是噪声;C与A强边缘相连,我们认为C是边缘。
import cv2img = cv2.imread("img.png", cv2.IMREAD_GRAYSCALE)edge_img = cv2.Canny(img, 190, 350) # 下边缘和上边缘的阈值设定 #需要自行更改
cv2.imshow("edge", edge_img)
cv2.waitKey(0)

当上边缘和下边缘都升高时,边缘显示会越来越少。
ROI mask
简单来讲就是类似于抠图,就是剔除无关信息的边缘。
roi : region of interest 感兴趣的区域
数组切片
布尔运算(与运算)

-
cv2.fillPoly
是 OpenCV 中的一个函数,用于在图像中填充多边形区域。它常用于绘制、遮罩或标记图像中的特定区域。通过指定多边形的顶点,cv2.fillPoly
可以将这些区域填充为指定的颜色。 -
cv2.bitwise_and
是 OpenCV 中的一个函数,用于对两个图像或数组进行按位与(bitwise AND)操作。按位与操作是逐像素进行的,只有当两个图像的对应像素都为非零值时,结果图像的该像素才为非零值。-
图像遮罩:
- 使用掩码提取图像的特定区域。例如,将一个形状(如矩形、圆形或多边形)作为掩码,只保留掩码内的图像内容。
-
图像合成:
- 将两个图像的特定部分组合在一起。
-
图像处理:
- 在图像处理中,按位与操作常用于对图像进行区域选择或区域遮挡。
-
图像以矩阵np.array形式存储在内存中
np.zeros_like : np.zeros_like
是 NumPy 库中的一个函数,用于创建一个与给定数组形状和数据类型相同的数组,但所有元素都初始化为零。
# @Author : LiZhongzheng
# 开发时间 :2025-04-28 17:30
import cv2
import numpy as npedge_img = cv2.imread("edge_img.png", cv2.IMREAD_GRAYSCALE)
mask = np.zeros_like(edge_img) # 获取一个与edge_img大小相同的数组
mask = cv2.fillPoly(mask, np.array([[[0, 569], [661, 195], [914, 248], [979, 592]]]),color=255) # array中的存放的是想要识别区域的四个顶点 #顺序为左下、左上、右上、右下masked_edge_img = cv2.bitwise_and(edge_img, mask)
# cv2.imshow('mask', mask)
# cv2.waitKey(0)
cv2.imshow("edged", masked_edge_img)
cv2.waitKey(0)

霍夫变换
提取图片中的直线。
注意:霍夫变换是针对灰度图的。



min是最短线段的长度,max是两点之间的最大距离,超过这个距离就不认为是线段了。
-
首先经过 cv2.HoughLinesP()函数获取到所有的线条,然后计算线条的斜率,根据斜率的正负判断是左车道线还是右车道线。
-
# @Author : LiZhongzheng # 开发时间 :2025-04-29 8:54 import cv2 import numpy as npdef calculate_slope(line):"""计算线段line的斜率:param line: np.array([[x_1, y_1, x_2, y_2]]):return:"""x_1, y_1, x_2, y_2 = line[0]return (y_2 - y_1) / (x_2 - x_1)edge_img = cv2.imread('masked_edge_img.jpg', cv2.IMREAD_GRAYSCALE) # 获取所有线段 lines = cv2.HoughLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40,maxLineGap=20) # 按照斜率分成车道线 left_lines = [line for line in lines if calculate_slope(line) > 0] right_lines = [line for line in lines if calculate_slope(line) < 0]print("left_lines =", len(left_lines)) print("right_lines =", len(right_lines))
-
离群值过滤
剔除出因为误差而被识别出的直线。
如何分解出噪点和车道线那?
- 我们可以知道,车道线的斜率大致是相同的,进而可以分辨出噪点和车道线。
# @Author : LiZhongzheng
# 开发时间 :2025-04-29 9:01
import cv2
import numpy as np"""
剔除出因为误差而被识别出的直线。
如何分解出噪点和车道线那?我们可以知道,车道线的斜率大致是相同的,进而可以分辨出噪点和车道线。
"""def calculate_slope(line):"""计算线段line的斜率:param line: np.array([[x_1, y_1, x_2, y_2]]):return:"""x_1, y_1, x_2, y_2 = line[0]return (y_2 - y_1) / (x_2 - x_1)edge_img = cv2.imread('masked_edge_img.jpg', cv2.IMREAD_GRAYSCALE)# 获取所有线段
lines = cv2.HoughLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40, maxLineGap=20)# 按照斜率分成车道线
left_lines = [line for line in lines if calculate_slope(line) > 0]
right_lines = [line for line in lines if calculate_slope(line) < 0]def reject_abnormal_lines(lines, threshold):"""剔除斜率不一致的线段:param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]"""slopes = [calculate_slope(line) for line in lines]while len(lines) > 0:mean = np.mean(slopes) # 使用 NumPy 的 np.mean 函数计算当前所有斜率的平均值diff = [abs(s - mean) for s in slopes] # 遍历 slopes 列表,计算每个斜率与平均斜率的绝对差值,并将结果存储在 diff 列表中idx = np.argmax(diff) # 使用 NumPy 的 np.argmax 函数找到 diff 列表中最大值的索引,即斜率差异最大的线段。if diff[idx] > threshold: # 如果最大差异大于阈值 threshold,则认为该线段是异常的,将其从 slopes 和 lines 列表中移除。slopes.pop(idx)lines.pop(idx)else: # 如果最大差异小于或等于阈值,则认为所有线段的斜率已经足够一致,退出循环。breakreturn lines # 如果最大差异小于或等于阈值,则认为所有线段的斜率已经足够一致,退出循环。print('before filter:')
print('left lines number=')
print(len(left_lines))
print('right lines number=')
print(len(right_lines))reject_abnormal_lines(left_lines, threshold=0.2)
reject_abnormal_lines(right_lines, threshold=0.2)print('after filter:')
print('left lines number=')
print(len(left_lines))
print('right lines number=')
print(len(right_lines))
最小二乘拟合
将lines的线段拟合成一条直线。
np.ravel 将高维数组拉成一维
np.polyfit 多项式拟合
np.polyval 多项式求值
-
经过上述的步骤,进而我们可以求出车道线的数量等信息,同时又剔除了噪点。然后我们就可以将在同一个区域的线段拟合一条直线
-
# @Author : LiZhongzheng # 开发时间 :2025-04-29 15:58 import cv2 import numpy as npdef calculate_slope(line):"""计算线段line的斜率:param line: np.array([[x_1, y_1, x_2, y_2]]):return:"""x_1, y_1, x_2, y_2 = line[0]return (y_2 - y_1) / (x_2 - x_1)edge_img = cv2.imread("masked_edge_img.jpg", cv2.IMREAD_GRAYSCALE) # 获取所有线段 lines = cv2.HoughLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40, maxLineGap=20)# 按照斜率分成车道线 left_lines = [line for line in lines if calculate_slope(line) > 0] right_lines = [line for line in lines if calculate_slope(line) < 0]def reject_abnormal_lines(lines, threshold):"""剔除斜率不一致的线段:param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]"""slopes = [calculate_slope(line) for line in lines]while len(lines) > 0:mean = np.mean(slopes)diff = [abs(s - mean) for s in slopes]idx = np.argmax(diff)if (diff[idx] > threshold):slopes.pop(idx)lines.pop(idx)else:breakreturn linesleft_lines = reject_abnormal_lines(left_lines, threshold=0.2) right_lines = reject_abnormal_lines(right_lines, threshold=0.2)def least_squares_fit(lines):"""将lines中的线段拟合成一条线段:param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]:return: 线段上的两点,np.array([[xmin, ymin], [xmax, ymax]])"""# 1. 取出所有坐标点"""在 OpenCV 中,线段通常用一个形状为 (1, 4) 的 NumPy 数组表示,其中包含线段的两个端点的坐标。具体来说,数组的格式为 [x1, y1, x2, y2],分别表示起点 (x1, y1) 和终点 (x2, y2)。"""x_coords = np.ravel([[line[0][0], line[0][2]] for line in lines]) # np.ravel 将二维列表展平为一维数组y_coords = np.ravel([[line[0][1], line[0][3]] for line in lines])# 2. 进行直线拟合.得到多项式系数poly = np.polyfit(x_coords, y_coords, deg=1)# 3. 根据多项式系数,计算两个直线上的点,用于唯一确定这条直线point_min = (np.min(x_coords), np.polyval(poly, np.min(x_coords)))point_max = (np.max(x_coords), np.polyval(poly, np.max(x_coords)))return np.array([point_min, point_max], dtype=np.int32)print("left lane") print(least_squares_fit(left_lines)) print("right lane") print(least_squares_fit(right_lines))
-
直线绘制
绘制车道线 cv2.line
# @Author : LiZhongzheng
# 开发时间 :2025-04-29 16:23
import cv2
import numpy as npdef calculate_slope(line):"""计算线段line的斜率:param line: np.array([[x_1, y_1, x_2, y_2]]):return:"""x_1, y_1, x_2, y_2 = line[0]return (y_2 - y_1) / (x_2 - x_1)edge_img = cv2.imread('masked_edge_img.jpg', cv2.IMREAD_GRAYSCALE)
# 获取所有线段
lines = cv2.HoughLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40,maxLineGap=20)
# 按照斜率分成车道线
left_lines = [line for line in lines if calculate_slope(line) > 0]
right_lines = [line for line in lines if calculate_slope(line) < 0]def reject_abnormal_lines(lines, threshold):"""剔除斜率不一致的线段:param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]"""slopes = [calculate_slope(line) for line in lines]while len(lines) > 0:mean = np.mean(slopes)diff = [abs(s - mean) for s in slopes]idx = np.argmax(diff)if diff[idx] > threshold:slopes.pop(idx)lines.pop(idx)else:breakreturn linesleft_lines = reject_abnormal_lines(left_lines, threshold=0.2)
right_lines = reject_abnormal_lines(right_lines, threshold=0.2)def least_squares_fit(lines):"""将lines中的线段拟合成一条线段:param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]:return: 线段上的两点,np.array([[xmin, ymin], [xmax, ymax]])"""# 1. 取出所有坐标点x_coords = np.ravel([[line[0][0], line[0][2]] for line in lines])y_coords = np.ravel([[line[0][1], line[0][3]] for line in lines])# 2. 进行直线拟合.得到多项式系数poly = np.polyfit(x_coords, y_coords, deg=1)# 3. 根据多项式系数,计算两个直线上的点,用于唯一确定这条直线point_min = (np.min(x_coords), np.polyval(poly, np.min(x_coords)))point_max = (np.max(x_coords), np.polyval(poly, np.max(x_coords)))return np.array([point_min, point_max], dtype=np.int32)left_line = least_squares_fit(left_lines)
right_line = least_squares_fit(right_lines)img = cv2.imread('img.jpg', cv2.IMREAD_COLOR)
cv2.line(img, tuple(left_line[0]), tuple(left_line[1]), color=(0, 255, 255), thickness=5)
cv2.line(img, tuple(right_line[0]), tuple(right_line[1]), color=(0, 255, 255), thickness=5)cv2.imshow('lane', img)
cv2.waitKey(0)

重难点讲解:least_squares_fit()函数讲解
该函数主要做了三个部分:提取坐标点、进行直线拟合、计算直线上的两个点。
1. 提取所有坐标点
x_coords = np.ravel([[line[0][0], line[0][2]] for line in lines])
y_coords = np.ravel([[line[0][1], line[0][3]] for line in lines])
lines
:- 输入的线段集合,每个线段是一个形状为
(1, 4)
的 NumPy 数组,表示线段的两个端点坐标 [x1,y1,x2,y2]。
- 输入的线段集合,每个线段是一个形状为
x_coords
:- 提取所有线段的 x 坐标。
line[0][0]
是起点的 x 坐标,line[0][2]
是终点的 x 坐标。 - 使用列表推导式
[[line[0][0], line[0][2]] for line in lines]
生成一个二维列表,包含所有线段的起点和终点的 x 坐标。 - 使用
np.ravel
将二维列表展平为一维数组。
- 提取所有线段的 x 坐标。
y_coords
:- 提取所有线段的 y 坐标。
line[0][1]
是起点的 y 坐标,line[0][3]
是终点的 y 坐标。 - 使用列表推导式
[[line[0][1], line[0][3]] for line in lines]
生成一个二维列表,包含所有线段的起点和终点的 y 坐标。 - 使用
np.ravel
将二维列表展平为一维数组。
- 提取所有线段的 y 坐标。
2. 进行直线拟合
poly = np.polyfit(x_coords, y_coords, deg=1)
np.polyfit
:- 这是 NumPy 中的一个函数,用于对给定的数据点进行多项式拟合。
- 参数:
x_coords
:自变量 x 的值。y_coords
:因变量 y 的值。deg=1
:指定拟合多项式的次数为 1,即线性拟合。
- 返回值:
- 返回拟合多项式的系数,从最高次项到常数项。对于线性拟合,返回两个值
[slope, intercept]
,分别表示直线的斜率和截距。
- 返回拟合多项式的系数,从最高次项到常数项。对于线性拟合,返回两个值
3. 计算直线上的两个点
point_min = (np.min(x_coords), np.polyval(poly, np.min(x_coords)))
point_max = (np.max(x_coords), np.polyval(poly, np.max(x_coords)))
np.min(x_coords)
和np.max(x_coords)
:- 分别计算 x 坐标中的最小值和最大值。
np.polyval(poly, x)
:- 这是 NumPy 中的一个函数,用于计算多项式在给定的 x 值处的 y 值。
- 参数:
poly
:拟合多项式的系数数组。x
:输入的 x 值。
- 返回值:
- 返回多项式在 x 处的 y 值。
point_min
和point_max
:point_min
是直线上的一个点,其 x 坐标为最小值,y 坐标通过多项式计算得到。point_max
是直线上的一个点,其 x 坐标为最大值,y 坐标通过多项式计算得到。
4. 返回值
return np.array([point_min, point_max], dtype=np.int32)
- 返回一个形状为
(2, 2)
的 NumPy 数组,表示直线上的两个点的坐标。这两个点可以唯一确定一条直线。
视频流读写
cv2.VideoCapture
capture.read
- 基础代码介绍:
# @Author : LiZhongzheng
# 开发时间 :2025-04-29 17:06
import cv2capture = cv2.VideoCapture('video.mp4')
# capture = cv2.VideoCapture(0) #读取当前设备第0个摄像头
while True:ret, frame = capture.read() # ret 视频流的状态,frame 当前帧的图像cv2.imshow('frame', frame)cv2.waitKey(20) # 相当于播放速率
cv2.VideoWriter
最后我们不仅可以识别图片的车道线还可以识别视频的车道线,原理相同,因为视频是一帧一帧的,每一帧就是一个图片。
# @Author : LiZhongzheng
# 开发时间 :2025-04-29 17:12
import cv2
import numpy as npdef get_edge_img(color_img, gaussian_ksize=5, gaussian_sigmax=1, canny_threshold1=50, canny_threshold2=100):"""灰度化,模糊,canny变换,提取边缘:param color_img: 彩色图,channels=3""""""cv2.GaussianBlur() 函数参数color_img:输入的彩色图像,必须是 3 通道的 BGR 图像。gaussian_ksize(可选):高斯模糊的核大小。必须是正奇数,默认值为 5。gaussian_sigmax(可选):高斯模糊的 X 方向标准差,默认值为 1。"""gaussian = cv2.GaussianBlur(color_img, (gaussian_ksize, gaussian_ksize),gaussian_sigmax) # 使用 cv2.GaussianBlur 对输入图像进行高斯模糊处理。高斯模糊可以减少图像中的噪声,使边缘检测更加稳定。gray_img = cv2.cvtColor(gaussian, cv2.COLOR_BGR2GRAY)edges_img = cv2.Canny(gray_img, canny_threshold1, canny_threshold2)return edges_imgdef roi_mask(gray_img):"""对gray_img进行掩膜:param gray_img: 灰度图,channels=1"""poly_pts = np.array([[[0, 368], [300, 210], [340, 210], [640, 368]]])mask = np.zeros_like(gray_img)mask = cv2.fillPoly(mask, pts=poly_pts, color=255)img_mask = cv2.bitwise_and(gray_img, mask)return img_maskdef get_lines(edge_img):"""获取edge_img中的所有线段:param edge_img: 标记边缘的灰度图"""def calculate_slope(line):"""计算线段line的斜率:param line: np.array([[x_1, y_1, x_2, y_2]]):return:"""x_1, y_1, x_2, y_2 = line[0]return (y_2 - y_1) / (x_2 - x_1)def reject_abnormal_lines(lines, threshold=0.2):"""剔除斜率不一致的线段:param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]"""slopes = [calculate_slope(line) for line in lines]while len(lines) > 0:mean = np.mean(slopes)diff = [abs(s - mean) for s in slopes]idx = np.argmax(diff)if (diff[idx] > threshold):slopes.pop(idx)diff.pop(idx)else:breakreturn linesdef least_squares_fit(lines):"""将lines中的线段拟合成一条线段:param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]:return: 线段上的两点,np.array([[xmin, ymin], [xmax, ymax]])""""""np.polyfit 是 NumPy 库中的一个函数,用于对给定的数据点进行多项式拟合。它通过最小二乘法找到一个多项式,使得这个多项式在给定数据点上的值与实际值之间的误差平方和最小。"""x_coords = np.ravel([[line[0][0], line[0][2]] for line in lines])y_coords = np.ravel([[line[0][1], line[0][3]] for line in lines])poly = np.polyfit(x_coords, y_coords, deg=1)point_min = (np.min(x_coords), np.polyval(poly, np.min(x_coords))) # 这行代码的作用是计算拟合直线(或多项式曲线)上的一个特定点的坐标。具体来说,它计算的是当 x 取最小值时,对应的 y 值,并将这个点的坐标存储为一个元组 (x_min, y_min)。point_max = (np.max(x_coords), np.polyval(poly, np.max(x_coords)))return np.array([point_min, point_max], dtype=np.int32)# 获取所有线段lines = cv2.HoughLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40,maxLineGap=20)# 按照斜率分成车道线left_lines = [line for line in lines if calculate_slope(line) > 0]right_lines = [line for line in lines if calculate_slope(line) < 0]# 剔除离群线段left_lines = reject_abnormal_lines(left_lines)right_lines = reject_abnormal_lines(right_lines)return least_squares_fit(left_lines), least_squares_fit(right_lines)def draw_lines(img, lines):"""在img上绘制lines:param img::param lines: 两条线段: [np.array([[xmin1, ymin1], [xmax1, ymax1]]), np.array([[xmin2, ymin2], [xmax2, ymax2]])]:return:"""left_line, right_line = linescv2.line(img, tuple(left_line[0]), tuple(left_line[1]), color=(0, 255, 255),thickness=5)cv2.line(img, tuple(right_line[0]), tuple(right_line[1]),color=(0, 255, 255), thickness=5)def show_lane(color_img): # 封装"""在color_img上画出车道线:param color_img: 彩色图,channels=3:return:"""edge_img = get_edge_img(color_img)mask_gray_img = roi_mask(edge_img)lines = get_lines(mask_gray_img)draw_lines(color_img, lines)return color_imgif __name__ == '__main__':capture = cv2.VideoCapture('video.mp4')while True:ret, frame = capture.read()frame = show_lane(frame)cv2.imshow('frame', frame)cv2.waitKey(10)

以上就是我对这个项目的总结。
同时再次说明我已经将项目上传到github项目中,欢迎大家多多支持,你们的支持是我最大的前进动力~~~
再次感谢b站up主 嘉然今天吃带变,以及各位大佬的宝贵意见。
祝好~
相关文章:
从车道检测项目入门open cv
从车道检测项目入门open cv 前提声明:非常感谢b站up主 嘉然今天吃带变,感谢其视频的帮助。同时希望各位大佬积积极提出宝贵的意见。😊😊😊(❁◡❁)(●’◡’●)╰(▽)╯ github地址:https://github.com/liz…...
Vue3取消网络请求的方法(AbortController)
在 Vue3 中,已经发出的请求是否可以被取消,取决于你使用的 HTTP 客户端库。Vue3 本身不直接处理 HTTP 请求,但通常搭配 Axios 或原生 fetch 使用。以下是两种主流方案的取消方法: 1. 使用 Axios CancelToken Axios 提供了 Cance…...
深度解析Qwen3:性能实测对标Gemini 2.5 Pro?开源大模型新标杆的部署挑战与机遇
大语言模型(LLM)的浪潮持续席卷技术圈,性能天花板不断被刷新。以 Gemini 2.5 Pro 为代表的闭源模型展现了惊人的能力,但其高昂的成本和有限的可访问性也让许多开发者望而却步。与此同时,开源力量正以前所未有的速度崛起…...
AI遇见端动态神经网络:Cephalon(联邦学习+多模态编码)认知框架构建
前引: 在数字化浪潮席卷全球的今天,数据爆炸与算力需求的指数级增长正推动着云计算向更智能、更高效的方向演进。面对海量终端设备的实时响应需求、复杂AI模型的分布式训练挑战,以及多场景数据的协同处理难题,传统云架构逐渐显露出…...
机器学习之五:基于解释的学习
正如人们有各种各样的学习方法一样,机器学习也有多种学习方法。若按学习时所用的方法进行分类,则机器学习可分为机械式学习、指导式学习、示例学习、类比学习、解释学习等。这是温斯顿在1977年提出的一种分类方法。 有关机器学习的基本概念,…...
高翔视觉slam中常见的OpenCV和Eigen的几种数据类型的内存布局及分配方式详解
vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> 内存布局及分配方式详解 1. 内存对齐的必要性 Eigen 的固定大小类型(如 Eigen::Vector2d、Eigen::Matrix4d 等)需要 16 字节内存对齐,以支持 SIMD 指令(如 SSE/AVX)的并行计算。若未对…...
电子电器架构 --- 人工智能、固态电池和先进自动驾驶功能等新兴技术的影响
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
【C++11】类的新功能
前言 上文我们学习了包装器:function和bind。function可以包装一切可调用对象,并用统一的调用方式调用不同的可调用对象。bind则可以控制函数参数个数【C11】包装器:function与bind-CSDN博客 本文我们来学习C11的类中新增的一些功能 默认的移…...
1.6 点云数据获取方式——单目相机多视图几何
图1-6-1多视图几何重建 单目相机的多视图几何研究具有重要的理论与实际意义。在理...
马井堂-区块链技术:架构创新、产业变革与治理挑战(马井堂)
区块链技术:架构创新、产业变革与治理挑战 摘要 区块链技术作为分布式账本技术的革命性突破,正在重构数字时代的信任机制。本文系统梳理区块链技术的核心技术架构,分析其在金融、供应链、政务等领域的实践应用,探讨共识算法优化、…...
MicroBlaze软核的开发使用
一、MicroBlaze 介绍 MicroBlaze 是由 Xilinx 开发的一种可配置的 32 位 RISC 软处理器内核。它作为 FPGA 设计中的 IP 核,通过 Vivado 工具进行配置和集成。MicroBlaze 提供了高度的灵活性,允许开发人员根据应用需求调整处理器的功能、性能和资源占用。…...
是从原始数据到价值挖掘的完整流程解析,涵盖数据采集、清洗、存储、处理、建模、可视化等核心环节,并附上完整代码示例(含详细注释)及技术选型建议表
以下是从原始数据到价值挖掘的完整流程解析,涵盖数据采集、清洗、存储、处理、建模、可视化等核心环节,并附上完整代码示例(含详细注释)及技术选型建议表。 一、全流程技术栈概览 阶段核心任务关键技术/工具数据采集获取原始数据…...
【爬虫】案例-获取cbh电影
以cupfox.in为例子: 观察ts文件和m3u8文件,可以知道一个完整的视频是由多个ts文件组合,而m3u8则是记录所有ts文件信息的文本 思路 1.先爬一个ts,测试能否观看 2.爬m3u8文件,通过正则分析出变化的部分 3.完整的把每个…...
分治而不割裂—分治协同式敏捷工作模式
分治而不割裂:解密敏捷协同工作模式如何驱动大企业持续领跑 在数字化浪潮中,亚马逊仅用11天完成Prime Day全球技术架构升级,华为5G基站项目组创造过单周迭代47个功能模块的纪录,这些商业奇迹的背后,都隐藏着一个共性秘…...
【MySQL】聚合查询 和 分组查询
个人主页:♡喜欢做梦 欢迎 👍点赞 ➕关注 ❤️收藏 💬评论 目录 🌴 一、聚合查询 🌲1.概念 🌲2.聚合查询函数 COUNT() SUM() AVG(&…...
Weka通过10天的内存指标数据计算内存指标动态阈值
在数据处理和监控系统中,动态阈值的计算是一种常见的方法,用以根据数据的实际分布和变化来调整阈值,从而更有效地监控和预警。在Weka中,虽然它主要是用于机器学习和数据挖掘的工具,但你可以通过一些间接的方法来实现…...
iOS签名的包支持推送功能吗?
推送失败的可能原因: 1. 生产包没有上报token ,所以无法推送成功,需要检查是否在企业包签名后导致无法完成apns的注册,无法从Apple取到token 2. 问题可能出在证书上,因为iOS推送有一个开发证书和一个生产证书ÿ…...
JavaWeb:后端web基础(TomcatServletHTTP)
一、今日内容 二、Tomcat 介绍与使用 介绍 基本使用 小结 配置 配置 查找进程 三、Servlet 什么是Servlet 快速入门 需求 步骤 1.新建工程-模块(Maven) 2.修改打包方式-war 3.编写代码 /*** 可以选择继承HttpServlet*/ WebServlet("/hello&q…...
关于浏览器对于HTML实体编码,urlencode,Unicode解析
目录 HTML实体编码 URL编码 Unicode编码 解析层次逻辑 为什么<script></script>不可以编码符号 为什么不能编码JavaScript:协议 为什么RCDATA标签中的都会被解析成文本 为什么HTML编码了<>无法执行 HTML实体编码 通过特殊语法(<、>…...
C++智能指针滥用带来的性能与内存问题有哪些
在现代C编程中,智能指针(Smart Pointers)已经成为开发者工具箱中不可或缺的一部分。它们作为一种对传统裸指针(Raw Pointers)的替代方案,旨在解决长期困扰C开发者的内存管理难题。C作为一门高性能的系统编程…...
C++算法(17):reverse函数用法详解,头文件<algorithm>与实战示例
在C中,std::reverse 函数用于反转容器或数组中元素的顺序,需包含头文件 <algorithm>。以下是其用法详解: 基本用法 函数原型: template <class BidirIt> void reverse(BidirIt first, BidirIt last); 参数…...
【滑动窗口】最大连续1的个数|将x减到0的最小操作数
文章目录 1.最大连续1的个数2.将x减到0的最小操作数 1.最大连续1的个数 解法: 1.暴力解法给定一个left指针固定左端点元素,再给定一个right指针从左端点元素开始遍历。 当遇到1时,让一个计数器cnt1,当遇到0时,让统计0…...
MySQL 在 CentOS 7 环境下的安装教程
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
嵌入式复习第一章
1. 嵌入式系统概念、应用与特点 2. 嵌入式系统的硬件( CPU 、外设) 3. 主要嵌入式软件系统(应用及 OS ) 4. 嵌入式系统的发展趋势 嵌入式系统定义 “以 应用为中心 ,以计算机技术为基础,并且软硬件…...
【C#】.net core6.0无法访问到控制器方法,直接404。由于自己的不仔细,出现个低级错误,这让DeepSeek看出来了,是什么错误呢,来瞧瞧
🌹欢迎来到《小5讲堂》🌹 🌹这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!&#…...
Tailwind CSS 实战:基于 Kooboo 构建企业官网页面(三)
基于前两篇内容,继续完善企业官网页面: Tailwind CSS 实战:基于 Kooboo 构建企业官网页面(一)-CSDN博客 Tailwind CSS 实战:基于 Kooboo 构建企业官网页面(二)-CSDN博客 3.5 联系方…...
Opencv中图像深度(Depth)和通道数(Channels)区别
在OpenCV中,图像深度(Depth)和通道数(Channels)是两个完全不同的概念,需严格区分。以下是详细解析: 图像深度(Depth) 定义:指图像中每个像素通道的位数&#…...
【网络原理】从零开始深入理解HTTP的报文格式(一)
本篇博客给大家带来的是网络HTTP协议的知识点, 重点介绍HTTP的报文格式. 🐎文章专栏: JavaEE初阶 🚀若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅Ὠ…...
Go语言之路————接口、泛型
Go语言之路————接口 前言接口定义实操,接口的定义和实现接口的继承空接口和Any 泛型类型集 结语 前言 我是一名多年Java开发人员,因为工作需要现在要学习go语言,Go语言之路是一个系列,记录着我从0开始接触Go,到后…...
Go语言中的 `time.Tick` 函数详解
time.Tick 是 Go 标准库中用于创建周期性定时器的简便函数。 函数签名 func Tick(d Duration) <-chan Time核心功能 创建一个周期性的定时器通道当 d < 0 时返回 nil返回一个只读的时间通道,定期发送当前时间 与 NewTicker 的关系 time.Tick 是 time.New…...
打印及判断回文数组、打印N阶数组、蛇形矩阵
打印回文数组 1 1 1 1 1 1 2 2 2 1 1 2 3 2 1 1 2 2 2 1 1 1 1 1 1方法1: 对角线对称 左上和右下是对称的。 所以先考虑左上打印, m i n ( i 1 , j 1 ) \text min(i1,j1) min(i1,j1),打印出来: 1 1 1 1 1 2 2 2 1 2 3 3 1 2 …...
【图像融合】基于非负矩阵分解分解 CNMF的高光谱和多光谱数据融合附MATLAB代码
基于CNMF的高光谱与多光谱数据融合技术详解 一、非负矩阵分解(NMF)与约束非负矩阵分解(CNMF)的核心原理 NMF的基本概念 非负矩阵分解(NMF)是一种通过将非负矩阵分解为两个非负矩阵乘积的降维方法。给定非负…...
HarmonyOS NEXT 诗词元服务项目开发上架全流程实战(一、项目介绍及实现效果)
在当今数字化时代,如何让传统文化与现代科技相结合,成为了一个值得思考的问题。诗词作为中国传统文化的重要组成部分,承载着丰富的历史信息和文化内涵。为了让更多人了解和欣赏诗词的魅力,我们决定开发一款基于HarmonyOS NEXT的诗…...
线性代数与数据学习
The Functions of Deep Learning (essay from SIAM News, December 2018) Deep Learning and Neural Nets...
Linux中的计划任务
一次性任务 功能介绍: 如果我们希望在将来的某个时间点去执行某件事件,这个事件执行完后任务就结束,那么我们 就可以使用一性计划任务。而要实现这种功能,我们需要任务 atd 服务。我们先查询一下系 统是否存在这个服务。 查看是…...
【C++】线程池
C 线程池介绍 什么是线程池? 线程池(Thread Pool) 是一种并发编程模型,用于管理和复用多个线程,避免频繁创建/销毁线程的开销。它通过预创建一组线程,并将任务提交到队列中,由空闲线程自动执行…...
美团社招一面
美团社招一面 做题 1、面试题 <style> .outer{width: 100px;background: red;height: 100px; }.inner {width: 50px;height: 50px;background: green; }</style> <div class"outer"><div class"inner"></div> </div>…...
C++:BST、AVL、红黑树
C:BST、AVL、红黑树 二叉搜索树(BST)二叉平衡搜索树(AVL)红黑树(RBT)三者对比什么情况下使用?C 标准库中的使用总结 二叉搜索树(BST) 二叉搜索树(Binary Sea…...
算法笔记.染色法判断二分图
题目:(来自AcWing) 给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。 请你判断这个图是否是二分图。 输入格式 第一行包含两个整数 n 和 m。 接下来 m 行,每行包含两个整数 u 和 v,表示点 u …...
在 IDEA 中写 Spark 程序:从入门到实践
在大数据处理领域,Apache Spark 凭借其出色的性能和丰富的功能受到广泛欢迎。而 IntelliJ IDEA 作为一款功能强大的 Java 集成开发环境,为编写 Spark 程序提供了极大的便利。本文将详细介绍如何在 IDEA 中搭建 Spark 开发环境并编写运行 Spark 程序&…...
[Spring] Sentinel详解
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
让数据优雅落地:用 serde::Deserialize 玩转结构体实体
前言 想象一下,服务器突然飞来一堆 JSON 数据,就像一群无头苍蝇冲进办公室,嗡嗡作响,横冲直撞。此刻,你的任务,就是把这群“迷路数据”安置进正确的格子里,分门别类,秩序井然,不混不乱,不漏一只。 好在 Rust 早就为我们备好瑞士军刀:serde::Deserialize。它不仅刀…...
【wpf】 WPF中实现动态加载图片浏览器(边滚动边加载)
WPF中实现动态加载图片浏览器(边滚动边加载) 在做图片浏览器程序时,遇到图片数量巨大的情况(如几百张、上千张),一次性加载所有图片会导致界面卡顿甚至程序崩溃。 本文介绍一种 WPF Prism 实现动态分页加…...
Flow原理
fun main() {runBlocking {launch {flow4.collect{println("---collect-4")}println("---flow4")}}val flow4 flow<Boolean>{delay(5000)emit(false) } 我们分析下整个流程 1.flow为什么之后在collect之后才会发送数据 2.collect的调用流程 我…...
业绩回暖、股价承压,三只松鼠赴港上市能否重构价值锚点?
在营收重返百亿俱乐部后,三只松鼠再度向资本市场发起冲击。 4月25日,这家坚果零食巨头正式向港交所递交上市申请书,若成功登陆港股,将成为国内首个实现“AH”双上市的零食品牌。 其赴港背后的支撑力,显然来自近期披露…...
基于大模型的胆总管结石全流程预测与临床应用研究报告
目录 一、引言 1.1 研究背景 1.2 研究目的与意义 1.3 研究方法和创新点 二、大模型在胆总管结石预测中的应用原理 2.1 大模型概述 2.2 模型构建的数据来源与处理 2.3 模型训练与优化 三、术前预测与准备 3.1 术前胆总管结石存在的预测 3.2 基于预测结果的术前检查方…...
QT—布局管理器之BoxLayout篇
1.布局管理器的概述 在Qt中,使用布局管理器的主要原因是它能够自动管理组件的大小和位置,从而实现灵活且动态的界面布局。布局管理器可以自动调整组件以适应窗口大小的变化,确保界面在不同分辨率和设备上都能保持良好的显示效果。这不仅减少了…...
如何在 IntelliJ IDEA 中编写 Speak 程序
在当今数字化时代,语音交互技术越来越受到开发者的关注。如果你想在 IntelliJ IDEA(一个强大的集成开发环境)中编写一个语音交互(Speak)程序,那么本文将为你提供详细的步骤和指南。 一、环境准备 在开始编…...
湖北理元理律师事务所:债务优化的法律机制与民生实践
在债务纠纷日益增多的社会背景下,合法、规范的债务管理服务成为民生需求的重要环节。湖北理元理律师事务所作为经国家司法局注册登记的债事服务机构,以法律为工具,探索出一套覆盖债务咨询、规划与风险防控的服务体系。 1.法律服务的专业化框…...
练习普通话,说话更有节奏
玲珑塔,塔玲珑,玲珑宝塔第一层,一张高桌四条腿, 一个和尚一本经。一个铙钹一口磬,一个木鱼一盏灯。 一个金玲,整四两,风儿一刮响哗愣。 玲珑塔,隔过两层数三层,三张高桌十…...