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

【计算机视觉】基于OpenCV计算机视觉的摄像头测距技术设计与实现

基于计算机视觉的摄像头测距技术

文章目录

  • 基于计算机视觉的摄像头测距技术
    • 导读
    • 引入
    • 技术实现原理
    • 技术实现细节
      • Python-opencv实现方案
      • 获取目标轮廓
        • 步骤 1:图像处理
        • 步骤 2:找到轮廓
        • 步骤完整代码
      • 计算图像距离
        • 前置技术背景与原理
        • 步骤 1:定义距离计算函数
        • 步骤 2:准备调用函数的数据
        • 步骤 3:循环遍历图片并计算距离
    • 完整代码
      • Python
      • C++
      • 运行截图
    • 思路总结
      • 代码逻辑思路
    • 结语

导读

在当今技术日益进步的时代,计算机视觉已成为我们生活中不可或缺的一部分。从智能监控到虚拟现实,计算机视觉技术的应用范围日益广泛。在这篇博客中,我们将探索一个特别实用的计算机视觉案例:使用OpenCV实现摄像头测距。这一技术不仅对专业人士有用,也为编程爱好者和技术创新者提供了广泛的应用可能性。

引入

OpenCV,作为一个功能强大的开源计算机视觉库,已经在全球范围内被广泛应用于各种项目和研究中。其中,摄像头测距是一个极具挑战性且实用的话题。本文将介绍如何利用OpenCV结合相似三角形原理来实现精确的距离测量。无论你是计算机视觉的新手还是有经验的开发者,这篇文章都将为你提供一种新的视角来理解和应用这一领域的基本概念。我们将从相似三角形的基本原理出发,逐步深入,展示如何在实际项目中应用这些知识来实现摄像头测距的功能。。

技术实现原理

使用相似三角形计算物体到相机的距离

在使用相似三角形方法计算摄像头测距时,我们关注的是在不同距离下,同一个物体在相机视野中所占的像素大小变化。这个方法基于一个简单的几何原理:当我们知道某个距离下物体的实际大小和在图像中的大小,就可以推算出在其他距离下的参数。

举一个实际例子,我们可以将此过程的单位转换为厘米来更好地适应中国常用的度量标准。假设我们已知一个物体的真实宽度是 W 厘米,然后将其放置在距离相机 D 厘米的地方进行拍照。在照片中测量该物体的像素宽度为 P 像素,那么可以通过以下公式计算相机的焦距 F(单位为像素):

F = ( P ⋅ D ) / W F = (P \cdot D) / W F=(PD)/W

以实际数据为例,假设我们在距离相机 60.96厘米(大约等于24英寸)的地方放置了一张纸,其宽度为 27.94厘米(大约等于11英寸)。通过图像处理,我们测得照片中纸的像素宽度为 248 像素。那么,焦距 F 计算如下:

F = ( 248 px ⋅ 60.96 cm ) / 27.94 cm ≈ 543.45 px F = (248 \text{px} \cdot 60.96 \text{cm}) / 27.94 \text{cm} ≈ 543.45 \text{px} F=(248px60.96cm)/27.94cm543.45px

现在,无论我们将相机移动得更近或更远,都可以使用相似三角形的原理来计算物体到相机的距离 D’:

D ′ = ( W ⋅ F ) / P D' = (W \cdot F) / P D=(WF)/P

其中,W 是物体的实际宽度(厘米),F 是之前计算得到的焦距(像素),P 是新位置下物体在照片中的宽度(像素)。通过这种方式,我们就能够计算出物体在不同距离下到相机的距离,从而实现精准的测距。

技术实现细节

Python-opencv实现方案

首先,我们需要导入必要的库,并定义一个find_marker函数来定位图像中我们想要测量距离的物体。在这个例子中,我们以一张约A4纸作为目标物体。下面是找到这个目标物体的过程:

from imutils import paths
import numpy as np
import imutils
import cv2# 用于识别要计算距离的物体
def find_marker(image):# 将图像转换为灰度图,然后进行模糊处理,以去除图像中的高频噪声gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (5, 5), 0)# 使用 Canny 算法进行边缘检测edged = cv2.Canny(gray, 35, 125)# 寻找边缘图像中的轮廓,保留最大的一个,假设这是我们图像中的纸张cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)c = max(cnts, key=cv2.contourArea)# 计算纸张区域的边界框,并返回return cv2.minAreaRect(c)

