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

亚博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 = boxself.isWorking = Truedef 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, p2else:# 跟踪失败# Tracking failedcv.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 CvBridgefrom 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 = Trueself.select_flags = Falseself.gTracker_state = Falseself.windows_name = 'frame'self.cols, self.rows = 0, 0 #鼠标选择区域坐标self.Mouse_XY = (0, 0) #鼠标点击坐标self.index = 2self.end = 0self.color = color_follow()self.tracker_types = ['BOOSTING', 'MIL', 'KCF']self.tracker_type = ['KCF'] self.VideoSwitch = Trueself.img_flip = Falseself.last_stamp = Noneself.new_seconds = 0self.fps_seconds = 1ser1_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 = 1000self.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_wifiself.bridge = CvBridge()self.sub_img = self.create_subscription(CompressedImage, '/espRos/esp32camera', self.handleTopic, 1) #获取esp32传来的图像def declare_param(self):#PIDself.declare_parameter("Kp",12)self.Kp = self.get_parameter('Kp').get_parameter_value().integer_valueself.declare_parameter("Ki",0)self.Ki = self.get_parameter('Ki').get_parameter_value().integer_valueself.declare_parameter("Kd",0.9)self.Kd = self.get_parameter('Kd').get_parameter_value().integer_valuedef get_param(self):self.Kd = self.get_parameter('Kd').get_parameter_value().integer_valueself.Ki = self.get_parameter('Ki').get_parameter_value().integer_valueself.Kp = self.get_parameter('Kp').get_parameter_value().integer_valueself.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).nanosecondsdelta = datetime.timedelta(seconds=total_secs * 1e-9)seconds = delta.total_seconds()*100if self.new_seconds != 0:self.fps_seconds = seconds - self.new_secondsself.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 = 0self.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_Pidself.target_servoy += y_Pidelse:self.target_servox -= x_Pidself.target_servoy += y_Pid#角度控制(保护舵机)    if self.target_servox >= 45:self.target_servox = 45elif self.target_servox <= -45:self.target_servox = -45if self.target_servoy >= 20:self.target_servoy = 20elif self.target_servoy <= -90:self.target_servoy = -90print("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 configdef 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 = Trueself.Mouse_XY = (x,y)if event == 4:#左键放开self.select_flags = Falseself.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 = Trueself.dyn_update = Trueelse: 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 = Falseif 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 = Falsergb_img, (targBegin_x, targBegin_y), (targEnd_x, targEnd_y) = self.gTracker.track(rgb_img)#执行追踪center_x = targEnd_x / 2 + targBegin_x / 2center_y = targEnd_y / 2 + targBegin_y / 2width = targEnd_x - targBegin_xhigh = targEnd_y - targBegin_yself.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, binaryclass simplePID:'''very simple discrete PID controller'''def __init__(self, target, P, I, D):'''Create a discrete PID controllereach of the parameters may be a vector if they have the same lengthArgs: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 = 0self.integrator = 0self.timeOfLastCall = Noneself.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 constructorReturns: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 appliedself.timeOfLastCall = time.perf_counter()return np.zeros(np.size(current_value))error = self.setPoint - current_value#计算误差P = errorcurrentTime = time.perf_counter()deltaT = (currentTime - self.timeOfLastCall)# integral of the error is current error * time since last update  计算Iself.integrator = self.integrator + (error * deltaT)I = self.integrator# derivative is difference in error / time since last update 计算PD = (error - self.last_error) / deltaTself.last_error = errorself.timeOfLastCall = currentTime# return controll signal 计算输出return self.Kp * P + self.Ki * I + self.Kd * Ddef main():rclpy.init()mono_tracker = mono_Tracker("monoIdentify")try:rclpy.spin(mono_tracker)except KeyboardInterrupt:passfinally: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查看节点之间的话题通讯,

对比下颜色追踪的,

不足:

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

以上

相关文章:

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

背景知识 跟上一个颜色追踪类似。也是基于opencv的&#xff0c;不过背后的算法有很多 BOOSTING&#xff1a;算法原理类似于Haar cascades (AdaBoost)&#xff0c;是一种很老的算法。这个算法速度慢并且不是很准。MIL&#xff1a;比BOOSTING准一点。KCF&#xff1a;速度比BOOST…...

JAVA异步的TCP 通讯-客户端

一、客户端代码示例 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.util.concurrent.ExecutorService; impo…...

python:递归函数与lambda函数

递归函数&#xff1a;1.函数内调用自己 2.有一个出口 1.递归 一.有出口时 def sum(num):if num1:return 1return numsum(num-1) asum(3) print(a) #num3 3sum(2) #num2 2sum(1) #num1是返回1 #即3sum(2&#xff09;即32sum(1)即321运行结果 6 二.无出口时 def sum(num)…...

G1相对于CMS的的优势

