亚博microros小车-原生ubuntu支持系列:22 物体识别追踪

背景知识

跟上一个颜色追踪类似。也是基于opencv的,不过背后的算法有很多

  • BOOSTING:算法原理类似于Haar cascades (AdaBoost),是一种很老的算法。这个算法速度慢并且不是很准。
  • MIL:BOOSTING准一点。
  • KCF:速度比BOOSTINGMIL更快,与BOOSTINGMIL一样不能很好地处理遮挡问题。
  • CSRT:KCF更准一些,但是速度比KCF稍慢。
  • MedianFlow:对于快速移动的目标和外形变化迅速的目标效果不好。
  • TLD:会产生较多的false-positives。
  • MOSSE:算法速度非常快,但是准确率比不上KCFCSRT。在一些追求算法速度的场合很适用。
  • GOTURN:OpenCV中自带的唯一一个基于深度学习的算法。运行算法需要提前下载好模型文件。

对算法背后的原理干兴趣的,推荐看看大佬的

几个目标跟踪算法_视频目标跟踪算法-CSDN博客


    def initWorking(self, frame, box):
        '''
        Tracker work initialization 追踪器工作初始化
        frame:初始化追踪画面
        box:追踪的区域
        '''
        if not self.tracker: raise Exception("追踪器未初始化Tracker is not initialized")
        status = self.tracker.init(frame, box)
        #if not status: raise Exception("追踪器工作初始化失败Failed to initialize tracker job")
        self.coord = box
        self.isWorking = True

    def track(self, frame):
        if self.isWorking:#更新跟踪器
            status, self.coord = self.tracker.update(frame)
            if status:#如果跟踪成功,则绘制跟踪框:获取的坐标位置(x,y,w,h)画框就是(x,y),(x+w,y+h)
                p1 = (int(self.coord[0]), int(self.coord[1]))
                p2 = (int(self.coord[0] + self.coord[2]), int(self.coord[1] + self.coord[3]))
                cv.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)
                return frame, p1, p2
            else:
                # 跟踪失败
		# Tracking failed
                cv.putText(frame, "Tracking failure detected", (100, 80), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
                return frame, (0, 0), (0, 0)
        else: return frame, (0, 0), (0, 0)

#!/usr/bin/env python3
# encoding: utf-8
import getpass
import threading
from yahboom_esp32ai_car.astra_common import *
from sensor_msgs.msg import CompressedImage,Image
from std_msgs.msg import Int32, Bool,UInt16
import rclpy
from rclpy.node import Node
from cv_bridge import CvBridge

from rclpy.time import Time
import datetime
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径


class mono_Tracker(Node):
    def __init__(self,name):
        super().__init__(name)
        self.pub_Servo1 = self.create_publisher(Int32,"servo_s1" , 10)#舵机控制
        self.pub_Servo2 = self.create_publisher(Int32,"servo_s2" , 10) 
        #初始化参数
        self.declare_param()
        self.target_servox = 0 #目标中心点x坐标
        self.target_servoy = 10 #目标中心点y坐标
        self.point_pose = (0, 0, 0)  #目标点位置 (x,y,z)
        self.circle = (0, 0, 0) #目标点圆信息 (x,y,radius)
        self.hsv_range = ()  #hsv 颜色范围
        self.dyn_update = True
        self.select_flags = False
        self.gTracker_state = False
        self.windows_name = 'frame'
        self.cols, self.rows = 0, 0 #鼠标选择区域坐标
        self.Mouse_XY = (0, 0) #鼠标点击坐标
        self.index = 2
        self.end = 0
        self.color = color_follow()
    
        self.tracker_types = ['BOOSTING', 'MIL', 'KCF']
        self.tracker_type = ['KCF'] 
        self.VideoSwitch = True
        self.img_flip = False

        self.last_stamp = None
        self.new_seconds = 0
        self.fps_seconds = 1

        ser1_angle = Int32()#舵机初始角度
        ser1_angle.data = int(self.target_servox)
        ser2_angle = Int32()
        ser2_angle.data = int(self.target_servoy)

        #确保角度正常处于中间
        for i in range(10):
            self.pub_Servo1.publish(ser1_angle)
            self.pub_Servo2.publish(ser2_angle)
            time.sleep(0.1)
        


        self.hsv_text = get_package_share_directory('yahboom_esp32ai_car')+'/resource/colorHSV.text'
        self.mono_PID = (12, 0, 0.9)
        self.scale = 1000
        self.PID_init()

        print("OpenCV Version: ",cv.__version__)
        self.gTracker = Tracker(tracker_type=self.tracker_type)
        self.tracker_type = self.tracker_types[self.index]
        self.Track_state = 'init'

        #USB
        #self.capture = cv.VideoCapture(0)
        #self.timer = self.create_timer(0.001, self.on_timer)

        #ESP32_wifi
        self.bridge = CvBridge()
        self.sub_img = self.create_subscription(
            CompressedImage, '/espRos/esp32camera', self.handleTopic, 1) #获取esp32传来的图像


    def declare_param(self):
        #PID
        self.declare_parameter("Kp",12)
        self.Kp = self.get_parameter('Kp').get_parameter_value().integer_value
        self.declare_parameter("Ki",0)
        self.Ki = self.get_parameter('Ki').get_parameter_value().integer_value
        self.declare_parameter("Kd",0.9)
        self.Kd = self.get_parameter('Kd').get_parameter_value().integer_value
    
    def get_param(self):
        self.Kd = self.get_parameter('Kd').get_parameter_value().integer_value
        self.Ki = self.get_parameter('Ki').get_parameter_value().integer_value
        self.Kp = self.get_parameter('Kp').get_parameter_value().integer_value
        self.mono_PID = (self.Kp,self.Ki,self.Kd)
        

    def cancel(self):     
        self.Reset()
        if self.VideoSwitch==False: self.__sub_img.unregister()
        cv.destroyAllWindows()

    # USB
    # def on_timer(self):
    #     self.get_param()
    #     ret, frame = self.capture.read()
    #     action = cv.waitKey(10) & 0xFF
    #     frame, binary =self.process(frame, action)
    #     start = time.time()
    #     fps = 1 / (start - self.end)
    #     text = "FPS : " + str(int(fps))
    #     self.end = start
    #     cv.putText(frame, text, (20, 30), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)
    #     if len(binary) != 0: cv.imshow('frame', ManyImgs(1, ([frame, binary])))
    #     else:cv.imshow('frame', frame)
    #     if action == ord('q') or action == 113:
    #         self.capture.release()
    #         cv.destroyAllWindows()

    #ESP32_wifi  图像回调函数
    def handleTopic(self, msg):
        self.last_stamp = msg.header.stamp  
        if self.last_stamp:
            total_secs = Time(nanoseconds=self.last_stamp.nanosec, seconds=self.last_stamp.sec).nanoseconds
            delta = datetime.timedelta(seconds=total_secs * 1e-9)
            seconds = delta.total_seconds()*100

            if self.new_seconds != 0:
                self.fps_seconds = seconds - self.new_seconds

            self.new_seconds = seconds#保留这次的值

        self.get_param()
        start = time.time()
        frame = self.bridge.compressed_imgmsg_to_cv2(msg)#图像格式转换
        frame = cv.resize(frame, (640, 480))

        action = cv.waitKey(10) & 0xFF #获取按键事件
        frame, binary =self.process(frame, action)#核心处理逻辑
        
        
        end = time.time()
        fps = 1 / ((end - start)+self.fps_seconds)
        
        text = "FPS : " + str(int(fps))
        cv.putText(frame, text, (10,20), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0,255,255), 2)
        cv.imshow('frame', frame)

        if action == ord('q') or action == 113:
            cv.destroyAllWindows()




    def Reset(self):
        self.hsv_range = ()
        self.circle = (0, 0, 0)
        self.Mouse_XY = (0, 0)
        self.Track_state = 'init'
        self.target_servox = 0
        self.target_servoy = 10
    
    #控制舵机
    def execute(self, point_x, point_y):
        # rospy.loginfo("point_x: {}, point_y: {}".format(point_x, point_y))
        #通过PID计算舵机调整量(参数是计算目标位置与图像中心的偏差,图像中心坐标(320,240))
        [x_Pid, y_Pid] = self.PID_controller.update([point_x - 320, point_y - 240])
        if self.img_flip == True:#根据图像翻转标识调整方向
            self.target_servox -= x_Pid
            self.target_servoy += y_Pid
        else:
            self.target_servox -= x_Pid
            self.target_servoy += y_Pid
        #角度控制(保护舵机)    
        if self.target_servox >= 45:
            self.target_servox = 45
        elif self.target_servox <= -45:
            self.target_servox = -45
        if self.target_servoy >= 20:
            self.target_servoy = 20
        elif self.target_servoy <= -90:
            self.target_servoy = -90
        print("servo1",self.target_servox)
        servo1_angle = Int32()
        servo1_angle.data = int(self.target_servox)
        servo2_angle = Int32()
        servo2_angle.data = int(self.target_servoy)
        self.pub_Servo1.publish(servo1_angle)
        self.pub_Servo2.publish(servo2_angle)

    def dynamic_reconfigure_callback(self, config, level):
        self.scale = config['scale']
        self.mono_PID = (config['Kp'], config['Ki'], config['Kd'])
        self.hsv_range = ((config['Hmin'], config['Smin'], config['Vmin']),
                          (config['Hmax'], config['Smax'], config['Vmax']))
        self.PID_init()
        return config

    def PID_init(self):
        self.PID_controller = simplePID(
            [0, 0],
            [self.mono_PID[0] / float(self.scale), self.mono_PID[0] / float(self.scale)],
            [self.mono_PID[1] / float(self.scale), self.mono_PID[1] / float(self.scale)],
            [self.mono_PID[2] / float(self.scale), self.mono_PID[2] / float(self.scale)])
    #鼠标回调,除了param其他都是自动获取  
    def onMouse(self, event, x, y, flags, param):
        if event == 1:#左键点击
            self.Track_state = 'init'
            self.select_flags = True
            self.Mouse_XY = (x,y)
        if event == 4:#左键放开
            self.select_flags = False
            self.Track_state = 'identify'
        if self.select_flags == True:
            self.cols = min(self.Mouse_XY[0], x), min(self.Mouse_XY[1], y)
            self.rows = max(self.Mouse_XY[0], x), max(self.Mouse_XY[1], y)
            self.Roi_init = (self.cols[0], self.cols[1], self.rows[0], self.rows[1])
    #图像处理主流程
    def process(self, rgb_img, action):
        # param action: [113 or 'q':退出],[114 or 'r':重置],[105 or 'i':识别],[32:开始追踪]
        rgb_img = cv.resize(rgb_img, (640, 480))
        binary = []
        if self.img_flip == True: rgb_img = cv.flip(rgb_img, 1)#图像翻转
        #按键处理
        if action == 32: self.Track_state = 'tracking'
        elif action == ord('i') or action == 105: self.Track_state = "identify"
        elif action == ord('r') or action == 114: self.Reset()
        elif action == ord('q') or action == 113: self.cancel()
        if self.Track_state == 'init':#初始化状态
            cv.namedWindow(self.windows_name, cv.WINDOW_AUTOSIZE)
            cv.setMouseCallback(self.windows_name, self.onMouse, 0)
            if self.select_flags == True:#绘制选择区域
                cv.line(rgb_img, self.cols, self.rows, (255, 0, 0), 2)
                cv.rectangle(rgb_img, self.cols, self.rows, (0, 255, 0), 2)
                if self.Roi_init[0] != self.Roi_init[2] and self.Roi_init[1] != self.Roi_init[3]:
                    if self.tracker_type == "color": rgb_img, self.hsv_range = self.color.Roi_hsv(rgb_img, self.Roi_init)#提取roi区域hsv范围
                    self.gTracker_state = True
                    self.dyn_update = True
                else: self.Track_state = 'init'
        if self.Track_state != 'init':#跟踪模式
            if self.tracker_type == "color" and len(self.hsv_range) != 0:
                rgb_img, binary, self.circle = self.color.object_follow(rgb_img, self.hsv_range)#颜色追踪
                if self.dyn_update == True:
                    params = {'Hmin': self.hsv_range[0][0], 'Hmax': self.hsv_range[1][0],
                              'Smin': self.hsv_range[0][1], 'Smax': self.hsv_range[1][1],
                              'Vmin': self.hsv_range[0][2], 'Vmax': self.hsv_range[1][2]}
                    self.dyn_client.update_configuration(params)#更新动态参数
                    self.dyn_update = False
            if self.tracker_type != "color":#其他跟踪模式
                if self.gTracker_state == True:
                    Roi = (self.Roi_init[0], self.Roi_init[1], self.Roi_init[2] - self.Roi_init[0], self.Roi_init[3] - self.Roi_init[1])
                    self.gTracker = Tracker(tracker_type=self.tracker_type)
                    self.gTracker.initWorking(rgb_img, Roi)
                    self.gTracker_state = False
                rgb_img, (targBegin_x, targBegin_y), (targEnd_x, targEnd_y) = self.gTracker.track(rgb_img)#执行追踪
                center_x = targEnd_x / 2 + targBegin_x / 2
                center_y = targEnd_y / 2 + targBegin_y / 2
                width = targEnd_x - targBegin_x
                high = targEnd_y - targBegin_y
                self.point_pose = (center_x, center_y, min(width, high))
        if self.Track_state == 'tracking':#执行追踪
            if self.circle[2] != 0: threading.Thread(target=self.execute, args=(self.circle[0], self.circle[1])).start()
            if self.point_pose[0] != 0 and self.point_pose[1] != 0: threading.Thread(target=self.execute, args=(self.point_pose[0], self.point_pose[1])).start()
        if self.tracker_type != "color": cv.putText(rgb_img, " Tracker", (260, 20), cv.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2)
        return rgb_img, binary