获取目标轮廓

我们的目标是使用 OpenCV 来识别图像中的物体(例如一张纸),并计算它与摄像头之间的距离。首先,我们需要定义一个函数 find_marker,用于在图片中找到我们要计算距离的目标物体。在这个例子中,我们使用一张 8.5 x 11 英寸的纸作为目标物体。

步骤 1:图像处理
# 导入必要的包
from imutils import paths
import numpy as np
import imutils
import cv2# 将图像转换为灰度图,然后进行模糊处理,以减少噪声,最后进行边缘检测
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)

在这几行代码中,我们首先将图像转换为灰度图,这是因为灰度图处理起来更加高效,且对于边缘检测来说足够了。然后,我们使用高斯模糊来降低图像的高频噪声,这有助于后续的边缘检测。最后,我们使用 Canny 算法来检测图像中的边缘。

image-20231203205608370

步骤 2:找到轮廓
# 在边缘检测后的图像中找到轮廓,保留最大的那个轮廓
# 我们假设最大的轮廓就是我们的目标物体(比如纸)
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)# 计算物体轮廓的边界框,并返回
return cv2.minAreaRect(c)

这一部分代码用于找出图像中的所有轮廓,然后选择面积最大的轮廓作为目标物体的轮廓。我们使用 cv2.findContours 函数来检测轮廓,并通过 cv2.contourArea 函数找出最大的轮廓。cv2.minAreaRect 函数则用于计算该轮廓的最小面积矩形,这个矩形包含了轮廓的 (x, y) 坐标以及像素长度和宽度。

步骤完整代码
from imutils import paths
import numpy as np
import imutils
import cv2# 用于识别要计算距离的物体
def find_marker(image):# 将图像转换为灰度图,然后进行模糊处理,以去除图像中的高频噪声gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (5, 5), 0)# 使用 Canny 算法进行边缘检测edged = cv2.Canny(gray, 35, 125)# 寻找边缘图像中的轮廓,保留最大的一个,假设这是我们图像中的纸张cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)c = max(cnts, key=cv2.contourArea)# 计算纸张区域的边界框,并返回return cv2.minAreaRect(c)

阶段总结

  1. 图像预处理:首先,图像被转换为灰度图。灰度图是处理图像的常见方式,因为它简化了分析过程并降低了计算复杂性。接着,对灰度图像应用高斯模糊。这一步骤可以帮助去除图像中的高频噪声,使边缘检测更加准确。
  2. 边缘检测:使用Canny算法进行边缘检测。Canny边缘检测是一种广泛使用的技术,它能够帮助识别图像中物体的轮廓。
  3. 轮廓识别:检测到边缘后,接下来找出图像中所有轮廓,并选择面积最大的轮廓。在这个案例中,假设最大的轮廓是我们要测量距离的目标物体。
  4. 计算包围盒:最后,cv2.minAreaRect函数被用来计算轮廓的最小区域矩形。这个矩形可以用来估计物体的大小和它在图像中的方向,这是后续计算距离所必需的。

接下来,我们将详细探讨如何使用OpenCV和相似三角形原理来计算物体到摄像头的距离。我们会深入每个步骤的技术细节,并解释背后的原理。

计算图像距离

前置技术背景与原理
  • 相似三角形原理:这是计算距离的核心原理。当两个三角形的相应角相等时,它们的边长成比例。在我们的应用中,我们利用这一点来推算物体到摄像头的距离。

  • 焦距的计算与应用:焦距是摄像头镜头中心到成像平面的距离。通过已知距离和物体尺寸,我们可以计算出焦距。然后,使用这个焦距来计算在其他距离下的物体尺寸。

步骤 1:定义距离计算函数
def distance_to_camera(knownWidth, focalLength, perWidth):# 计算并返回从物体到摄像头的距离return (knownWidth * focalLength) / perWidth

这个函数使用三个参数:目标物体的已知宽度(knownWidth)、计算得到的焦距(focalLength)和图像中目标物体的像素宽度(perWidth)。通过相似三角形原理,可以计算出物体到摄像头的距离。

距离计算公式及其解析

函数 distance_to_camera 的核心在于应用相似三角形原理来计算物体到摄像头的距离。这里的计算公式为:

