【计算机视觉】基于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 paths

class DistanceCalculator:
    def __init__(self, knownWidth, knownDistance):
        # 初始化已知物体宽度和距离
        self.knownWidth = knownWidth
        self.knownDistance = knownDistance
        self.focalLength = None

    def calibrate(self, calibrationImagePath):
        # 使用一张已知距离的图片进行焦距标定
        image = cv2.imread(calibrationImagePath)
        marker = self.find_marker(image)
        self.focalLength = (marker[1][0] * self.knownDistance) / self.knownWidth

    def 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) / perWidth

    def 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; // cm
    float KNOWN_WIDTH = 27.94f; // cm

    DistanceCalculator 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等技术领域的精彩内容。您的支持是我们不断前进、分享更多知识和见解的最大动力。我们期待与您一起探索这些激动人心的技术领域,共同成长。感谢您的阅读和支持,敬请期待我们的后续文章!

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

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

相关文章

【tensorflow学习-选择动作】 学习tensorflow代码调用过程

a actor.choose_action(s) def choose_action(self, s):s s[np.newaxis, :]return self.sess.run(self.action, {self.s: s}) # get probabilities for all actions输入&#xff1a;s 输出&#xff1a;self.sess.run(self.action, {self.s: s}) &#xff1a;a

【云原生Prometheus篇】Prometheus PromQL语句详解 1.0

文章目录 一、前言1.1 Prometheus的时间序列1.1.1 指标名称1.1.2 标签1.1.3 使用的注意事项 1.2 样本数据格式1.3 Prometheus 的聚合函数 二 、PromQL 理论部分2.1 PromQL简介2.2 PromQL的数据类型2.3 时间序列选择器2.3.1 瞬时向量选择器 &#xff08;Instant Vector Selector…

React使用TailwindCSS

React中使用TailwindCSS TailwindCSS是 下载及初始化 可以查看官网对照自己使用的框架进行配置 npm install -D tailwindcss postcss autoprefixer下载完毕后执行如下命令 npx tailwindcss init -p可以发现项目中多了两个文件 其中默认已经进行了配置&#xff0c;我们需要将…

JSP格式化标签 parseNumber指定格式字符串转数字类型

好 我们继续来说格式化标签 parseNumber 它的作用是讲一个字符串 转换为指定格式的数值型 老实说 这东西 作为了解把 实际开发中都不是用得少 我建议还是在java端就处理好 不建议在jsp中高这种类型转换的操作 基本格式如下 这几个属性都是我们这几期jsp标签的老朋友了 我们…

bean依赖属性配置

bean依赖属性配置 文章目录 bean依赖属性配置 Data ConfigurationProperties(prefix "cartoon") public class CartoonProperties {private Cat cat;private Mouse mouse; }cartoon:cat:name: whatage: 5mouse:name: howage: 6这样的话&#xff0c;业务bean无需在读…

使用AOS实现网页动画效果

在现代Web开发中&#xff0c;动画效果是提升用户体验和页面交互性的重要因素之一。而AOS&#xff08;Animate On Scroll&#xff09;作为一个强大的动画库&#xff0c;可以帮助我们轻松地实现网页元素的滚动动画效果。 什么是AOS&#xff1f; AOS是一个基于CSS3和JavaScript的…

[C/C++]数据结构 关于二叉树的OJ题(利用分治思想解决难题)

题目一: 单值二叉树 &#x1f6a9;⛲&#x1f31f;⚡&#x1f966;&#x1f4ac; &#x1f6a9;题目链接:力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 ⛲题目描述: 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。…

docker部署typecho博客

文章目录 1.安装git2.安装compose3.拉取仓库4.创建目录5.配置文件修改6.启动容器7.修改MYSQL数据库8.安装成功9.参考GitHub文档 1.安装git 安装git yum -y install git2.安装compose &#xff08;docker安装参考&#xff1a;docker基本知识&#xff09; 确保已经安装了 Doc…

如何捕捉股票短线机会

一、个股相关新闻 1、盈利变化 当公司的盈利能力提升时&#xff0c;投资者就会积极地买入该股&#xff0c;股价短期内会上升。尤其是财报即将发布的阶段&#xff0c;那些能够盈利预增的股票往往会受到投资者青睐&#xff0c;使股价在短时间内大幅上涨。 比如&#xff0c;2022年…

