RV1103调用摄像头运行yolov5进行实时检测

news2024/11/16 3:35:07

目录

    • 前言
    • 运行Yolov5模型
      • 第一步:修改CMA_SIZE
      • 第二步:修改yolov5项目代码
      • 第三步:运行程序

前言

买了luckfox picorv1103开发板,摄像头是SC3336 3MP Camera (A)摄像头,参考RV1103 Luckfox Pico使用SPI NAND Flash烧录镜像焊了nand flash,烧录的buildroot系统。
在这里插入图片描述在这里插入图片描述

官网中有一些调用摄像头进行检测的实例:RKMPI-example,其中retinaface的两个例子luckfox_pico_rtsp_retinaface和luckfox_pico_rtsp_retinaface_osd均在开发板上能跑起来会有人脸的识别结果打印出来,但是rtsp推流时会显示下方的问题,在局域网下的 PC 使用 VLC 软件打开网络串流rtsp://172.32.0.93/live/0并不能获取图像,后续再看啥问题。
在这里插入图片描述

运行Yolov5模型

以官网实例中的luckfox_pico_rtsp_yolov5为基础,实现在rv1103上调用摄像头进行实时检测。

受内存限制,luckfox pico开发板是无法运行该yolov5例子的。
官网上实现的是RKNN推理图像rtsp推流实例,并且为了最大化提高rtsp推流的帧率,实例使用VI组件来实现摄像头图像捕获。在RKNN推理结果的标注上,采用两种方式来实现:

1)将标注好的图像上传到 VENC 组件进行编码传输
2)在图像上传到 VENC 组件后再使用 RGN 模块以打 OSD 的形式标注结果

其中yolov5例子采用的是第1种方法,工作流程为:
在这里插入图片描述
要在rv1103上跑起来yolov5需要将rtsp推流部分去掉,直接以输出打印的方式查看yolov5检测结果,从该流程中可以知道需要将VENC组件和rtsp部分去掉,像下面图中所示,直接VI输入VPSS然后输入rknn,其余都删除。
在这里插入图片描述
具体操作如下:

第一步:修改CMA_SIZE

rknn和摄像头部分都有用到CMA内存,系统烧录时默认的是24M,不太够,需要增加到30M。参考RV1103 Luckfox Pico使用SPI NAND Flash烧录镜像,在第2)步中的BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Pro-IPC.mk中需要调整这句代码:export RK_BOOTARGS_CMA_SIZE="30M",其他都一样的流程进行烧录。
adb连接上开发板后,可使用下面命令查看CMA的大小是否正确

[root@luckfox ]# grep -i cma /proc/meminfo
CmaTotal:          30720 kB
CmaAllocated:         12 kB
CmaReleased:       30708 kB
CmaFree:               0 kB

第二步:修改yolov5项目代码

源码:https://github.com/luckfox-eng29/luckfox_pico_rtsp_yolov5
很简单,将main.cc代码中与VENCrstp两部分的代码注释掉就行,注释完后代码为:

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <time.h>
#include <unistd.h>
#include <vector>

#include "rtsp_demo.h"
#include "luckfox_mpi.h"
#include "yolov5.h"

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

// disp size
int width    = 720;
int height   = 480;

// model size
int model_width = 640;
int model_height = 640;	
float scale ;
int leftPadding ;
int topPadding  ;

bool quit = false;
static void sigterm_handler(int sig) {
	fprintf(stderr, "signal %d\n", sig);
	quit = true;
}

cv::Mat letterbox(cv::Mat input)
{
	float scaleX = (float)model_width  / (float)width; //0.888
	float scaleY = (float)model_height / (float)height; //1.125	
	scale = scaleX < scaleY ? scaleX : scaleY;
	
	int inputWidth   = (int)((float)width * scale);
	int inputHeight  = (int)((float)height * scale);

	leftPadding = (model_width  - inputWidth) / 2;
	topPadding  = (model_height - inputHeight) / 2;	
	

	cv::Mat inputScale;
    cv::resize(input, inputScale, cv::Size(inputWidth,inputHeight), 0, 0, cv::INTER_LINEAR);	
	cv::Mat letterboxImage(640, 640, CV_8UC3,cv::Scalar(0, 0, 0));
    cv::Rect roi(leftPadding, topPadding, inputWidth, inputHeight);
    inputScale.copyTo(letterboxImage(roi));

	return letterboxImage; 	
}