D = W × F P D = \frac{W \times F}{P} D=PW×F
其中,D 代表从物体到摄像头的距离,W 是物体的已知宽度(knownWidth),F 是焦距(focalLength),P 是图像中物体的像素宽度(perWidth)。

公式解析

  1. 已知宽度(W):这是实际物体的宽度,它是我们预先知道的一个固定值,通常用于校准过程。例如,在本例中,如果我们使用一张标准尺寸的纸张,其宽度是一个已知量。

  2. 焦距(F):焦距是相机镜头特性的一部分,表示在光学系统中,光线汇聚成清晰图像的特定距离。在标定过程中通过特定的设置(如已知物体距离和尺寸)计算得出。

  3. 像素宽度(P):这是通过图像处理技术(如边缘检测)从相机拍摄的图像中测量得到的物体的像素宽度。

应用原理

这个公式基于相似三角形的概念。在两个三角形中,如果角度相同,那么它们的边长比例相同。在这种情况下,一侧是实际物体到相机的距离(我们想要计算的),另一侧是物体在相机成像平面上的像素宽度。通过已知的实际宽度和计算出的焦距,我们可以使用比例关系来找出未知的距离。

步骤 2:准备调用函数的数据
# 已知目标物体到摄像头的距离,这里是24英寸
KNOWN_DISTANCE = 24.0# 已知目标物体的宽度,这里是11英寸
KNOWN_WIDTH = 11.0# 加载第一张图片,这张图片中的物体距离摄像头已知,然后找到标记,初始化焦距
image = cv2.imread("images/object.jpg")
marker = find_marker(image)
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH

在这个准备阶段,我们首先确定目标物体到摄像头的已知距离和物体的已知宽度。然后,我们加载一张物体距离摄像头已知的图片,通过 find_marker 函数找到物体的轮廓,并使用这些信息计算焦距。这里的焦距计算基于相似三角形原理,即在已知一定距离下物体在图像中的尺寸,我们可以推算出在其他距离下的尺寸。

步骤 3:循环遍历图片并计算距离
# 遍历每张图片
for imagePath in sorted(paths.list_images("images")):# 加载图片,找到标记,然后计算摄像头到标记的距离image = cv2.imread(imagePath)marker = find_marker(image)inches = distance_to_camera(KNOWN_WIDTH, focalLength, marker[1][0])# 绘制边界框并展示box = cv2.cv.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)box = np.int0(box)cv2.drawContours(image, [box], -1, (0, 255, 0), 2)cv2.putText(image, "%.2fft" % (inches / 12),(image.shape[1] - 200, image.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,2.0, (0, 255, 0), 3)cv2.imshow("image", image)cv2.waitKey(0)

在这个循环中,我们处理每张图片,使用 find_marker 函数找到物体的轮廓,然后调用 distance_to_camera 函数计算物体到摄像头的距离。结果显示在图片上,包括绘制的边界框和距离信息。

完整代码

Python

import cv2
import numpy as np
import imutils
from imutils import pathsclass DistanceCalculator:def __init__(self, knownWidth, knownDistance):# 初始化已知物体宽度和距离self.knownWidth = knownWidthself.knownDistance = knownDistanceself.focalLength = Nonedef calibrate(self, calibrationImagePath):# 使用一张已知距离的图片进行焦距标定image = cv2.imread(calibrationImagePath)marker = self.find_marker(image)self.focalLength = (marker[1][0] * self.knownDistance) / self.knownWidthdef find_marker(self, image):# 在图像中寻找目标物体的轮廓gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (5, 5), 0)edged = cv2.Canny(gray, 35, 125)cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)c = max(cnts, key=cv2.contourArea)return cv2.minAreaRect(c)def distance_to_camera(self, perWidth):# 计算物体到摄像头的距离if self.focalLength is None:raise ValueError("Focal length is not calibrated.")return (self.knownWidth * self.focalLength) / perWidthdef process_image(self, imagePath):# 处理单张图片,并显示距离image = cv2.imread(imagePath)marker = self.find_marker(image)distance = self.distance_to_camera(marker[1][0])box = cv2.cv.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)box = np.int0(box)cv2.drawContours(image, [box], -1, (0, 255, 0), 2)cv2.putText(image, "%.2fcm" % (distance * 2.54), # 将英寸转换为厘米(image.shape[1] - 200, image.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,2.0, (0, 255, 0), 3)cv2.imshow("Distance", image)cv2.waitKey(0)# 主程序
if __name__ == "__main__":KNOWN_DISTANCE = 60.96 # 设置已知距离(厘米)KNOWN_WIDTH = 27.94 # 设置已知物体宽度(厘米)calculator = DistanceCalculator(KNOWN_WIDTH, KNOWN_DISTANCE)calculator.calibrate("images/calibration_image.jpg") # 使用已知距离的图片进行焦距标定for imagePath in sorted(paths.list_images("images")):calculator.process_image(imagePath) # 处理每张图片并计算距离cv2.destroyAllWindows() # 关闭所有OpenCV窗口