class simplePID:
    '''very simple discrete PID controller'''

    def __init__(self, target, P, I, D):
        '''Create a discrete PID controller
        each of the parameters may be a vector if they have the same length
        Args:
        target (double) -- the target value(s)
        P, I, D (double)-- the PID parameter
        '''
        # check if parameter shapes are compatabile.
        if (not (np.size(P) == np.size(I) == np.size(D)) or ((np.size(target) == 1) and np.size(P) != 1) or (
                np.size(target) != 1 and (np.size(P) != np.size(target) and (np.size(P) != 1)))):
            raise TypeError('input parameters shape is not compatable')
       # rospy.loginfo('P:{}, I:{}, D:{}'.format(P, I, D))
        self.Kp = np.array(P)
        self.Ki = np.array(I)
        self.Kd = np.array(D)
        self.last_error = 0
        self.integrator = 0
        self.timeOfLastCall = None
        self.setPoint = np.array(target)
        self.integrator_max = float('inf')

    def update(self, current_value):
        '''Updates the PID controller.
        Args:
            current_value (double): vector/number of same legth as the target given in the constructor
        Returns:
            controll signal (double): vector of same length as the target
        '''
        current_value = np.array(current_value)
        if (np.size(current_value) != np.size(self.setPoint)):
            raise TypeError('current_value and target do not have the same shape')
        if (self.timeOfLastCall is None):
            # the PID was called for the first time. we don't know the deltaT yet
            # no controll signal is applied
            self.timeOfLastCall = time.perf_counter()
            return np.zeros(np.size(current_value))
        error = self.setPoint - current_value#计算误差
        P = error
        currentTime = time.perf_counter()
        deltaT = (currentTime - self.timeOfLastCall)
        # integral of the error is current error * time since last update  计算I
        self.integrator = self.integrator + (error * deltaT)
        I = self.integrator
        # derivative is difference in error / time since last update 计算P
        D = (error - self.last_error) / deltaT
        self.last_error = error
        self.timeOfLastCall = currentTime
        # return controll signal 计算输出
        return self.Kp * P + self.Ki * I + self.Kd * D