void mapCoordinates(int *x, int *y) {	
	int mx = *x - leftPadding;
	int my = *y - topPadding;

    *x = (int)((float)mx / scale);
    *y = (int)((float)my / scale);
}


int main(int argc, char *argv[]) {
	RK_S32 s32Ret = 0; 
	int sX,sY,eX,eY; 
	
	// Ctrl-c quit
	signal(SIGINT, sigterm_handler);
		
	// Rknn model
	char text[16];
	rknn_app_context_t rknn_app_ctx;	
	object_detect_result_list od_results;
    int ret;
	const char *model_path = "./model/yolov5.rknn";
    memset(&rknn_app_ctx, 0, sizeof(rknn_app_context_t));	
	init_yolov5_model(model_path, &rknn_app_ctx);
	printf("init rknn model success!\n");
	init_post_process();

	//h264_frame	
	// VENC_STREAM_S stFrame;	
	// stFrame.pstPack = (VENC_PACK_S *)malloc(sizeof(VENC_PACK_S));
 	// VIDEO_FRAME_INFO_S h264_frame;
 	VIDEO_FRAME_INFO_S stVpssFrame;

	// rkaiq init
	RK_BOOL multi_sensor = RK_FALSE;	
	const char *iq_dir = "/etc/iqfiles";
	rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
	//hdr_mode = RK_AIQ_WORKING_MODE_ISP_HDR2;
	SAMPLE_COMM_ISP_Init(0, hdr_mode, multi_sensor, iq_dir);
	SAMPLE_COMM_ISP_Run(0);

	// rkmpi init
	if (RK_MPI_SYS_Init() != RK_SUCCESS) {
		RK_LOGE("rk mpi sys init fail!");
		return -1;
	}

	// rtsp init	
	// rtsp_demo_handle g_rtsplive = NULL;
	// rtsp_session_handle g_rtsp_session;
	// g_rtsplive = create_rtsp_demo(554);
	// g_rtsp_session = rtsp_new_session(g_rtsplive, "/live/0");
	// rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
	// rtsp_sync_video_ts(g_rtsp_session, rtsp_get_reltime(), rtsp_get_ntptime());
	
	// vi init
	vi_dev_init();
	vi_chn_init(0, width, height);

	// vpss init
	vpss_init(0, width, height);

	// bind vi to vpss
	MPP_CHN_S stSrcChn, stvpssChn;
	stSrcChn.enModId = RK_ID_VI;
	stSrcChn.s32DevId = 0;
	stSrcChn.s32ChnId = 0;

	stvpssChn.enModId = RK_ID_VPSS;
	stvpssChn.s32DevId = 0;
	stvpssChn.s32ChnId = 0;
	printf("====RK_MPI_SYS_Bind vi0 to vpss0====\n");
	s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stvpssChn);
	if (s32Ret != RK_SUCCESS) {
		RK_LOGE("bind 0 ch venc failed");
		return -1;
	}

	// venc init
	// RK_CODEC_ID_E enCodecType = RK_VIDEO_ID_AVC;
	// venc_init(0, width, height, enCodecType);

	// printf("venc init success\n");	
	
  while(!quit)
	{	
		// get vpss frame
		s32Ret = RK_MPI_VPSS_GetChnFrame(0,0, &stVpssFrame,-1);
		if(s32Ret == RK_SUCCESS)
		{
			void *data = RK_MPI_MB_Handle2VirAddr(stVpssFrame.stVFrame.pMbBlk);	
			//opencv	
			cv::Mat frame(height,width,CV_8UC3,data);			
			//cv::Mat frame640;
        	//cv::resize(frame, frame640, cv::Size(640,640), 0, 0, cv::INTER_LINEAR);	
			//letterbox
			cv::Mat letterboxImage = letterbox(frame);	
			memcpy(rknn_app_ctx.input_mems[0]->virt_addr, letterboxImage.data, model_width*model_height*3);		
			inference_yolov5_model(&rknn_app_ctx, &od_results);

			for(int i = 0; i < od_results.count; i++)
			{					
				//获取框的四个坐标 
				if(od_results.count >= 1)
				{
					object_detect_result *det_result = &(od_results.results[i]);
					printf("%s @ (%d %d %d %d) %.3f\n", coco_cls_to_name(det_result->cls_id),
							 det_result->box.left, det_result->box.top,
							 det_result->box.right, det_result->box.bottom,
							 det_result->prop);
	
					sX = (int)(det_result->box.left   );	
					sY = (int)(det_result->box.top 	  );	
					eX = (int)(det_result->box.right  );	
					eY = (int)(det_result->box.bottom );
					mapCoordinates(&sX,&sY);
					mapCoordinates(&eX,&eY);

					cv::rectangle(frame,cv::Point(sX ,sY),
								        cv::Point(eX ,eY),
										cv::Scalar(0,255,0),3);
					sprintf(text, "%s %.1f%%", coco_cls_to_name(det_result->cls_id), det_result->prop * 100);
					cv::putText(frame,text,cv::Point(sX, sY - 8),
												 cv::FONT_HERSHEY_SIMPLEX,1,
												 cv::Scalar(0,255,0),2);
				}
			}

			memcpy(data, frame.data, width * height * 3);					
		}
		
		// send stream
		// encode H264
		// RK_MPI_VENC_SendFrame(0, &stVpssFrame,-1);
		// rtsp
		// s32Ret = RK_MPI_VENC_GetStream(0, &stFrame, -1);
		// if(s32Ret == RK_SUCCESS)
		// {
		// 	if(g_rtsplive && g_rtsp_session)
		// 	{
		// 		//printf("len = %d PTS = %d \n",stFrame.pstPack->u32Len, stFrame.pstPack->u64PTS);
				
		// 		void *pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
		// 		rtsp_tx_video(g_rtsp_session, (uint8_t *)pData, stFrame.pstPack->u32Len,
		// 					  stFrame.pstPack->u64PTS);
		// 		rtsp_do_event(g_rtsplive);
		// 	}
		// }

		// release frame 
		s32Ret = RK_MPI_VPSS_ReleaseChnFrame(0, 0, &stVpssFrame);
		if (s32Ret != RK_SUCCESS) {
			RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret);
		}
		// s32Ret = RK_MPI_VENC_ReleaseStream(0, &stFrame);
		// if (s32Ret != RK_SUCCESS) {
		// 	RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret);
		// }
		// memset(text,0,8);
	}



	printf("Release\n");
	RK_MPI_SYS_UnBind(&stSrcChn, &stvpssChn);
	
	RK_MPI_VI_DisableChn(0, 0);
	RK_MPI_VI_DisableDev(0);
	
	RK_MPI_VPSS_StopGrp(0);
	RK_MPI_VPSS_DestroyGrp(0);
	
	// RK_MPI_VENC_StopRecvFrame(0);
	// RK_MPI_VENC_DestroyChn(0);

	// free(stFrame.pstPack);

	// if (g_rtsplive)
	// 	rtsp_del_demo(g_rtsplive);
	SAMPLE_COMM_ISP_Stop(0);

	RK_MPI_SYS_Exit();

	// Release rknn model
    release_yolov5_model(&rknn_app_ctx);		
	deinit_post_process();
	
	return 0;
}