C++

请确保你已经安装了C++OpenCV环境。Windows下Visual Studio详情参考可以参考:Windows安装Opencv与VS配置

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <algorithm>class DistanceCalculator {
public:DistanceCalculator(float knownWidth, float knownDistance) : knownWidth(knownWidth), knownDistance(knownDistance), focalLength(0.0f) {}void calibrate(const cv::Mat& calibrationImage) {cv::RotatedRect marker = findMarker(calibrationImage);focalLength = (marker.size.width * knownDistance) / knownWidth;}float distanceToCamera(float perWidth) const {if (focalLength == 0.0f) {throw std::logic_error("Focal length is not calibrated.");}return (knownWidth * focalLength) / perWidth;}cv::RotatedRect findMarker(const cv::Mat& image) const {cv::Mat gray, blurred, edged;cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0);cv::Canny(blurred, edged, 35, 125);std::vector<std::vector<cv::Point>> contours;cv::findContours(edged, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);std::sort(contours.begin(), contours.end(), [](const std::vector<cv::Point>& c1, const std::vector<cv::Point>& c2) {return cv::contourArea(c1) > cv::contourArea(c2);});return cv::minAreaRect(contours[0]);}private:float knownWidth;float knownDistance;float focalLength;
};int main() 
{float KNOWN_DISTANCE = 60.96f; // cmfloat KNOWN_WIDTH = 27.94f; // cmDistanceCalculator calculator(KNOWN_WIDTH, KNOWN_DISTANCE);cv::Mat calibrationImage = cv::imread("calibration_image.jpg");calculator.calibrate(calibrationImage);std::vector<std::string> imagePaths = { "path_to_images/image1.jpg", "path_to_images/image2.jpg", ... };for (const std::string& path : imagePaths) {cv::Mat image = cv::imread(path);cv::RotatedRect marker = calculator.findMarker(image);float distance = calculator.distanceToCamera(marker.size.width);cv::Point2f points[4];marker.points(points);for (int i = 0; i < 4; i++)cv::line(image, points[i], points[(i+1)%4], cv::Scalar(0, 255, 0), 2);std::string text = std::to_string(distance) + " cm";cv::putText(image, text, cv::Point(10, image.rows - 20), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2);cv::imshow("Distance", image);cv::waitKey(0);}cv::destroyAllWindows();return 0;
}

运行截图

当你运行结果会有以下输出

image-20231203222713593

image-20231203222844179

思路总结

本项目的目标是使用OpenCV实现摄像头测距,即计算照片中目标物体到相机的距离。我们采用了相似三角形的方法,利用物体在不同距离下在相机成像平面上的尺寸变化来推算实际距离。首先,通过图像处理技术识别并提取目标物体的轮廓,然后计算焦距,并利用已知的物体宽度和图像中的像素宽度来计算物体到摄像头的距离。

代码逻辑思路