def main():
    rclpy.init()
    mono_tracker = mono_Tracker("monoIdentify")
    try:
        rclpy.spin(mono_tracker)
    except KeyboardInterrupt:
        pass
    finally:
        mono_tracker.destroy_node()
        rclpy.shutdown()
    
    

关键功能:

  • 支持多种跟踪算法(KCF/BOOSTING/MIL)

  • 颜色跟踪模式可自动提取HSV范围

  • 多线程控制确保流畅性

  • 完善的异常处理机制

  • 实时显示处理帧率

这个系统可以实现对运动目标或特定颜色物体的自动跟踪,通过PID算法保持目标在画面中心位置,典型应用于智能监控、机器人视觉跟随等场景。这个做上一篇的颜色追踪类似:亚博microros小车-原生ubuntu支持系列:21 颜色追踪-CSDN博客

都是根据目标的中心坐标和来计算s1、s2舵机转动角度,然后发布给底盘。

程序说明

程序启动后,通过鼠标选中需要跟踪的物体,按下空格键,小车的云台舵机进入跟踪模式。小车云台会跟随 被跟踪的物体移动,并且时刻保证被追踪的物体保持在画面中心。

测试

启动小车代理

 sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4

启动图像代理

docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 9999 -v4

(选做)调整舵机