前提需要下载luckfox pico的sdk:https://github.com/LuckfoxTECH/luckfox-pico或者https://gitee.com/LuckfoxTECH/luckfox-pico,编译脚本:

export LUCKFOX_SDK_PATH=< 你的 Luckfox-pico SDK 路径>
cd /home/cw/zhouying/RV1103/luckfox_pico_rtsp_yolov5/
mkdir build
cd build
cmake ..
make && make install
# 在确定能adb连接开发板后将程序push进开发板
adb push ../luckfox_rtsp_yolov5_demo/ /

第三步:运行程序

adb shell连接开发板
top或者ps输出自启动的程序有哪些,需要kill掉一些程序释放出内存才能跑起来yolov5

[root@luckfox ]# top
Mem: 26820K used, 920K free, 228K shrd, 0K buff, 1604K cached
CPU:  17% usr  79% sys   0% nic   2% idle   0% io   0% irq   0% sirq
Load average: 11.21 3.00 1.02 2/106 426
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
  251     1 root     S    92616 334%  51% rkipc -a /oem/usr/share/iqfiles
  401   399 root     D    31148 112%   8% smbd -D
  425   420 root     R     1796   6%   8% top
   36     2 root     SW       0   0%   8% [kswapd0]
  424   423 root     S     1800   6%   5% {default.script} /bin/sh /usr/share/ud
  190     2 root     SW       0   0%   5% [vcodec_thread_0]
  193     1 root     S     5368  19%   3% /usr/sbin/ntpd -g -p /var/run/ntpd.pid
  355     1 root     S    14392  52%   0% /usr/bin/adbd
  314     1 root     S     4852  17%   0% sshd: /usr/sbin/sshd [listener] 0 of 1
  420   355 root     S     1804   6%   0% /bin/sh -l
   65     1 root     S     1800   6%   0% {rcS} /bin/sh /etc/init.d/rcS
    1     0 root     S     1796   6%   0% init
  423   251 root     S     1792   6%   0% udhcpc -i usb0 -T 1 -A 0 -b -q
  399    65 root     S     1792   6%   0% {S91smb} /bin/sh /etc/init.d/S91smb st
   71     1 root     S     1788   6%   0% /sbin/syslogd -n
  320     1 root     S     1788   6%   0% /usr/sbin/telnetd -F
   75     1 root     S     1784   6%   0% /sbin/klogd -n
   86     1 root     S     1628   6%   0% /sbin/udevd -d
  426   424 root     D     1012   4%   0% /sbin/ifconfig usb0 up
   41     2 root     IW       0   0%   0% [kworker/u2:1-fl]