在代码实现方面,我们首先定义了一个处理图像和计算距离的类 DistanceCalculator。这个类包含方法来寻找图像中的目标物体轮廓、计算相机焦距、以及最终计算物体到摄像头的距离。

  1. 图像处理和轮廓检测:对于每张输入图像,首先应用图像处理技术(灰度转换、高斯模糊、边缘检测)来准备图像,并使用find_marker方法提取目标物体的轮廓。
  2. 焦距计算:使用一张已知距离的标定图像来计算焦距。这个过程包括测量标定图像中物体的像素宽度,并根据已知的实际宽度和距离计算焦距。
  3. 距离测量:对于每张图像,使用distance_to_camera方法计算物体到摄像头的距离。这依赖于焦距、已知物体的实际宽度以及图像中物体的像素宽度。
  4. 结果展示:在处理后的图像上绘制物体轮廓,并显示计算出的距离。这不仅提供了视觉反馈,也验证了距离计算的准确性。
  5. 主程序流程:实例化DistanceCalculator类,使用标定图像进行焦距计算,然后遍历目标图像集合,对每张图像进行处理和距离计算。
    • __init__: 构造函数,用于初始化已知的物体宽度和距离。
    • calibrate: 通过一张已知距离的图片计算焦距。这一步是关键,因为正确的焦距计算对于后续的距离测量至关重要。
    • find_marker: 在给定的图像中找到目标物体的轮廓。这通过将图像转换为灰度图,应用高斯模糊和Canny边缘检测来完成。
    • distance_to_camera: 使用计算得到的焦距和图像中物体的像素宽度来计算物体到摄像头的距离。

运行逻辑流程图

开始
DistanceCalculator 类
图像处理和轮廓检测
焦距计算
距离测量
结果展示
图像处理: 灰度转换 高斯模糊 边缘检测
提取目标物体轮廓
使用标定图像计算焦距
计算物体到摄像头的距离
在图像上绘制轮廓和显示距离
结束

结语

如果您喜欢我们的文章,请不要忘记点击关注。我们将继续推出更多关于计算机视觉、人工智能、以及C++、Python、Java等技术领域的精彩内容。您的支持是我们不断前进、分享更多知识和见解的最大动力。我们期待与您一起探索这些激动人心的技术领域,共同成长。感谢您的阅读和支持,敬请期待我们的后续文章!

相关文章:

【计算机视觉】基于OpenCV计算机视觉的摄像头测距技术设计与实现

基于计算机视觉的摄像头测距技术 文章目录 基于计算机视觉的摄像头测距技术导读引入技术实现原理技术实现细节Python-opencv实现方案获取目标轮廓步骤 1&#xff1a;图像处理步骤 2&#xff1a;找到轮廓步骤完整代码 计算图像距离前置技术背景与原理步骤 1&#xff1a;定义距离…...

Java项目实战《苍穹外卖》 四、Swagger接口文档

以铜为镜&#xff0c;可以正衣冠&#xff1b;以人为镜&#xff0c;可以明得失&#xff1b;以史为镜&#xff0c;可以知兴替。 - - - 李世民 系列文章目录 苍穹外卖是黑马程序员2023年的Java实战项目&#xff0c;作为业余练手用&#xff0c;需要源码或者课程的可以找我&#xff…...

深度学习——第03章 Python程序设计语言(3.1 Python语言基础)

无论是在机器学习还是深度学习中&#xff0c;Python已经成为主导性的编程语言。而且&#xff0c;现在许多主流的深度学习框架&#xff0c;例如PyTorch、TensorFlow也都是基于Python。本课程主要是围绕“理论实战”同时进行&#xff0c;所以本章将重点介绍深度学习中Python的必备…...

【人工智能Ⅰ】实验6:回归预测实验

实验6 回归预测实验 一、实验目的 1&#xff1a;了解机器学习中数据集的常用划分方法以及划分比例&#xff0c;并学习数据集划分后训练集、验证集及测试集的作用。 2&#xff1a;了解降维方法和回归模型的应用。 二、实验要求 数据集&#xff08;LUCAS.SOIL_corr-实验6数据…...

前端下载文件的方法-blob下载

前端经常会遇到下载文件的需求&#xff0c;后端一般提供的以下两种方法&#xff1a; 文件地址。后端直接提供要下载的文件地址&#xff0c;常用于图片、音视频等静态文件文件流。后端返回文件流&#xff0c;常用于excel等动态文件 一、a 标签下载 1、直接html使用a标签下载 …...

zookeeper+kafka+ELK+filebeat集群

目录 一、zookeeper概述&#xff1a; 1、zookeeper工作机制&#xff1a; 2、zookeeper主要作用&#xff1a; 3、zookeeper特性&#xff1a; 4、zookeeper的应用场景&#xff1a; 5、领导者和追随者&#xff1a;zookeeper的选举机制 二、zookeeper安装部署&#xff1a; 三…...

【LangChain实战】开源模型学习(2)-ChatGLM3