ros2 run yahboom_esp32_mediapipe control_servo

启动脚本

ros2 run yahboom_esp32ai_car mono_Tracker

启动之后,进入选择模式,用鼠标选中目标所在位置,如下图所示,松开即开始识别。

把我的镇宅之宝小黄鸭拿出来了

键盘按键控制:

【r】:选择模式,可用鼠标选择要识别目标的区域,如上图。

【q】:退出程序。

【空格键】:目标追踪;在跟随的时候缓慢移动目标即可,移动太快将会丢失目标。

按下空格能看到通过pid算出来的运动角度。

ohu@bohu-TM1701:~/yahboomcar/yahboomcar_ws$ ros2 run yahboom_esp32ai_car mono_Tracker 
OpenCV Version:  4.11.0
servo1 0.0
servo1 1.6740220783505821
servo1 2.981003373069086
servo1 4.277003373069086
servo1 5.418249937784921
servo1 6.018073510048205
servo1 6.0159973543603105
servo1 5.71860954302583
servo1 4.775629931904761
servo1 3.8326030635678214
servo1 2.9206030635678215
servo1 1.9081850712547614
servo1 0.7822878210318385
servo1 0.18899249274645924
servo1 -0.2834846440358629
servo1 -0.7540859436953311
servo1 -1.234085943695331
servo1 -1.6484508720535367
servo1 -2.1135512406099104
servo1 -2.5695512406099104
servo1 -3.058080514019669
servo1 -3.538080514019669
servo1 -4.171699309150052
servo1 -4.530007470444837
servo1 -4.800294859267008
servo1 -4.8453324923276115
servo1 -4.865291304517047
servo1 -4.94373365090143
servo1 -5.136952220684027
servo1 -5.469228000644295
servo1 -6.027853281852513
servo1 -6.710800306564447
servo1 -7.6552821486406
servo1 -8.052589780593427
servo1 -9.223112314977138
servo1 -10.319161974550278
servo1 -11.591078854236214
servo1 -12.416221902691895
servo1 -13.360740214236708
servo1 -14.51497408279646
servo1 -14.780085181765932
servo1 -14.310165362425591
servo1 -14.15717444041632
servo1 -14.435688173088373
servo1 -15.32025424018754
servo1 -16.531503721252605
servo1 -17.836778372955706
servo1 -19.017197794387748
servo1 -20.28310463824062
servo1 -21.166754300006183
servo1 -21.242287643352327
servo1 -21.1565011124945
servo1 -21.707825159200315
servo1 -23.013047473734893
servo1 -24.58221911876973
servo1 -26.81213675078672
servo1 -28.374622533573962
servo1 -29.871810297867736
servo1 -31.217257596323204
servo1 -32.31216336848393
servo1 -33.601930296065284
servo1 -34.03160970476731
2查看节点话题通讯图