[root@luckfox ]# killall rkipc
[root@luckfox ]# killall smbd
[root@luckfox ]# killall sshd
[root@luckfox ]# killall ntpd
[root@luckfox ]# killall udhcpc
[root@luckfox ]# killall nmbd

然后就能运行程序了

[root@luckfox ]# cd luckfox_rtsp_yolov5_demo/
[root@luckfox luckfox_rtsp_yolov5_demo]# ./luckfox_rtsp_yolov5 
  index=0, name=images, n_dims=4, dims=[1, 640, 640, 3], n_elems=1228800, size=1228800, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003922
  index=0, name=output0, n_dims=4, dims=[1, 80, 80, 255], n_elems=1632000, size=1632000, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003922
  index=1, name=286, n_dims=4, dims=[1, 40, 40, 255], n_elems=408000, size=408000, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003922
  index=2, name=288, n_dims=4, dims=[1, 20, 20, 255], n_elems=102000, size=102000, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003922
model is NHWC input fmt
model input height=640, width=640, channel=3
init rknn model success!
load lable ./model/coco_80_labels_list.txt
rkaiq log level ff0
ID: 0, sensor_name is m00_b_sc3336 4-0030, iqfiles is /etc/iqfiles
rk_aiq_uapi2_sysctl_init/prepare succeed
rk_aiq_uapi2_sysctl_start succeed
rockit log path (null), log_size = 0, can use export rt_log_path=, export rt_log_size= change
log_file = (nil) 
RTVersion        00:02:18-532 {dump              :064} ---------------------------------------------------------
RTVersion        00:02:18-534 {dump              :065} rockit version: git-8cb4d25b8 Tue Feb 28 11:12:39 2023 +0800
RTVersion        00:02:18-534 {dump              :066} rockit building: built- 2023-02-28 15:23:19
RTVersion        00:02:18-535 {dump              :067} ---------------------------------------------------------
(null)           00:02:18-535 {log_level_init    :203} 

 please use echo name=level > /tmp/rt_log_level set log level 
        name: all cmpi mb sys vdec venc rgn vpss vgs tde avs wbc vo vi ai ao aenc adec
        log_level: 0 1 2 3 4 5 6 