1.G1在压缩空间方面有优势。 2.G1通过将内存空间分成区域&#xff08;Region&#xff09;的方式避免内存碎片问题 3.Eden、Survivor、Old区不再固定&#xff0c;在内存使用率上来说更灵活 4.G1可以通过设置预期停顿时间&#xff08;Pause Time&#xff09;来控制垃圾收集时间…...

java进阶之并发编程一ReentrantLock的实际应用和线程中断EXAMPLE

引言:继上一篇ReentrantLock的介绍来做俩个小demo。 实现3个线程分别打印指定数字和线程死锁进行线程中断。 上一篇:<<java进阶之并发编程一ReentrantLock同步锁的学习和syncthronized的区别>> **demo1:**ReentrantLock搭配三个线程分别打印指定的数字,直接上代…...

消费kafka消息示例

以下是使用 Java 结合 Spring Kafka 框架来监听 updated-topic-test 这个 Kafka Topic 的详细实现步骤及代码示例&#xff0c;用于捕获人员信息变更的事件。 1. 添加依赖 在 pom.xml 文件中添加 Spring Kafka 相关依赖&#xff1a; <dependencies><!-- Spring Boot…...

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

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

SpringBoot+Dubbo+zookeeper 急速入门案例

项目目录结构&#xff1a; 第一步&#xff1a;创建一个SpringBoot项目&#xff0c;这里选择Maven项目或者Spring Initializer都可以&#xff0c;这里创建了一个Maven项目&#xff08;SpringBoot-Dubbo&#xff09;&#xff0c;pom.xml文件如下&#xff1a; <?xml versio…...

Java 面试之结束问答

技术优化 线程池优化 设置最大线程数设置最小核心线程数设置额外线程存活时间选择线程池队列选择合适的线程池选择合适的饱和策略 锁优化 尽量不要锁住方法缩小同步代码块&#xff0c;只锁数据锁中尽量不要再包含锁将锁私有化&#xff0c;在内部管理锁进行适当的锁分解 HT…...

[LeetCode] 二叉树 I — 深度优先遍历(前中后序遍历) | 广度优先遍历(层序遍历):递归法迭代法

二叉树 基础知识深度优先遍历递归法迭代法&#xff08;栈&#xff09;144# 二叉树的前序遍历94# 二叉树的中序遍历145# 二叉树的后序遍历 广度优先遍历递归法迭代法&#xff08;队列&#xff09;102# 二叉树的层序遍历107# 二叉树的层序遍历 II199# 二叉树的右视图637# 二叉树的…...

主动管理的基本概念

什么是主动管理&#xff1f; 主动管理&#xff0c;又称主动投资&#xff0c;是一种投资策略&#xff0c;投资组合经理进行特定投资的目的是超越投资基准指数。与被动管理不同&#xff0c;主动管理者依靠分析研究、预测以及自己的判断和经验来决定买入、持有和卖出哪些证券。“…...

Python aiortc API

本研究的主要目的是基于Python aiortc api实现抓取本地设备&#xff08;摄像机、麦克风&#xff09;媒体流实现Web端预览。本文章仅仅描述实现思路&#xff0c;索要源码请私信我。 demo-server解耦 原始代码解析 http服务器端 import argparse import asyncio import json…...

OpenCV4,快速入门,第二讲:图像色彩空间转换

文章目录 引言一、色彩空间概述1.1 RGB与HSV的区别1.2 HSV的详细含义cvtColor二、cvtColor函数详解2.1 函数原型2.2 参数说明2.3 使用示例三、imwrite函数详解3.1 函数原型3.2 参数说明3.3 使用示例四、完整示例代码五、应用场景与注意事项5.1 HSV的典型应用5.2 注意事项结语引…...

86.(2)攻防世界 WEB PHP2

之前做过&#xff0c;回顾一遍&#xff0c;详解见下面这篇博客 29.攻防世界PHP2-CSDN博客 既然是代码审计题目&#xff0c;打开后又不显示代码&#xff0c;肯定在文件里 <?php // 首先检查通过 GET 请求传递的名为 "id" 的参数值是否严格等于字符串 "admi…...

【Leetcode 每日一题】90. 子集 II

问题背景 给你一个整数数组 n u m s nums nums&#xff0c;其中可能包含重复元素&#xff0c;请你返回该数组所有可能的 子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。返回的解集中&#xff0c;子集可以按 任意顺序 排列。 数据约束 ● 1 ≤ n u m s . …...

RK3588——解决Linux系统触摸屏坐标方向相反问题

问题描述&#xff1a;触摸正常产生中断&#xff0c;但系统上报的触摸坐标不正确&#xff0c;是反向的坐标。 解决办法通过修改设备树添加属性翻转坐标。 注&#xff1a;需确认对应的驱动是否有解析该属性的具体内容&#xff0c;否则仍然无法生效。...

面对全球化的泼天流量,出海企业如何观测多地域网络质量?