可以通过rqt查看节点之间的话题通讯,

对比下颜色追踪的,

不足:

移动速度稍快一点就跟丢了。

以上

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

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

相关文章

低至3折,百度智能云千帆宣布全面支持DeepSeek-R1/V3调用

DeepSeek-R1和 DeepSeek-V3模型已在百度智能云千帆平台上架 。 出品|产业家 新年伊始&#xff0c;百度智能云又传来新动作 。 2月3日百度智能云宣布&#xff0c; DeepSeek-R1和 DeepSeek-V3模型已在百度智能云千帆平台上架&#xff0c;同步推出超低价格方案&#xff0c;并…

Deepseek技术浅析(四):专家选择与推理机制

DeepSeek 是一种基于**专家混合模型&#xff08;Mixture of Experts, MoE&#xff09;**的先进深度学习架构&#xff0c;旨在通过动态选择和组合多个专家网络&#xff08;Expert Networks&#xff09;来处理复杂的任务。其核心思想是根据输入数据的特征&#xff0c;动态激活最合…

go运算符

内置运算符 算术运算符关系运算符逻辑运算符位运算符赋值运算符 算术运算符 注意&#xff1a; &#xff08;自增&#xff09;和–&#xff08;自减&#xff09;在 Go 语言中是单独的语句&#xff0c;并不是运算符 package mainimport "fmt"func main() {fmt.Printl…