rockit default level 4, can use export rt_log_level=x, x=0,1,2,3,4,5,6 change
(null)           00:02:18-536 {read_log_level    :093} text is all=4
(null)           00:02:18-536 {read_log_level    :095} module is all, log_level is 4
(null)           00:02:18-541 {monitor_log_level :144} #Start monitor_log_level thread, arg:(nil)
RTIsp3x          00:02:18-567 {ispInitDevice     :208} sensor name = m00_b_sc3336 4-0030
RTIsp3x          00:02:18-567 {ispInitDevice     :211} sensor_index = 0
RTIsp3x          00:02:18-573 {ispInitDevice     :208} sensor name = m00_b_sc3336 4-0030
RTIsp3x          00:02:18-573 {ispInitDevice     :211} sensor_index = 0
vi_dev_init
RKViDev          00:02:18-587 {vi_set_dev_attr   :440} VI_DEV_ATTR_S all parameter reserved
  === VI ATTRS INFO: ===  
        devId  :      0
        chnId  :      0
        buffcnt:      0
        buffSize:     0
        width:        0
        height:       0
        Maxwidth:     0
        Maxwidth:     0
        streaming:    0
RKViChn          00:02:18-593 {prepareRuntime    :334} ---------------------------------------------------------
RKViChn          00:02:18-593 {prepareRuntime    :336} vi version: 1.86, name:vvi
RKViChn          00:02:18-594 {prepareRuntime    :337} rockit-ko version: vmpi:fb2eed2be49e
RKViChn          00:02:18-594 {prepareRuntime    :338} rockit-ko building: -2023-02-09-11:04:49
RKViChn          00:02:18-594 {prepareRuntime    :339} ---------------------------------------------------------
RKViChn          00:02:18-600 {prepareRuntime    :358} mb pool create success, MBCnt= 2
cmpi             00:02:18-601 {createRuntime     :546} [non-WRAP MODE]: buff size = 518400
RTIsp3x          00:02:18-607 {ispInitDevice     :208} sensor name = m00_b_sc3336 4-0030
RTIsp3x          00:02:18-607 {ispInitDevice     :211} sensor_index = 0
RTDeviceV4L2     00:02:18-611 {open              :138} open video name(/dev/video11)
RKViChn          00:02:18-612 {setFrameRate      :1153} [vi] dev(0) ch(0) illegal param s32SrcFrameRate(0) s32DstFrameRate(0)
RTDeviceV4L2     00:02:18-614 {ispCameraInfo     :549} current device:/dev/video11 isn't compatible(cap:0x84201000) device,memoryType:4, retry:0
RTDeviceV4L2     00:02:18-615 {ispInitFormat     :726} ioctl VIDIOC_S_FMT OK
RKViChn          00:02:18-616 {start             :813} =========== vi Start startRuntime ===========
RTDeviceV4L2     00:02:18-616 {ispStreamOn       :440} do ispStreamOn start
RTDeviceV4L2     00:02:18-638 {ispStreamOn       :493} do ispStreamOn done
vpss_init
=== 0 ===
=== 1 ===
rga_api version 1.10.0_[2]
====RK_MPI_SYS_Bind vi0 to vpss0====
cmpi             00:02:18-721 {mb_get_buffer_by_i:422} allocated buffer(this=0x2e78b0, data=(nil), size=0, id=-1)
traffic light @ (27 239 81 297) 0.266
person @ (185 285 488 532) 0.465
laptop @ (533 380 619 500) 0.465
person @ (120 234 356 501) 0.294
laptop @ (464 344 535 430) 0.286
person @ (206 272 506 528) 0.424
person @ (577 297 640 513) 0.251
person @ (215 285 535 527) 0.592
person @ (190 291 427 523) 0.441
laptop @ (529 385 592 455) 0.364
person @ (190 294 423 522) 0.599
bottle @ (524 380 585 456) 0.263
person @ (229 351 445 529) 0.421
^Csignal 2
Release
RTDeviceV4L2     00:02:25-737 {ispStreamOff      :503} do ispStreamOff start
RTDeviceV4L2     00:02:25-802 {ispStreamOff      :514} do ispStreamOff done
RTDeviceV4L2     00:02:25-803 {close             :365} do RTDeviceV4L2 close
rk_aiq_uapi2_sysctl_stop enter
rk_aiq_uapi2_sysctl_deinit enter
MessageParser process loop exit!
rk_aiq_uapi2_sysctl_deinit exit
RKSockServer     00:02:26-568 {start             :162} accept failed
Release success

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库备份与恢复和日志管理