【C++】类和对象——explicit关键字,友元和内部类

这篇博客已经到了类和对象的最后一部分了&#xff0c;下面我们先看一下explicit关键字 我们还是先来引入一个例子&#xff0c;我们的代码是可以这么写的 class A { public:A(int aa 0) {_a aa;cout << "A(int aa 0)" << endl;} private:int _a; }; i…

Python读取栅格遥感影像并加以辐射校正后导出为Excel的一列数据

本文介绍基于Python语言中的gdal模块&#xff0c;读取一景.tif格式的栅格遥感影像文件&#xff0c;提取其中每一个像元的像素数值&#xff0c;对像素值加以计算&#xff08;辐射定标&#xff09;后&#xff0c;再以一列数据的形式将计算后的各像元像素数据保存在一个.csv格式文…

llama.cpp部署通义千问Qwen-14B

llama.cpp是当前最火热的大模型开源推理框架之一&#xff0c;支持了非常多的LLM的量化推理&#xff0c;生态比较完善&#xff0c;是个人学习和使用的首选。最近阿里开源了通义千问大语言模型&#xff0c;在众多榜单上刷榜了&#xff0c;是当前最炙手可热的开源中文大语言模型。…

使用postman请求x5接口

x5接口简介 1.接口样例 {"header"{"appid":"bpmnew_fanwei","sign":"C033162E86E4CADE80C7EB44D68A5AD2","sign_type":"md5","url":"https://oa.mioffice.cn/api/bpm/xm/app/show/tod…

Java线程安全问题

一、共享资源 共享资源是指&#xff0c;同时会有多个线程访问的资源。 二、线程安全问题 线程安全问题是指多个线程同时读写共享资源时并且没有任何同步措施的情况下&#xff0c;出现脏数据或者其他不可预见的结果的问题。当然如果所有线程都只是读取共享资源而不去修改共享…

LTO编译器优化介绍以及开启方法

文章目录 LTO介绍LTO 开启方法 LTO介绍 LTO&#xff08;Link Time Optimization&#xff0c;链接时优化&#xff09;是一种在链接阶段进行优化的技术。传统的编译过程中&#xff0c;编译器仅能对单个编译单元进行优化。LTO 允许编译器看到跨编译单元的代码&#xff0c;从而进行…

实战案例:chatglm3 基础模型多轮对话微调

chatglm3 发布了&#xff0c;这次还发了base版本的模型&#xff0c;意味着我们可以基于这个base模型去自由地做SFT了。 本项目实现了基于base模型的SFT。 base模型 https://huggingface.co/THUDM/chatglm3-6b-base由于模型较大&#xff0c;建议离线下载后放在代码目录&#…

OpenTelemetry系列 - 第2篇 Java端接入OpenTelemetry

目录 一、架构说明二、方式1 - 自动化2.1 opentelemetry-javaagent.jar&#xff08;Java8 &#xff09;2.2 使用opentelemetry-javaagent.jar完成自动注入2.3 配置opentelemetry-javaagent.jar2.4 使用注解&#xff08;WithSpan, SpanAttribute&#xff09;2.5.1 代码集成WithS…

智能诊疗体验:整合AI技术的互联网医院小程序开发

在科技化的趋势下&#xff0c;互联网医院小程序的开发变得愈发重要&#xff0c;尤其是通过整合人工智能&#xff08;AI&#xff09;技术&#xff0c;进一步提升了就医的效率。 一、引言 互联网医院小程序其开发目标是提高医疗服务的效率&#xff0c;同时也也提升了用户的就医…

【读书笔记】微习惯

周日晚上尝试速读一本书《微习惯》&#xff0c;共七章看了下目录结构并不复杂&#xff0c;计划每章7-8分钟读完&#xff0c; 从20:15-21:00。读的时候&#xff0c;订下闹钟&#xff0c;催促着自己的进度。边读边记了一些要点和微信读书里面的划线。 第六章实践内容最为丰富&…

Ubuntu中安装IDEA,并配置桌面快捷方式

1、首先自己下载linux版本的idea 这一步省略不说了 2、在/usr/local/路径下新建安装目录IDEA&#xff1a; mkdir -p /usr/local/IDEA3、执行如下命令&#xff0c;解压下载的压缩包到指定目录&#xff1a; tar -zxvf ideaIU-2022.3.3.tar.gz -C /usr/local/IDEA 注意&#x…