介绍 ChatGLM3 是智谱AI和清华大学 KEG 实验室联合发布的新一代对话预训练模型。ChatGLM3-6B 是 ChatGLM3 系列中的开源模型&#xff0c;在保留了前两代模型对话流畅、部署门槛低等众多优秀特性的基础上&#xff0c;ChatGLM3-6B 引入了如下特性&#xff1a; 更强大的基础模型&a…...

Python编程技巧 – 迭代器(Iterator)

Python编程技巧 – 迭代器(Iterator) By JacksonML Iterator(迭代器)是Python语言的核心概念之一。它常常与装饰器和生成器一道被人们提及&#xff0c;也是所有Python书籍需要涉及的部分。 本文简要介绍迭代器的功能以及实际的案例&#xff0c;希望对广大读者和学生有所帮助。…...

C语言练习题

C语言练习题 文章目录 C语言练习题题目一题目二题目三题目四题目五题目六题目八 题目一 #include <stdio.h> //VS2022,默认对齐数为8字节 union Un {short s[7];int n; };int main() {printf("%zd", sizeof(union Un));return 0; }代码运行结果:> 16 sizeo…...

常见的AI安全风险(数据投毒、后门攻击、对抗样本攻击、模型窃取攻击等)

文章目录 数据投毒&#xff08;Data Poisoning&#xff09;后门攻击&#xff08;Backdoor Attacks&#xff09;对抗样本攻击&#xff08;Adversarial Examples&#xff09;模型窃取攻击&#xff08;Model Extraction Attacks&#xff09;参考资料 数据投毒&#xff08;Data Poi…...

flutter开发实战-为ListView去除Android滑动波纹

flutter开发实战-为ListView去除Android滑动波纹 在之前的flutter聊天界面上&#xff0c;由于使用ScrollBehavior时候&#xff0c;当时忘记试试了&#xff0c;今天再试代码发现不对。这里重新记录一下为ListView去除Android滑动波纹的方式。 一、ScrollBehavior ScrollBehav…...

牛客在线编程(SQL大厂面试真题)