一、数据库备份的概述 1、数据库备份的目的&#xff1a;备灾。在生产环境中&#xff0c;数据的安全性非常重要 2、造成数据丢失的原因&#xff1a;程序出错、人为的问题、磁盘故障、自然灾害。 二、备份的分类 从物理和逻辑的角度 1、物理备份&#xff1a; 对数据库操作系…

可视掏耳勺安全吗?独家揭示六大风险弊病!

很多人习惯在洗漱完顺手拿一根棉签掏耳朵&#xff0c;但是棉签的表面直径大且粗糙&#xff0c;不易将耳朵深处的耳垢挖出&#xff0c;耳垢堆积在耳道深处长时间不清理会导致堵塞耳道&#xff0c;引起耳鸣甚至感染。而可视掏耳勺作为一种新型的挖耳工具&#xff0c;它的安全性也…

OpenAI突然上线两件“杀手锏”:势在维持大模型霸主地位

在最近的大模型战争中&#xff0c;OpenAI似乎很难维持霸主地位。虽然没有具体的数据统计&#xff0c;但Claude3.5出现后&#xff0c;只是看网友们的反响&#xff0c;就能感觉到OpenAI订阅用户的流失&#xff1a;既然Claude3.5比GPT-4o好用&#xff0c;为什么我们不去订阅Claude…

html+css 实现遮罩按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…

mybatis-plus批量插入优化

mybatis-plus批量插入优化 背景优化新的问题分批插入springboot3整合mybaits-plus 背景 使用的mybatisplus的批量插入方法&#xff1a;saveBatch()&#xff0c;打印 sql 日志发现&#xff0c;底层还是一条条的 insert 语句&#xff0c;这显然是不行的 优化 之前就看到过网上都…

怎么把C盘分成两个盘?让C盘分区更简单,赶快试试!

在日常使用电脑的过程中&#xff0c;有时我们可能希望将C盘分割成两个独立的分区&#xff0c;以便更好地管理文件和数据。这种操作需要谨慎进行&#xff0c;因为错误的分区操作可能导致数据丢失。那么&#xff0c;我们该怎么把C盘分成两个盘呢&#xff1f;下面&#xff0c;我将…

Telegraf 命令行指南:高效监控数据的秘诀

Telegraf 是一个轻量级的服务器监控代理&#xff0c;它支持从数百种数据源收集、处理和发送数据到各种存储库。它由 InfluxData 开发&#xff0c;常用于时间序列数据库 InfluxDB。Telegraf 的灵活性和强大的插件系统使其成为监控基础设施的理想选择。本文将为您提供一个 Telegr…

【解决方案】华普微基于收发芯片系列的LED智能灯控高效解决方案

一、方案概述 LED智能灯是一种集LED照明技术与智能控制技术于一体的现代照明产品。它采用高效节能的LED作为光源&#xff0c;相比传统灯具&#xff0c;具有更低的能耗、更长的使用寿命以及更环保的特性。 智能灯通过内置的智能芯片或连接外部智能设备&#xff08;如智能手机、…

vue2-级联选择器