分享2款 .NET 开源且强大的翻译工具

前言 对于程序员而言永远都无法逃避和英文打交道&#xff0c;今天大姚给大家分享2款 .NET 开源、功能强大的翻译工具&#xff0c;希望可以帮助到有需要的同学。 STranslate STranslate是一款由WPF开源的、免费的&#xff08;MIT License&#xff09;、即开即用、即用即走的翻…

技术书籍写作与编辑沟通指南

引言 撰写技术书籍不仅仅是知识的输出过程&#xff0c;更是与编辑团队紧密合作的协同工作。优秀的技术书籍不仅依赖作者深厚的技术背景&#xff0c;还需要精准的表达、流畅的结构以及符合出版要求的编辑润色。因此&#xff0c;如何高效地与编辑沟通&#xff0c;确保书籍质量&a…

Linux中系统相关指令(一)

一、时间查看指令date 1.1时间显示的格式 1> 默认格式&#xff0c;直接输入&#xff1a; date 回车 会直接展示出来&#xff0c;如&#xff1a; 2> 常用格式&#xff1a;年-月-日 时&#xff1a;分&#xff1a;秒 这种格式更加贴近于我们的习惯&#xff0c;但需要…

C语言:深入了解指针3

1.回调函数是什么&#xff1f; 基本概念 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当这个指针被⽤来调⽤其所指向的函数 时&#xff0c;被调⽤的函数就是回调函数。回调函数不是由该函…

【Uniapp-Vue3】创建DB schema数据表结构

右键uniCloud文件下的database文件&#xff0c;点击“新建DB schema”&#xff0c;选择模板&#xff0c;修改文件名&#xff0c;点击“创建” 创建完成后会出现对应的文件&#xff0c;进入该文件进行配置 对文件中的必填选项&#xff0c;用户权限&#xff0c;字段进行配置 其…

Java基础进阶-水仙花数