1.各个视频的平均完播率_牛客题霸_牛客网 ROP TABLE IF EXISTS tb_user_video_log, tb_video_info; CREATE TABLE tb_user_video_log (id INT PRIMARY KEY AUTO_INCREMENT COMMENT 自增ID,uid INT NOT NULL COMMENT 用户ID,video_id INT NOT NULL COMMENT 视频ID,start_time d…...

ubuntu下快速搭建docker环境训练yolov5数据集

参考文档 yolov5-github yolov5-github-训练文档 csdn训练博客 一、配置环境 1.1 安装依赖包 前往清华源官方地址 选择适合自己的版本替换自己的源 # 备份源文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list_bak # 修改源文件 # 更新 sudo apt update &&a…...

SpringMVC常用注解和用法总结

目标&#xff1a; 1. 熟悉使用SpringMVC中的常用注解 目录 前言 1. Controller 2. RestController 3. RequestMapping 4. RequestParam 5. PathVariable 6. SessionAttributes 7. CookieValue 前言 SpringMVC是一款用于构建基于Java的Web应用程序的框架&#xff0c;它通…...

webpack如何处理css

一、准备工作 新建目录 添加样式 .word {color: red; } index.js添加dom元素&#xff0c;添加一个css word import ./css/index.css;const div document.createElement("div"); div.innerText "hello word!!!"; div.className "word"; do…...

IELTS学习笔记_grammar_新东方

参考&#xff1a; 新东方 田静 语法 目录&#xff1a; 导学简单句… x.1 导学 学语法以应用为主。 基础为&#xff1a;单词&#xff0c;语法 进阶为&#xff1a;听说读写译&#xff0c;只考听说读写。 words -> chunks -> sentences, chunks&#xff08;语块的重要…...

【计算机组成原理】存储器知识

目录 1、存储器分类 1.1、按存储介质分类 1.2、按存取方式分类 1.3、按信息的可改写性分类 1.4、按信息的可保存性分类 1.5、按功能和存取速度分类 2、存储器技术指标 2.1、存储容量 2.2、存取速度 3、存储系统层次结构 4、主存的基本结构 5、主存中数据的存放 5.…...

vscode配置代码片段

1.ctrl shift p 然后选择 Snippets:Configure User Snippets &#xff08;配置用户代码片段&#xff09; 2.选择vue或者vue.json 3.下面为json内容 { “vue-template”: { “prefix”: “modal-table”, “body”: [ “”, " <a-modal v-model:visible“visible” wi…...

vite脚手架,手写实现配置动态生成路由

参考文档 vite的glob-import vue路由配置基本都是重复的代码&#xff0c;每次都写一遍挺难受&#xff0c;加个页面就带配置下路由 那就利用 vite 的 文件系统处理啊 先看实现效果 1. 考虑怎么约定路由&#xff0c;即一个文件夹下&#xff0c;又有组件&#xff0c;又有页面&am…...

解决浏览器缓存问题

1.index.html文件meta标签添加属性 <meta name"viewport" content"widthdevice-width,initial-scale1.0, maximum-scale1.0, minimum-scale1.0, user-scalableno" viewport-fitcover >2.提前main.html处理逻辑再跳转到index.html页 <script>…...

【数据中台】开源项目(2)-Davinci可视应用平台

1 平台介绍 Davinci 是一个 DVaaS&#xff08;Data Visualization as a Service&#xff09;平台解决方案&#xff0c;面向业务人员/数据工程师/数据分析师/数据科学家&#xff0c;致力于提供一站式数据可视化解决方案。既可作为公有云/私有云独立部署使用&#xff0c;也可作为…...

Java实现简单飞翔小鸟游戏

一、创建新项目 首先创建一个新的项目&#xff0c;并命名为飞翔的鸟。 其次在飞翔的鸟项目下创建一个名为images的文件夹用来存放游戏相关图片。 用到的图片如下&#xff1a;0~7&#xff1a; bg&#xff1a; column&#xff1a; gameover&#xff1a; ground&#xff1a; st…...

numpy实现神经网络

numpy实现神经网络 首先讲述的是神经网络的参数初始化与训练步骤 随机初始化 任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为0&#xff0c;这样的初始方法对于逻辑回归来说是可行的&#xff0c;但是对于神经网络来说是不可行的。如果我们令所有的初始…...

Bean的加载控制

Bean的加载控制 文章目录 Bean的加载控制编程式注解式ConditionalOn*** 编程式 public class MyImportSelector implements ImportSelector {Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {try {Class<?> clazz Class.forName("…...

使用 OpenCV 识别和裁剪黑白图像上的白色矩形--含源码

为了仅获取具有特定边框颜色的矩形,我寻求一种替代识别图像中的轮廓和所有矩形的传统方法。如示例图片所示,我有兴趣使用 opencv 仅获取白色边框矩形的坐标。任何这方面的建议将不胜感激。到目前为止,我的代码已产生如下所示的输出。我的下一个目标是将图像裁剪到大的中心框…...

LeetCode 每日一题 Day1

1094. 拼车 车上最初有 capacity 个空座位。车 只能 向一个方向行驶&#xff08;也就是说&#xff0c;不允许掉头或改变方向&#xff09; 给定整数 capacity 和一个数组 trips , trip[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客&#xff0c;接…...

【hacker送书活动第7期】Python网络爬虫入门到实战

第7期图书推荐 内容简介作者简介大咖推荐图书目录概述参与方式 内容简介 本书介绍了Python3网络爬虫的常见技术。首先介绍了网页的基础知识&#xff0c;然后介绍了urllib、Requests请求库以及XPath、Beautiful Soup等解析库&#xff0c;接着介绍了selenium对动态网站的爬取和S…...

【算法】希尔排序

目录 1. 说明2. 举个例子3. java代码示例4. java示例截图 1. 说明 1.希尔排序是直接插入排序的一种改进&#xff0c;其本质是一种分组插入排序 2.希尔排序采取了分组排序的方式 3.把待排序的数据元素序列按一定间隔进行分组&#xff0c;然后对每个分组进行直接插入排序 4.随着间…...

四、Zookeeper节点类型

目录 1、临时节点 2、永久节点 Znode有两种,分别为临时节点和永久节点。 节点的类型在创建时即被确定,并且不能改变。 1、临时节点 临时节点的生命周期依赖于创建它们的会话。一旦会话结束,临时节点将被自动删除,...

arcgis导出某个属性的栅格

选中栅格特定属性想要导出时&#xff0c;无法选中“所选图形” 【方法】spatial analyst 工具——提取分析——按属性提取...