级联选择器 一、市面上的级联选择器二、功能实现1、数据类型2、隐藏下拉框的方法3、html结构4、CSS代码5、各个方法代码 三、实现样式截图1、一级菜单1、鼠标放到一级菜单&#xff0c;就显示二级菜单2、鼠标点击一级菜单的时候 2、二级菜单1、鼠标放到二级菜单的时候&#xff0…

合规征程新里程碑:ATFX荣获香港SFC牌照,运营再上新台阶

全球知名金融科技品牌ATFX又传来好消息&#xff0c;继2023年6月获得阿联酋SCA第五类牌照后&#xff0c;ATFX全球合规运营策略再次取得重大成功。日前&#xff0c;ATFX宣布获得中国香港证券及期货事务监察委员会&#xff08;SFC&#xff09;颁发的第三类牌照&#xff08;号码&am…

GAMES104:06(下)游戏中地形大气和云的渲染2-学习笔记

文章目录 三、大气Atmosphere3.1 大气散射理论3.1.1 Analytic Atmosphere Appearance Modeling&#xff08;经验模型&#xff09;3.1.2 Participating Media参与介质3.1.3 辐射传递方程RTE(Radiative Transfer Equation)3.1.4 体积渲染公式VRE(Volume Rendering Equation) 3.2 …

比原生Transformer快的LMDeploy

创建conda环境 conda create lmdeploy conda activate lmdeploy 安装依赖包(注&#xff1a;下对应的版本要不然容易报错) pip install pytorch2.1.2 pip install lmdeploy[all]0.3.0 下载模型 通过Git协议下载模型。首先安装git-lfs组件 此处使用的root权限 curl -s ht…

YOLOv8改进 | 主干网络 | 简单而优雅且有效的VanillaNet 【华为诺亚方舟】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

【C++核心篇】—— C++面向对象编程:封装相关语法使用和注意事项详解(全网最详细!!!)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、封装&#xff08;类&#xff09;1.封装的使用&#xff08;类和对象&#xff09;2. 对象的初始化和清理2.1 构造函数2.2 析构函数2.3 构造函数的分类及调用 …

海外仓代理模式,借鸡生蛋也能成为跨境新出路

国际物流是跨境电商生态圈同质化最严重跨境电商最开放的“地带”。唯独海外仓&#xff0c;算是国际物流行业唯一的一块“世外桃源”&#xff0c;但一个1000平米的小仓库&#xff0c;每年至少要花费100万的运转资金&#xff0c;无论是新企业还是成熟的企业&#xff0c;建立海外仓…

成都云飞浩容文化传媒有限公司怎么样?靠谱吗?

在数字经济的浪潮中&#xff0c;电商行业如同一艘巨轮&#xff0c;乘风破浪&#xff0c;不断前行。而在这片波澜壮阔的蓝海中&#xff0c;成都云飞浩容文化传媒有限公司犹如一颗璀璨的新星&#xff0c;以其专业的电商服务能力和前瞻性的市场洞察&#xff0c;为众多品牌搭建起通…

【Python机器学习】支持向量机——基于最大间隔分隔数据

有些人认为&#xff0c;SVM是最好的现成的分类器&#xff0c;这里说的“现成”指的是分类器不加修改即可直接使用。同时&#xff0c;这就意味着在数据上应用基本形式的SVM分类器就可以得到低错误率的结果。SVM能够对训练集之外的数据点做出很好的分类决策。 支持向量机&#x…

SAP ABAP SUBMIT 用法详解(看这一篇就够了)

文章目录 前言一、案例介绍/笔者需求二、B报表&#xff08;被SUBMIT的程序&#xff09;三、A报表&#xff08;用SUBMIT的程序&#xff09; a.SUBMIT B程序 b.AND RETURN 详解 c.CL_SALV_BS_RUNTIME_INFO 捕获ALV数据的方法 d.捕获…

使用STM32实现一个线性代数计算器

文章目录 背景挑战与困难如何整合编译&#xff1f;error: non-ASM statement in naked function is not supportederror: #pragma import is an ARM Compiler 5 extension, and is not supported by ARM Compiler 6error: redefinition of __FILE 改造demo中的cout改造delete运…