ARM Linux LCD上实时预览摄像头画面

文章目录

  • 1、前言
  • 2、环境介绍
  • 3、步骤
  • 4、应用程序编写
    • 4.1、lcd初始化
    • 4.2、摄像头初始化
    • 4.3、jpeg解码
    • 4.4、开启摄像头
    • 4.5、完整的程序如下
  • 5、测试
    • 5.1、编译应用程序
    • 5.2、运行应用程序
  • 6、总结

1、前言

本次应用程序主要针对支持MJPEG格式输出的UVC摄像头。

2、环境介绍

rk3566 + 7寸 mipi lcd + uvc摄像头

3、步骤

应用程序编写主要分为以下几个步骤:

1、lcd初始化。

2、摄像头初始化。

3、摄像头采集数据。

4、jpeg解码。

5、lcd显示。

4、应用程序编写

4.1、lcd初始化

typedef struct lcd_mes {int fd;unsigned char *fb_base;int lcd_width;int lcd_height;unsigned int bpp;unsigned int line_width;
} lcd_mes;int lcd_init(const char *fb_dev, lcd_mes *lcd)
{int screen_size;struct fb_var_screeninfo var;   if (fb_dev == NULL)goto _err;/* 1. open /dev/fb* */    lcd->fd = open(fb_dev, O_RDWR);if(lcd->fd < 0){printf("can not open %s\n", fb_dev);goto _err;}/* 2. get lcd message */if (ioctl(lcd->fd, FBIOGET_VSCREENINFO, &var)){printf("can not get var\n");goto _err;}screen_size = var.xres * var.yres * var.bits_per_pixel / 8;lcd->line_width  = var.xres * var.bits_per_pixel / 8;lcd->lcd_width = var.xres;lcd->lcd_height = var.yres;lcd->bpp = var.bits_per_pixel;lcd->fb_base = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->fd, 0);if (lcd->fb_base == (unsigned char *)-1){printf("can not mmap\n");goto _err;}memset(lcd->fb_base, 0x00, screen_size);return 0;_err:return -1;
}

4.2、摄像头初始化

使用v4l2接口初始化uvc摄像头:

typedef struct camera_mes {int fd;void *bufs[32];int bufs_index;int buf_length;char fmt[20];int frame_x_size;int frame_y_size;
} camera_mes;int camera_init(const char *video, camera_mes *camera)
{   struct v4l2_fmtdesc fmtdesc;struct v4l2_frmsizeenum fsenum;int fmt_index = 0;int frame_index = 0;int buf_cnt;int i;if (video == NULL)goto _err;/* 1. open /dev/video* */camera->fd = open(video, O_RDWR);if (camera->fd < 0){printf("can not open %s\n", video);goto _err;}/* 2. query capability */struct v4l2_capability cap;memset(&cap, 0, sizeof(struct v4l2_capability));if (0 == ioctl(camera->fd, VIDIOC_QUERYCAP, &cap)){        if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {fprintf(stderr, "Error opening device %s: video capture not supported.\n", video);goto _ioc_querycap_err;}if(!(cap.capabilities & V4L2_CAP_STREAMING)) {fprintf(stderr, "%s does not support streaming i/o\n", video);goto _ioc_querycap_err;}}else{printf("can not get capability\n");goto _ioc_querycap_err;}/* 3. enum formt */while (1){fmtdesc.index = fmt_index;  fmtdesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;  if (0 != ioctl(camera->fd, VIDIOC_ENUM_FMT, &fmtdesc))break;frame_index = 0;// printf("format %s,%d:\n", fmtdesc.description, fmtdesc.pixelformat);while (1){memset(&fsenum, 0, sizeof(struct v4l2_frmsizeenum));fsenum.pixel_format = fmtdesc.pixelformat;fsenum.index = frame_index;/* get framesize */if (ioctl(camera->fd, VIDIOC_ENUM_FRAMESIZES, &fsenum) == 0){// printf("\t%d: %d x %d\n", frame_index, fsenum.discrete.width, fsenum.discrete.height);}else{break;}frame_index++;}fmt_index++;}/* 4. set formt */struct v4l2_format fmt;memset(&fmt, 0, sizeof(struct v4l2_format));fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.width = camera->frame_x_size;fmt.fmt.pix.height = camera->frame_y_size;fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;fmt.fmt.pix.field = V4L2_FIELD_ANY;if (0 == ioctl(camera->fd, VIDIOC_S_FMT, &fmt)){// printf("the final frame-size has been set : %d x %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);camera->frame_x_size = fmt.fmt.pix.width;camera->frame_y_size = fmt.fmt.pix.height;strncpy(camera->fmt, "Motion-JPEG", strlen("Motion-JPEG"));}else{printf("can not set format\n");goto _ioc_sfmt_err;}/* 5. require buffer */struct v4l2_requestbuffers rb;memset(&rb, 0, sizeof(struct v4l2_requestbuffers));rb.count = 32;rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;rb.memory = V4L2_MEMORY_MMAP;if (0 == ioctl(camera->fd, VIDIOC_REQBUFS, &rb)){buf_cnt = rb.count;for(i = 0; i < rb.count; i++) {struct v4l2_buffer buf;memset(&buf, 0, sizeof(struct v4l2_buffer));buf.index = i;buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (0 == ioctl(camera->fd, VIDIOC_QUERYBUF, &buf)){/* mmap */camera->bufs[i] = mmap(0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, camera->fd, buf.m.offset);if(camera->bufs[i] == MAP_FAILED) {printf("Unable to map buffer");goto _err;}}else{printf("can not query buffer\n");goto _err;}            }}else{printf("can not request buffers\n");goto _ioc_reqbufs_err;}/* 6. queue buffer */for(i = 0; i < buf_cnt; ++i) {struct v4l2_buffer buf;memset(&buf, 0, sizeof(struct v4l2_buffer));buf.index = i;buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (0 != ioctl(camera->fd, VIDIOC_QBUF, &buf)){perror("Unable to queue buffer");goto _ioc_qbuf_err;}}camera->bufs_index = 0;     // init camera structcamera->buf_length = 0;return 0;_ioc_qbuf_err:
_ioc_reqbufs_err:
_ioc_sfmt_err:
_ioc_querycap_err:
_err:return -1;
}

4.3、jpeg解码

int jpeg_show_on_lcd(lcd_mes *lcd, camera_mes *camera)
{int min_width, min_height;int valid_bytes;int offset_x, offset_y;struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;cinfo.err = jpeg_std_error(&jerr);      // 错误处理对象与解码对象绑定jpeg_create_decompress(&cinfo);         // 初始化解码器jpeg_mem_src(&cinfo, camera->bufs[camera->bufs_index], camera->buf_length);   // 指定JPEG数据的来源jpeg_read_header(&cinfo, TRUE);         // 读取图像信息cinfo.out_color_space = JCS_RGB;        // 设置解码后的颜色空间为RGBjpeg_start_decompress(&cinfo);          // 开始解码unsigned char *jpeg_line_buf = (char *)malloc(cinfo.output_components * cinfo.output_width);    // 用于存储从JPEG解码器读取的一行数据unsigned int *fb_line_buf = (int *)malloc(lcd->line_width);                                     // 用于存储转换后的RGB数据,准备写入framebuffermin_width = (cinfo.output_width < lcd->lcd_width) ? cinfo.output_width : lcd->lcd_width;min_height = (cinfo.output_height < lcd->lcd_height) ? cinfo.output_height : lcd->lcd_height;valid_bytes = min_width * lcd->bpp / 8;             // 一行的有效字节数unsigned char *ptr = lcd->fb_base;offset_x = ((lcd->lcd_width - min_width) / 2) * lcd->bpp / 8;   // x方向居中offset_y = (lcd->lcd_height - min_height) / 2;      // y方向居中for (int i = 0; i < offset_y; i++)                  ptr += lcd->lcd_width * lcd->bpp / 8;unsigned int red, green, blue;unsigned int color;while (cinfo.output_scanline < min_height){jpeg_read_scanlines(&cinfo, &jpeg_line_buf, 1); // 每次读取一行for(int i = 0; i < min_width; i++)              {red = jpeg_line_buf[i * 3];                 green = jpeg_line_buf[i * 3 + 1];           blue = jpeg_line_buf[i * 3 + 2];            color = red << 16 | green << 8 | blue;      // RGB888转RGB8888fb_line_buf[i] = color;}memcpy(ptr + offset_x, fb_line_buf, valid_bytes);   // 将一行数据写入framebufferptr += lcd->lcd_width * lcd->bpp / 8;               // 移动到下一行}jpeg_finish_decompress(&cinfo);                     // 完成解码jpeg_destroy_decompress(&cinfo);                    // 销毁解码对象free(jpeg_line_buf);                                // 释放内存free(fb_line_buf);                                  // 释放内存return 0;
}

4.4、开启摄像头

int main(int argc, char **argv)
{.../* start camera */if (0 != ioctl(camera.fd, VIDIOC_STREAMON, &type)){printf("Unable to start capture\n");goto _err;}printf("\nstart camera ...\n");while (1){/* poll */memset(fds, 0, sizeof(fds));fds[0].fd = camera.fd;fds[0].events = POLLIN;if (1 == poll(fds, 1, -1)){/* dequeue buffer */struct v4l2_buffer buf;memset(&buf, 0, sizeof(struct v4l2_buffer));buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (0 != ioctl(camera.fd, VIDIOC_DQBUF, &buf)){printf("Unable to dequeue buffer\n");goto _ioc_dqbuf_err;}/* jpeg show on lcd */camera.bufs_index = buf.index;camera.buf_length = buf.length;jpeg_show_on_lcd(&lcd, &camera);/* queue buffer */if (0 != ioctl(camera.fd, VIDIOC_QBUF, &buf)){printf("Unable to queue buffer");goto _ioc_qbuf_err;}}}...}

4.5、完整的程序如下


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/types.h>          
#include <linux/videodev2.h>
#include <poll.h>
#include <sys/mman.h>
#include <jpeglib.h>
#include <linux/fb.h>typedef struct lcd_mes {int fd;unsigned char *fb_base;int lcd_width;int lcd_height;unsigned int bpp;unsigned int line_width;
} lcd_mes;typedef struct camera_mes {int fd;void *bufs[32];int bufs_index;int buf_length;char fmt[20];int frame_x_size;int frame_y_size;
} camera_mes;int jpeg_show_on_lcd(lcd_mes *lcd, camera_mes *camera)
{int min_width, min_height;int valid_bytes;int offset_x, offset_y;struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;cinfo.err = jpeg_std_error(&jerr);      // 错误处理对象与解码对象绑定jpeg_create_decompress(&cinfo);         // 初始化解码器jpeg_mem_src(&cinfo, camera->bufs[camera->bufs_index], camera->buf_length);   // 指定JPEG数据的来源jpeg_read_header(&cinfo, TRUE);         // 读取图像信息cinfo.out_color_space = JCS_RGB;        // 设置解码后的颜色空间为RGBjpeg_start_decompress(&cinfo);          // 开始解码unsigned char *jpeg_line_buf = (char *)malloc(cinfo.output_components * cinfo.output_width);    // 用于存储从JPEG解码器读取的一行数据unsigned int *fb_line_buf = (int *)malloc(lcd->line_width);                                     // 用于存储转换后的RGB数据,准备写入framebuffermin_width = (cinfo.output_width < lcd->lcd_width) ? cinfo.output_width : lcd->lcd_width;min_height = (cinfo.output_height < lcd->lcd_height) ? cinfo.output_height : lcd->lcd_height;valid_bytes = min_width * lcd->bpp / 8;             // 一行的有效字节数unsigned char *ptr = lcd->fb_base;offset_x = ((lcd->lcd_width - min_width) / 2) * lcd->bpp / 8;   // x方向居中offset_y = (lcd->lcd_height - min_height) / 2;      // y方向居中for (int i = 0; i < offset_y; i++)                  ptr += lcd->lcd_width * lcd->bpp / 8;unsigned int red, green, blue;unsigned int color;while (cinfo.output_scanline < min_height){jpeg_read_scanlines(&cinfo, &jpeg_line_buf, 1); // 每次读取一行for(int i = 0; i < min_width; i++)              {red = jpeg_line_buf[i * 3];                 green = jpeg_line_buf[i * 3 + 1];           blue = jpeg_line_buf[i * 3 + 2];            color = red << 16 | green << 8 | blue;      // RGB888转RGB8888fb_line_buf[i] = color;}memcpy(ptr + offset_x, fb_line_buf, valid_bytes);   // 将一行数据写入framebufferptr += lcd->lcd_width * lcd->bpp / 8;               // 移动到下一行}jpeg_finish_decompress(&cinfo);                     // 完成解码jpeg_destroy_decompress(&cinfo);                    // 销毁解码对象free(jpeg_line_buf);                                // 释放内存free(fb_line_buf);                                  // 释放内存return 0;
}int lcd_init(const char *fb_dev, lcd_mes *lcd)
{int screen_size;struct fb_var_screeninfo var;   if (fb_dev == NULL)goto _err;/* 1. open /dev/fb* */    lcd->fd = open(fb_dev, O_RDWR);if(lcd->fd < 0){printf("can not open %s\n", fb_dev);goto _err;}/* 2. get lcd message */if (ioctl(lcd->fd, FBIOGET_VSCREENINFO, &var)){printf("can not get var\n");goto _err;}screen_size = var.xres * var.yres * var.bits_per_pixel / 8;lcd->line_width  = var.xres * var.bits_per_pixel / 8;lcd->lcd_width = var.xres;lcd->lcd_height = var.yres;lcd->bpp = var.bits_per_pixel;lcd->fb_base = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->fd, 0);if (lcd->fb_base == (unsigned char *)-1){printf("can not mmap\n");goto _err;}memset(lcd->fb_base, 0x00, screen_size);return 0;_err:return -1;
}int camera_init(const char *video, camera_mes *camera)
{   struct v4l2_fmtdesc fmtdesc;struct v4l2_frmsizeenum fsenum;int fmt_index = 0;int frame_index = 0;int buf_cnt;int i;if (video == NULL)goto _err;/* 1. open /dev/video* */camera->fd = open(video, O_RDWR);if (camera->fd < 0){printf("can not open %s\n", video);goto _err;}/* 2. query capability */struct v4l2_capability cap;memset(&cap, 0, sizeof(struct v4l2_capability));if (0 == ioctl(camera->fd, VIDIOC_QUERYCAP, &cap)){        if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {fprintf(stderr, "Error opening device %s: video capture not supported.\n", video);goto _ioc_querycap_err;}if(!(cap.capabilities & V4L2_CAP_STREAMING)) {fprintf(stderr, "%s does not support streaming i/o\n", video);goto _ioc_querycap_err;}}else{printf("can not get capability\n");goto _ioc_querycap_err;}/* 3. enum formt */while (1){fmtdesc.index = fmt_index;  fmtdesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;  if (0 != ioctl(camera->fd, VIDIOC_ENUM_FMT, &fmtdesc))break;frame_index = 0;// printf("format %s,%d:\n", fmtdesc.description, fmtdesc.pixelformat);while (1){memset(&fsenum, 0, sizeof(struct v4l2_frmsizeenum));fsenum.pixel_format = fmtdesc.pixelformat;fsenum.index = frame_index;/* get framesize */if (ioctl(camera->fd, VIDIOC_ENUM_FRAMESIZES, &fsenum) == 0){// printf("\t%d: %d x %d\n", frame_index, fsenum.discrete.width, fsenum.discrete.height);}else{break;}frame_index++;}fmt_index++;}/* 4. set formt */struct v4l2_format fmt;memset(&fmt, 0, sizeof(struct v4l2_format));fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.width = camera->frame_x_size;fmt.fmt.pix.height = camera->frame_y_size;fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;fmt.fmt.pix.field = V4L2_FIELD_ANY;if (0 == ioctl(camera->fd, VIDIOC_S_FMT, &fmt)){// printf("the final frame-size has been set : %d x %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);camera->frame_x_size = fmt.fmt.pix.width;camera->frame_y_size = fmt.fmt.pix.height;strncpy(camera->fmt, "Motion-JPEG", strlen("Motion-JPEG"));}else{printf("can not set format\n");goto _ioc_sfmt_err;}/* 5. require buffer */struct v4l2_requestbuffers rb;memset(&rb, 0, sizeof(struct v4l2_requestbuffers));rb.count = 32;rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;rb.memory = V4L2_MEMORY_MMAP;if (0 == ioctl(camera->fd, VIDIOC_REQBUFS, &rb)){buf_cnt = rb.count;for(i = 0; i < rb.count; i++) {struct v4l2_buffer buf;memset(&buf, 0, sizeof(struct v4l2_buffer));buf.index = i;buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (0 == ioctl(camera->fd, VIDIOC_QUERYBUF, &buf)){/* mmap */camera->bufs[i] = mmap(0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, camera->fd, buf.m.offset);if(camera->bufs[i] == MAP_FAILED) {printf("Unable to map buffer");goto _err;}}else{printf("can not query buffer\n");goto _err;}            }}else{printf("can not request buffers\n");goto _ioc_reqbufs_err;}/* 6. queue buffer */for(i = 0; i < buf_cnt; ++i) {struct v4l2_buffer buf;memset(&buf, 0, sizeof(struct v4l2_buffer));buf.index = i;buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (0 != ioctl(camera->fd, VIDIOC_QBUF, &buf)){perror("Unable to queue buffer");goto _ioc_qbuf_err;}}camera->bufs_index = 0;     // init camera structcamera->buf_length = 0;return 0;_ioc_qbuf_err:
_ioc_reqbufs_err:
_ioc_sfmt_err:
_ioc_querycap_err:
_err:return -1;
}int main(int argc, char **argv)
{int ret;lcd_mes lcd;camera_mes camera;int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;struct pollfd fds[1];if (argc != 3){printf("Usage: %s </dev/videoX> </dev/fbX>\n", argv[0]);return -1;}/* lcd init */ret = lcd_init(argv[2], &lcd);if (ret == -1){printf("lcd init err !\n");goto _err;}printf("\n-------------- lcd message --------------\n");printf("screen pixel: %d x %d\n", lcd.lcd_width, lcd.lcd_height);printf("line width: %d (byte)\n", lcd.line_width);printf("bpp: %d\n", lcd.bpp);printf("-----------------------------------------\n");/* camera init */camera.frame_x_size = lcd.lcd_width;camera.frame_y_size = lcd.lcd_height;ret = camera_init(argv[1], &camera);if (ret == -1){printf("camera init err !\n");goto _err;}printf("\n------------ camera message -------------\n");printf("frame size: %d x %d\n", camera.frame_x_size, camera.frame_y_size);printf("format: %s\n", camera.fmt);printf("-----------------------------------------\n");/* start camera */if (0 != ioctl(camera.fd, VIDIOC_STREAMON, &type)){printf("Unable to start capture\n");goto _err;}printf("\nstart camera ...\n");while (1){/* poll */memset(fds, 0, sizeof(fds));fds[0].fd = camera.fd;fds[0].events = POLLIN;if (1 == poll(fds, 1, -1)){/* dequeue buffer */struct v4l2_buffer buf;memset(&buf, 0, sizeof(struct v4l2_buffer));buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (0 != ioctl(camera.fd, VIDIOC_DQBUF, &buf)){printf("Unable to dequeue buffer\n");goto _ioc_dqbuf_err;}/* jpeg show on lcd */camera.bufs_index = buf.index;camera.buf_length = buf.length;jpeg_show_on_lcd(&lcd, &camera);/* queue buffer */if (0 != ioctl(camera.fd, VIDIOC_QBUF, &buf)){printf("Unable to queue buffer");goto _ioc_qbuf_err;}}}/* close camera */if (0 != ioctl(camera.fd, VIDIOC_STREAMOFF, &type)){printf("Unable to stop capture\n");goto _ioc_streamoff_err;}close(camera.fd);return 0;_ioc_streamoff_err:
_ioc_qbuf_err:
_ioc_dqbuf_err:
_err:return -1;
}

5、测试

5.1、编译应用程序

如果你使用的buildroot系统,需要交叉编译。

这里测试所使用的板子跑的是ubuntu,执行如下命令直接编译:

sudo gcc -o uvctolcd uvctolcd.c -ljpeg

5.2、运行应用程序

sudo ./uvctolcd /dev/video10 /dev/fb0


6、总结

参考文章:Linux摄像头(v4l2应用)——在LCD上实时显示摄像头采集JPEG数据_v4l2调用并显示图像-CSDN博客

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

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

相关文章

[代码规范]接口设计规范

一个优雅的接口要如何设计&#xff1f;有哪些设计规范可以遵循&#xff1f; 下面抛砖引玉&#xff0c;分享一些规范。 目录 1、RESTful API 设计最佳实践 2、Shneiderman 的 8 条黄金法则 3、Nielsen 的 10 条启发式规则 1、RESTful API 设计最佳实践 一共18条&#xff0c;参考…

如何在Python用Plot画出一个简单的机器人模型

如何在Python中使用 Plot 画出一个简单的模型 在下面的程序中&#xff0c;首先要知道机器人的DH参数&#xff0c;然后计算出每一个关节的位置&#xff0c;最后利用 plot 函数画出关节之间的连杆就可以了&#xff0c;最后利用 animation 库来实现一个动画效果。 import matplo…

Spark核心之01:架构部署、sparkshell、程序模板

spark内存计算框架 一、主题 spark核心概念spark集群架构spark集群安装部署spark-shell的使用通过IDEA开发spark程序 二、要点 1. spark是什么 Apache Spark™ is a unified analytics engine for large-scale data processing. spark是针对于大规模数据处理的统一分析引擎…

如何通过Python网络爬虫技术应对复杂的反爬机制?

要使用Python网络爬虫技术绕过复杂的反爬虫机制&#xff0c;可以采取以下几种策略&#xff1a; 设置User-Agent&#xff1a;通过设置不同的User-Agent&#xff0c;模拟正常用户的浏览器访问&#xff0c;避免被网站识别为爬虫。可以使用fake_useragent库来随机生成User-Agent。…

[Windows] 批量为视频或者音频生成字幕 video subtitle master 1.5.2

Video Subtitle Master 1.5.2 介绍 Video Subtitle Master 1.5.2 是一款功能强大的客户端工具&#xff0c;能够批量为视频或音频生成字幕&#xff0c;还支持批量将字幕翻译成其他语言。该工具具有跨平台性&#xff0c;无论是 mac 系统还是 windows 系统都能使用。 参考原文&a…

神经网络代码入门解析

神经网络代码入门解析 import torch import matplotlib.pyplot as pltimport randomdef create_data(w, b, data_num): # 数据生成x torch.normal(0, 1, (data_num, len(w)))y torch.matmul(x, w) b # 矩阵相乘再加bnoise torch.normal(0, 0.01, y.shape) # 为y添加噪声…

DeepSeek 开源狂欢周(一)FlashMLA:高效推理加速新时代

上周末&#xff0c;DeepSeek在X平台&#xff08;Twitter&#xff09;宣布将开启连续一周的开源&#xff0c;整个开源社区为之沸腾&#xff0c;全球AI爱好者纷纷为关注。没错&#xff0c;这是一场由DeepSeek引领的开源盛宴&#xff0c;推翻了传统推理加速的种种限制。这周一&…

EfficientViT模型详解及代码复现

核心架构 在EfficientViT模型的核心架构中,作者设计了一种创新的 sandwich布局 作为基础构建块,旨在提高内存效率和计算效率。这种布局巧妙地平衡了自注意力层和前馈神经网络层的比例,具体结构如下: 基于深度卷积的Token Interaction :通过深度卷积操作对输入特征进行初步…

大语言模型(LLM)如何赋能时间序列分析?

引言 近年来&#xff0c;大语言模型&#xff08;LLM&#xff09;在文本生成、推理和跨模态任务中展现了惊人能力。与此同时&#xff0c;时间序列分析作为工业、金融、物联网等领域的核心技术&#xff0c;长期依赖传统统计模型&#xff08;如ARIMA&#xff09;或深度学习模型&a…

Java 设计模式:软件开发的精髓与艺

目录 一、设计模式的起源二、设计模式的分类1. 创建型模式2. 结构型模式3. 行为型模式三、设计模式的实践1. 单例模式2. 工厂模式3. 策略模式四、设计模式的优势五、设计模式的局限性六、总结在软件开发的浩瀚星空中,设计模式犹如一颗颗璀璨的星辰,照亮了开发者前行的道路。它…

【基于Raft的KV共识算法】-序:Raft概述

本文目录 1.为什么会有Raft&#xff1f;CAP理论 2.Raft基本原理流程为什么要以日志作为中间载体&#xff1f; 3.实现思路任期领导选举日志同步 1.为什么会有Raft&#xff1f; 简单来说就是数据会随着业务和时间的增长&#xff0c;单机不能存的下&#xff0c;这个时候需要以某种…

【愚公系列】《Python网络爬虫从入门到精通》040-Matplotlib 概述

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

EasyRTC嵌入式WebRTC技术与AI大模型结合:从ICE框架优化到AI推理

实时通信技术在现代社会中扮演着越来越重要的角色&#xff0c;从视频会议到在线教育&#xff0c;再到远程医疗&#xff0c;其应用场景不断拓展。WebRTC作为一项开源项目&#xff0c;为浏览器和移动应用提供了便捷的实时通信能力。而EasyRTC作为基于WebRTC的嵌入式解决方案&…

javaEE初阶————多线程初阶(5)

本期是多线程初阶的最后一篇文章了&#xff0c;下一篇就是多线程进阶的文章了&#xff0c;大家加油&#xff01; 一&#xff0c;模拟实现线程池 我们上期说过线程池类似一个数组&#xff0c;我们有任务就放到线程池中&#xff0c;让线程池帮助我们完成任务&#xff0c;我们该如…

工业AR眼镜的‘芯’动力:FPC让制造更智能【新立电子】

随着增强现实&#xff08;AR&#xff09;技术的快速发展&#xff0c;工业AR智能眼镜也正逐步成为制造业领域的重要工具。它不仅为现场工作人员提供了视觉辅助&#xff0c;还极大地提升了远程协助的效率、优化了仓储管理。FPC在AI眼镜中的应用&#xff0c;为工业AR智能眼镜提供了…

FPGA开发,使用Deepseek V3还是R1(5):temperature设置

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…

网站内容更新后百度排名下降怎么办?有效策略有哪些?

转自 网站内容更新后百度排名下降怎么办&#xff1f;有效策略有哪些&#xff1f; 网站内容更新是促进网站优化的关键环节&#xff0c;但是频繁修改网站内容会对网站的搜索引擎排名造成很大的影响。为了保持网站排名&#xff0c;我们需要采取一些措施来最小化对百度排名的影响。…

安装 cpolar 内网穿透工具的步骤

安装 cpolar 内网穿透工具的步骤 1. 下载 cpolar 软件安装包 步骤&#xff1a; 前往 cpolar 官方下载页面。 根据您的操作系统&#xff08;Windows、macOS、Linux 等&#xff09;&#xff0c;选择对应的安装包进行下载。 2. 注册 cpolar 账号 步骤&#xff1a; 访问 cpolar…

Linux :进程状态

目录 1 引言 2 操作系统的资源分配 3进程状态 3.1运行状态 3.2 阻塞状态 3.3挂起状态 4.进程状态详解 4.1 运行状态R 4.2 休眠状态S 4.3深度睡眠状态D 4.4僵尸状态Z 5 孤儿进程 6 进程优先级 其他概念 1 引言 &#x1f33b;在前面的文章中&#xff0c;我们已…

openwebUI访问vllm加载deepseek微调过的本地大模型

文章目录 前言一、openwebui安装二、配置openwebui环境三、安装vllm四、启动vllm五、启动openwebui 前言 首先安装vllm&#xff0c;然后加载本地模型&#xff0c;会起一个端口好。 在安装openwebui,去访问这个端口号。下面具体步骤的演示。 一、openwebui安装 rootautodl-co…