作者&#xff1a;俞嵩、白玙 泼天富贵背后&#xff0c;技术挑战接踵而至 随着全球化进程&#xff0c;出海、全球化成为很多 Toc 产品的必经之路&#xff0c;保障不同地域、不同网络环境的一致的用户体验成为全球化应用的不得不面对的问题。在跨运营商、跨地域的网络环境中&am…...

YOLOv11实时目标检测 | 摄像头视频图片文件检测

在上篇文章中YOLO11环境部署 || 从检测到训练https://blog.csdn.net/2301_79442295/article/details/145414103#comments_36164492&#xff0c;我们详细探讨了YOLO11的部署以及推理训练&#xff0c;但是评论区的观众老爷就说了&#xff1a;“博主博主&#xff0c;你这个只能推理…...

PyQt6/PySide6 的 QPushButton 类

QPushButton 是 PyQt6 或 PySide6 库中用于创建按钮控件的类。按钮是用户界面中最常用的控件之一&#xff0c;用于触发特定的动作或事件。QPushButton 提供了丰富的功能和灵活性&#xff0c;使得开发者可以轻松地创建各种类型的按钮。下面我将详细介绍 QPushButton 的主要特性及…...

libdrm移植到arm设备

一、环境资源要求 下载libdrm Index of /libdrm 这边使用的是2.4.114版本&#xff0c;版本太高对meson版本要求也很高&#xff0c;为了省事用apt安装meson就不用太高版本了&#xff0c;1.x版本虽然使用makefile编译方便但是太老&#xff0c;对应用支持不太好。 https://dri…...

自定义序列化数据类型

目录 1. WritableComparable1.1 Writable1.2 Comparable1.3 IntWritable 2. 自定义序列化数据类型RectangleWritable3. 矩形面积计算3.1 Map3.2 Reduce 4. 代码和结果4.1 pom.xml中依赖配置4.2 工具类util4.3 矩形面积计算4.4 结果 参考 本文引用的Apache Hadoop源代码基于Apac…...

【Linux网络编程】:URL(encode),HTTP协议,telnet工具

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ Linux网络编程笔记&#xff1a; https://mp.csdn…...

C语言基础系列【3】VSCode使用

前面我们提到过VSCode有多么的好用&#xff0c;本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网&#xff08;https://code.visualstudio.com/&#xff09;下载安装包&#xff0c;点击Download for Windows 获取安装包后&#xff0c;一路点击Next就可以。 配…...

学前端框架之前,你需要先理解 MVC

MVC 软件架构设计模式鼎鼎大名&#xff0c;相信你已经听说过了&#xff0c;但你确定自己已经完全理解到 MVC 的精髓了吗&#xff1f; 如果你是新同学&#xff0c;没听过 MVC&#xff0c;那可以到网上搜一些文章来看看&#xff0c;不过你要有心理准备&#xff0c;那些文章大多都…...

Mysql:数据库

Mysql 一、数据库概念&#xff1f;二、MySQL架构三、SQL语句分类四、数据库操作4.1 数据库创建4.2 数据库字符集和校验规则4.3 数据库修改4.4 数据库删除4.4 数据库备份和恢复其他 五、表操作5.1 创建表5.2 修改表5.3 删除表 六、表的增删改查6.1 Create(创建):数据新增1&#…...

python的函数介绍

一.定义和调用函数 1.定义函数 在 Python 中&#xff0c;使用 def 关键字来定义一个函数。函数可以包含参数&#xff0c;也可以包含返回值 基本语法 def function_name(parameters):"""docstring"""# Function bodyreturn resultdef greet(n…...

要完成使用MLflow比较模型运行、选择模型并将其部署到REST API的教程

要完成使用MLflow比较模型运行、选择模型并将其部署到REST API的教程&#xff0c;请按照以下有序步骤操作&#xff1a; 设置环境 导出MLflow跟踪URI&#xff1a;设置环境变量以指向您的MLflow跟踪服务。export MLFLOW_TRACKING_URIyour-organizations-MLflow-server-url 加载数…...

Windows Docker笔记-简介摘录

Docker是一个开源的容器化平台&#xff0c;可以帮助开发人员将应用程序与其依赖项打包在一个独立的容器中&#xff0c;然后在任何安装的Docker的环境中快速、可靠地运行。 几个基本概念和优势&#xff1a; 容器&#xff1a;容器是一个轻量级、独立的运行环境&#xff0c;包含了…...

MVC 文件夹:架构之美与实际应用

MVC 文件夹:架构之美与实际应用 引言 MVC(Model-View-Controller)是一种设计模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种架构模式不仅提高了代码的可维护性和可扩展性,而且使得开发流程更加清晰。本文将深入探讨MVC文…...

AI透明化与全球政治格局的发展:如何避免AI被人为操控

在现代社会&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐渗透到我们的日常生活中&#xff0c;尤其是在社交平台和信息传播领域。虽然AI可以极大地推动社会发展&#xff0c;但也潜藏着被恶意操控的风险。最令人担忧的是&#xff0c;某些势力可能通过操控AI来操控公众…...