/* 功能&#xff1a;求水仙花数&#xff0c;打印并统计总个数。 思路&#xff1a; 水仙花数是定义范围100-999&#xff0c;满足每个位上的数子的3次方相加和等于这个数 第一步&#xff1a;循环遍历数据范围 第二步&#xff1b;取出当前数字的个位&#xff0c;十位&#xff0c;百…

DDD - 领域事件_解耦微服务的关键

文章目录 Pre领域事件的核心概念领域事件的作用领域事件的识别领域事件的技术实现领域事件的运行机制案例领域事件驱动的优势 Pre DDD - 微服务设计与领域驱动设计实战(中)_ 解决微服务拆分难题 EDA - Spring Boot构建基于事件驱动的消息系统 领域事件的核心概念 领域事件&a…

MacBook Pro(M1芯片)Qt环境配置

MacBook Pro&#xff08;M1芯片&#xff09;Qt环境配置 1、准备 试图写一个跨平台的桌面应用&#xff0c;此时想到了使用Qt&#xff0c;于是开始了搭建开发环境&#xff5e; 在M1芯片的电脑上安装&#xff0c;使用brew工具比较方便 Apple Silicon&#xff08;ARM/M1&#xf…

简单本地部署deepseek(软件版)

Download Ollama on Windows 下载 下载安装 winr 输入 cmd 然后输入ollama -v&#xff0c;出现ollama版本&#xff0c;安装成功 deepseek-r1 选择1.5b 输入 cmd 下面代码 ollama run deepseek-r1:1.5b 删除deepseek的代码如下&#xff1a; ollama rm deepseek-r1:1.5b 使用…

Linux生成自签证书【Nginx】

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

Docker基础以及单体实战

Docker 一、Docker1.1 Docker组成1.2 Dcoker运行图1.3 名称空间Namepace 1.4 docker、Docker compose、kubermetes 二、Docker安装2.1 在线Docker安装2.2 使用官方通用安装脚本2.3 二进制安装Docker三、Docker基础命令3.1 启动类3.2 镜像类3.3 容器类3.4 网络类3.5 Docker comp…

MySQL表的CURD

目录 一、Create 1.1单行数据全列插入 1.2多行数据指定列插入 1.3插入否则更新 1.4替换 2.Retrieve 2.1 select列 2.1.1全列查询 2.1.2指定列查询 2.1.3查询字段为表达式 2.1.4为查询结果指定别名 2.1.5结果去重 2.2where条件 2.3结果排序 2.4筛选分页结果 三…

如何优化垃圾回收机制?

垃圾回收机制 掌握 GC 算法之前&#xff0c;我们需要先弄清楚 3 个问题。第一&#xff0c;回收发生在哪里&#xff1f;第二&#xff0c;对象在 什么时候可以被回收&#xff1f;第三&#xff0c;如何回收这些对象&#xff1f; 回收发生在哪里&#xff1f; JVM 的内存区域中&…

基于SpringBoot的体检预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

PostgreSQL / PostGIS:创建地理要素

PostGIS详细教程可以参考官方文档&#xff1a;https://postgis.net/workshops/zh_Hans/postgis-intro/&#xff0c;并且官方文档提供了练习数据、教程、PPT版本教程。我这里参考QGIS文档中关于PostGIS的教程进行学习。 PostGIS 可以被认为是一组数据库内函数的集合&#xff0c…

embeddingbag词袋

文章目录 1. embeddingbag2. pytorch 1. embeddingbag 词袋embeddingbag 是在embedding词表的基础上演变起来的,nn.embedding的作用是构建一个词表&#xff0c;通过输入index序号来索引词对应的词向量&#xff0c;是可以根据词索引index进行forward计算的&#xff0c;embeddin…

分享|通过Self-Instruct框架将语言模型与自生成指令对齐

结论 在大型 “指令调整” 语言模型依赖的人类编写指令数据存在数量、多样性和创造性局限&#xff0c; 从而阻碍模型通用性的背景下&#xff0c; Self - Instruct 框架&#xff0c; 通过 自动生成 并 筛选指令数据 微调预训练语言模型&#xff0c; 有效提升了其指令遵循能…