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

【MediaFoundation】OpenCV VideoCapture 读取音频源码

OpenCV 读取音频代码实例

在windows7 以及OpenCV4 过后可以使用 CAP_MSMF 读取音频,但是OpenCV没有播放音频的API。代码示例如下。 本文解析OpenCVCAP_MSMF 进行文件、设备的 音频读取,学习MediaFoundation 的使用。

#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main(int argc, const char** argv)
{Mat videoFrame;Mat audioFrame;vector<vector<Mat>> audioData;VideoCapture cap;vector<int> params {    CAP_PROP_AUDIO_STREAM, 0,CAP_PROP_VIDEO_STREAM, -1,CAP_PROP_AUDIO_DATA_DEPTH, CV_32F   };//cap.open(file, CAP_MSMF, params);// 打开第一个音频输入设备cap.open(0, CAP_MSMF, params);if (!cap.isOpened()){cerr << "ERROR! Can't to open file: " + file << endl;return -1;}const int audioBaseIndex = (int)cap.get(CAP_PROP_AUDIO_BASE_INDEX);const int numberOfChannels = (int)cap.get(CAP_PROP_AUDIO_TOTAL_CHANNELS);cout << "CAP_PROP_AUDIO_DATA_DEPTH: " << depthToString((int)cap.get(CAP_PROP_AUDIO_DATA_DEPTH)) << endl;cout << "CAP_PROP_AUDIO_SAMPLES_PER_SECOND: " << cap.get(CAP_PROP_AUDIO_SAMPLES_PER_SECOND) << endl;cout << "CAP_PROP_AUDIO_TOTAL_CHANNELS: " << cap.get(CAP_PROP_AUDIO_TOTAL_CHANNELS) << endl;cout << "CAP_PROP_AUDIO_TOTAL_STREAMS: " << cap.get(CAP_PROP_AUDIO_TOTAL_STREAMS) << endl;int numberOfSamples = 0;int numberOfFrames = 0;audioData.resize(numberOfChannels);mfcap::AudioOutput audioOutput;audioOutput.Open((int)cap.get(CAP_PROP_AUDIO_TOTAL_CHANNELS),(int)cap.get(CAP_PROP_AUDIO_SAMPLES_PER_SECOND),16);for (;;){if (cap.grab()){//cap.retrieve(videoFrame);std::vector<const unsigned char*> planes;planes.resize(numberOfChannels);for (int nCh = 0; nCh < numberOfChannels; nCh++){cap.retrieve(audioFrame, audioBaseIndex+nCh);if (!audioFrame.empty()){audioData[nCh].push_back(audioFrame);//planes[nCh] = audioFrame.data + nCh * audioFrame.cols;}numberOfSamples+=audioFrame.cols;}} else { break; }}cout << "Number of audio samples: " << numberOfSamples << endl<< "Number of video frames: " << numberOfFrames << endl;return 0;
}

打开设备

bool CvCapture_MSMF::open(int index, const cv::VideoCaptureParameters* params)
{// 先重置环境close();if (index < 0)return false;if (params){// 开启硬件编解码加速,这里先省略,在后面的硬件加速上学习。configureHW(*params);/* configureStream 主要是配置是否捕获音频或视频流// 如果需要捕获音频流: audioStream = 0 否者 audioStream  = -1// 视频流同理,对应的变量为: videoStream*//* setAudioProperties // outputAudioFormat: 音频的位深, CV_16S 等// audioSamplesPerSecond 采样率// syncLastFrame: 是否需要音视频同步,OpenCV里面只支持视频文件的音视频同步*/if (!(configureStreams(*params) && setAudioProperties(*params)))return false;}// 仅支持打开音频流或者视频流,不能在一个对象里面打开或者都不打开。if (videoStream != -1 && audioStream != -1 || videoStream == -1 && audioStream == -1){CV_LOG_DEBUG(NULL, "Only one of the properties CAP_PROP_AUDIO_STREAM " << audioStream << " and " << CAP_PROP_VIDEO_STREAM << " must be different from -1");return false;}// DeviceList  主要检测当前系统中,视频或音频输入设备的个数,以及激活某一个设备。DeviceList devices;UINT32 count = 0;// 如果是读音频设备就枚举音频输入设备if (audioStream != -1)count = devices.read(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID);// 读视频设备同理。值得注意的是,opencv只支持读音频或视频设备// 如果都设置为0, 则默认读视频if (videoStream != -1)count = devices.read(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);if (count == 0 || static_cast<UINT32>(index) > count){CV_LOG_DEBUG(NULL, "Device " << index << " not found (total " << count << " devices)");return false;}/* getDefaultSourceConfig 这个主要设置硬件加速相关,这里可以先跳过*/_ComPtr<IMFAttributes> attr = getDefaultSourceConfig();/*SourceReaderCB 读取回调设置读取回调,当设置了读取的回调之后,MediaFoundation 读取Source 为异步模式这个Open函数是读设备的,还有其他重载函数用于读文件在OpenCV里面,读取设备使用异步模式,读取文件使用同步模式。*/_ComPtr<IMFSourceReaderCallback> cb = new SourceReaderCB();attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, cb.Get());// 激活目标设备_ComPtr<IMFMediaSource> src = devices.activateSource(index);if (!src.Get() || FAILED(MFCreateSourceReaderFromMediaSource(src.Get(), attr.Get(), &videoFileSource))){CV_LOG_DEBUG(NULL, "Failed to create source reader");return false;}isOpen = true;device_status = true;camid = index;readCallback = cb;duration = 0;// 选择合适的摄像头的流,比如宽高,fps.一般一个摄像头有很多个拉流的格式// 音频设备同理,比如有不同的采样率,位深等。if (configureOutput()){frameStep = captureVideoFormat.getFrameStep();}if (isOpen && !openFinalize_(params)){close();return false;}if (isOpen){if (audioStream != -1)if (!checkAudioProperties())return false;}return isOpen;
}

选择合适的设备流 configureOutput

bool CvCapture_MSMF::configureOutput()
{// 读取设备所有的流,当然也可以读第一个流if (FAILED(videoFileSource->SetStreamSelection((DWORD)MF_SOURCE_READER_ALL_STREAMS, false))){CV_LOG_WARNING(NULL, "Failed to reset streams");return false;}bool tmp = true;// 配置视频流if (videoStream != -1)tmp = (!device_status)? configureVideoOutput(MediaType(), outputVideoFormat) : configureVideoOutput(MediaType::createDefault_Video(), outputVideoFormat);// 配置音频流if (audioStream != -1)tmp &= (!device_status)? configureAudioOutput(MediaType()) : configureAudioOutput(MediaType::createDefault_Audio());return tmp;
}

配置音频流 configureAudioOutput

bool CvCapture_MSMF::configureAudioOutput(MediaType newType)
{/*FormatStorage  存储设备的流信息,以及挑选最合适的流*/FormatStorage formats;formats.read(videoFileSource.Get());std::pair<FormatStorage::MediaID, MediaType> bestMatch;formats.countNumberOfAudioStreams(numberOfAudioStreams);if (device_status)bestMatch = formats.findBestAudioFormat(newType);elsebestMatch = formats.findAudioFormatByStream(audioStream);if (bestMatch.second.isEmpty(true)){CV_LOG_DEBUG(NULL, "Can not find audio stream with requested parameters");isOpen = false;return false;}dwAudioStreamIndex = bestMatch.first.stream;dwStreamIndices.push_back(dwAudioStreamIndex);MediaType newFormat = bestMatch.second;newFormat.majorType = MFMediaType_Audio;newFormat.nSamplesPerSec = (audioSamplesPerSecond == 0) ? 44100 : audioSamplesPerSecond;switch (outputAudioFormat){case CV_8S:newFormat.subType = MFAudioFormat_PCM;newFormat.bit_per_sample = 8;break;case CV_16S:newFormat.subType = MFAudioFormat_PCM;newFormat.bit_per_sample = 16;break;case CV_32S:newFormat.subType = MFAudioFormat_PCM;newFormat.bit_per_sample = 32;case CV_32F:newFormat.subType = MFAudioFormat_Float;newFormat.bit_per_sample = 32;break;default:break;}// 初始化流return initStream(dwAudioStreamIndex, newFormat);
}

初始化流 initStream

bool CvCapture_MSMF::initStream(DWORD streamID, const MediaType mt)
{CV_LOG_DEBUG(NULL, "Init stream " << streamID << " with MediaType " << mt);_ComPtr<IMFMediaType> mediaTypesOut;if (mt.majorType == MFMediaType_Audio){captureAudioFormat = mt;mediaTypesOut = mt.createMediaType_Audio();}if (mt.majorType == MFMediaType_Video){captureVideoFormat = mt;mediaTypesOut = mt.createMediaType_Video();}if (FAILED(videoFileSource->SetStreamSelection(streamID, true))){CV_LOG_WARNING(NULL, "Failed to select stream " << streamID);return false;}HRESULT hr = videoFileSource->SetCurrentMediaType(streamID, NULL, mediaTypesOut.Get());if (hr == MF_E_TOPO_CODEC_NOT_FOUND){CV_LOG_WARNING(NULL, "Failed to set mediaType (stream " << streamID << ", " << mt << "(codec not found)");return false;}else if (hr == MF_E_INVALIDMEDIATYPE){CV_LOG_WARNING(NULL, "Failed to set mediaType (stream " << streamID << ", " << mt << "(unsupported media type)");return false;}else if (FAILED(hr)){CV_LOG_WARNING(NULL, "Failed to set mediaType (stream " << streamID << ", " << mt << "(HRESULT " << hr << ")");return false;}return true;
}

捕获音频帧 Garb()

捕获帧的回调 SourceReaderCB

OpenCV捕获设备数据,采用异步模式,需要自定义一个捕获帧的回调

// 需要继承 IMFSourceReaderCallback
class SourceReaderCB : public IMFSourceReaderCallback
{
public:
// 最大的缓冲帧数量static const size_t MSMF_READER_MAX_QUEUE_SIZE = 3;SourceReaderCB() :m_nRefCount(0), m_hEvent(CreateEvent(NULL, FALSE, FALSE, NULL)), m_bEOS(FALSE), m_hrStatus(S_OK), m_reader(NULL), m_dwStreamIndex(0){}// COM 接口必须的,感觉就是照着格式写// IUnknown methodsSTDMETHODIMP QueryInterface(REFIID iid, void** ppv) CV_OVERRIDE{
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4838)
#endifstatic const QITAB qit[] ={QITABENT(SourceReaderCB, IMFSourceReaderCallback),{ 0 },};
#ifdef _MSC_VER
#pragma warning(pop)
#endifreturn QISearch(this, qit, iid, ppv);}STDMETHODIMP_(ULONG) AddRef() CV_OVERRIDE{return InterlockedIncrement(&m_nRefCount);}STDMETHODIMP_(ULONG) Release() CV_OVERRIDE{ULONG uCount = InterlockedDecrement(&m_nRefCount);if (uCount == 0){delete this;}return uCount;}// 在 调用wait()的时候 被调用STDMETHODIMP OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex, DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample) CV_OVERRIDE{HRESULT hr = 0;cv::AutoLock lock(m_mutex);if (SUCCEEDED(hrStatus)){if (pSample){CV_LOG_DEBUG(NULL, "videoio(MSMF): got frame at " << llTimestamp);// 如果缓冲的帧的数量大于最大的数量,需要弹出前面的帧if (m_capturedFrames.size() >= MSMF_READER_MAX_QUEUE_SIZE){
#if 0CV_LOG_DEBUG(NULL, "videoio(MSMF): drop frame (not processed). Timestamp=" << m_capturedFrames.front().timestamp);m_capturedFrames.pop();
#else// this branch reduces latency if we drop frames due to slow processing.// avoid fetching of already outdated frames from the queue's front.CV_LOG_DEBUG(NULL, "videoio(MSMF): drop previous frames (not processed): " << m_capturedFrames.size());std::queue<CapturedFrameInfo>().swap(m_capturedFrames);  // similar to missing m_capturedFrames.clean();
#endif}m_capturedFrames.emplace(CapturedFrameInfo{ llTimestamp, _ComPtr<IMFSample>(pSample), hrStatus });}}else{CV_LOG_WARNING(NULL, "videoio(MSMF): OnReadSample() is called with error status: " << hrStatus);}if (MF_SOURCE_READERF_ENDOFSTREAM & dwStreamFlags){// Reached the end of the stream.m_bEOS = true;}m_hrStatus = hrStatus;if (FAILED(hr = m_reader->ReadSample(dwStreamIndex, 0, NULL, NULL, NULL, NULL))){CV_LOG_WARNING(NULL, "videoio(MSMF): async ReadSample() call is failed with error status: " << hr);m_bEOS = true;}if (pSample || m_bEOS){SetEvent(m_hEvent);}return S_OK;}STDMETHODIMP OnEvent(DWORD, IMFMediaEvent *) CV_OVERRIDE{return S_OK;}STDMETHODIMP OnFlush(DWORD) CV_OVERRIDE{return S_OK;}HRESULT Wait(DWORD dwMilliseconds, _ComPtr<IMFSample>& mediaSample, LONGLONG& sampleTimestamp, BOOL& pbEOS){pbEOS = FALSE;for (;;){{cv::AutoLock lock(m_mutex);pbEOS = m_bEOS && m_capturedFrames.empty();if (pbEOS)return m_hrStatus;if (!m_capturedFrames.empty()){CV_Assert(!m_capturedFrames.empty());CapturedFrameInfo frameInfo = m_capturedFrames.front(); m_capturedFrames.pop();CV_LOG_DEBUG(NULL, "videoio(MSMF): handle frame at " << frameInfo.timestamp);mediaSample = frameInfo.sample;CV_Assert(mediaSample);sampleTimestamp = frameInfo.timestamp;ResetEvent(m_hEvent);  // event is auto-reset, but we need this forced reset due time gap between wait() and mutex hold.return frameInfo.hrStatus;}}CV_LOG_DEBUG(NULL, "videoio(MSMF): waiting for frame... ");DWORD dwResult = WaitForSingleObject(m_hEvent, dwMilliseconds);if (dwResult == WAIT_TIMEOUT){return E_PENDING;}else if (dwResult != WAIT_OBJECT_0){return HRESULT_FROM_WIN32(GetLastError());}}}private:// Destructor is private. Caller should call Release.virtual ~SourceReaderCB(){CV_LOG_INFO(NULL, "terminating async callback");}public:long                m_nRefCount;        // Reference count.cv::Mutex           m_mutex;HANDLE              m_hEvent;BOOL                m_bEOS;HRESULT             m_hrStatus;IMFSourceReader *m_reader;DWORD m_dwStreamIndex;struct CapturedFrameInfo {LONGLONG timestamp;_ComPtr<IMFSample> sample;HRESULT hrStatus;};std::queue<CapturedFrameInfo> m_capturedFrames;
};

相关文章:

【MediaFoundation】OpenCV VideoCapture 读取音频源码

OpenCV 读取音频代码实例 在windows7 以及OpenCV4 过后可以使用 CAP_MSMF 读取音频&#xff0c;但是OpenCV没有播放音频的API。代码示例如下。 本文解析OpenCVCAP_MSMF 进行文件、设备的 音频读取&#xff0c;学习MediaFoundation 的使用。 #include <opencv2/core.hpp>…...

2024秋招,百度测试开发工程师一面

前言 大家好&#xff0c;今天我来回顾一下秋招中的一场很重要技术面试 一面面试官深挖我的项目经历&#xff0c;并提出了很多的实际场景&#xff0c;我现在回顾依然有很多新的认识 过程 自我介绍实习工作中&#xff0c;做得最好的地方是什么&#xff1f; 我先介绍了一下实习…...

Git 使用与问题记录 二(公司快速上手版)

写在前面 记录自己学习的内容&#xff0c;方便后面忘记的时候查看。给像我一样的新手提供一点参考 正文 上一章已经安装好了Git&#xff0c;如何使用呢。我这里会分享两种办法&#xff0c;第一种是在VS2022中克隆代码&#xff0c;修改和提交&#xff1b;第二种是用命令提交。…...

【C语言小游戏】贪吃蛇

文章目录 1.引言2.运行图2.涉及知识3 Windows API3.1 控制台3.2 控制台屏幕坐标3.3 操作句柄3.4 控制台屏幕光标3.5 监视按键 4. 设计说明5. 完整代码 1.引言 使⽤C语⾔在Windows环境的控制台中模拟实现经典⼩游戏贪吃蛇 实现基本的功能&#xff1a; 贪吃蛇地图绘制蛇吃⻝物的…...

价值7500的在线授权网站源码支持IP+域名+双向授权全开源

PHP授权验证更新系统完整版&#xff0c;一键更新系统&#xff0c;一键卡密生成自助授权功能&#xff0c;域名ip双重验证功能等等 修复盗版检测&#xff0c;确保实时查看盗版 修复在线加密系统&#xff0c;一键加密 授权系统几乎所有的程序都能整合使用,包括您的app和计算机程序…...

haiku实现门控多头注意力模块

在多头注意力机制中&#xff0c;通常输入的数据包括查询&#xff08;Q&#xff09;、键&#xff08;K&#xff09;和值&#xff08;V&#xff09;。这些数据的维度以及权重矩阵的维度在多头注意力机制中扮演关键角色。下面对数据及权重的维度进行解释&#xff1a; 输入数据&…...

【React 常用的 TS 类型】持续更新

1&#xff09;定义样式的 TS 类型 【 React.CSSProperties 】 一般定义样式时需要的类型限制&#xff0c;如下&#xff1a; const customStyle: React.CSSProperties {color: blue,fontSize: 16px,margin: 10px,}; 2&#xff09;定义 Input Ref 属性时的 TS 类型限制 【 R…...

打破传统边界,VR技术与六西格玛设计理念的创新融合!

在科技飞速发展的今天&#xff0c;虚拟现实&#xff08;VR&#xff09;技术以其独特的沉浸式体验&#xff0c;正在改变我们的生活和工作方式。然而&#xff0c;要让VR真正成为主流&#xff0c;我们必须解决一些关键问题&#xff0c;其中最重要的就是用户体验。六西格玛设计&…...

[uniapp] uni-ui+vue3.2小程序评论列表组件 回复评论 点赞和删除

先看效果 下载地址 uni-app官方插件市场: cc-comment组件 环境 基于vue3.2和uni-ui开发; 依赖版本参考如下: "dependencies": {"dcloudio/uni-mp-weixin": "3.0.0-3090820231124001","dcloudio/uni-ui": "^1.4.28","…...

TongLINKQ(3):TongLINKQ常用命令

启动&#xff1a; tlq 暂停&#xff1a; tlq -cabort -y -w1 查看lic信息&#xff1a; tlqstat –lic 查看队列消息&#xff1a; tlqstat -qcu qcu名 -c 查看发送连接状态&#xff1a; tlqstat -snd qcu名 -1 -ct 1 查看指定的Qcu连接状态&#xff1a; tlqsta…...

抽水马桶出水慢解决记录

今天分享一些修马桶的小心得&#xff08;雾&#xff09; 家里的马桶出水很好&#xff0c;但是水却不怎么被冲下去&#xff08;出水很慢&#xff09;&#xff0c;这会导致内容物滞留&#xff0c;造成很不好的使用体验。 出于成本考虑&#xff0c;首先选择自己维修。 首先直接…...

img标签的奇怪问题

本来只是为实现一个轮播图&#xff0c;img的url地址是从后端接口获取的&#xff0c;但不巧的是url地址的图片都过期了。 因为懒得重新到网上找图&#xff0c;就想直接用一下本地的图片&#xff0c;简单的想法遇到一堆问题。 问题一&#xff1a; 因为是springboot项目&#xf…...

深入探究Hibernate:优雅、强大的Java持久化框架

目录 1、前言 2、Hibernate简介 2.1 什么是Hibernate 2.2 为什么选择Hibernate 3、Hibernate核心概念 3.1 实体类和映射文件 3.2 数据库表和持久化类的映射 3.3 主键生成策略 3.4 持久化操作 3.5 查询语言(HQL和Criteria) 3.6 事务管理 4、Hibernate配置与连接 4…...

JavaScript高级特性详解

摘要&#xff1a;本文将深入探讨JavaScript中的一些高级特性&#xff0c;包括闭包、原型链、高阶函数和异步编程。我们将通过详细的注释和实例来帮助读者理解这些概念&#xff0c;并通过总结部分强调其在实际开发中的应用。 一、闭包 闭包是JavaScript中一个非常重要的概念&a…...

网站建设网络设计营销类网站eyouCMS模板(PC+WAP)

模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff0c;原创设计、手工书写DIVCSS&#xff0c;完美兼容IE7、Firefox、Chrome、360浏览器等&#xff1b;主流浏览器&#xff1b;结构容易优化&#xff1b;多终端均可正常预览。...

迅为RK3568开发板Android11/12/Linux编译驱动到内核

在平时的驱动开发中&#xff0c;经常需要在内核中配置某种功能&#xff0c;为了方便大家开发和学习&#xff0c;本小 节讲解如何在内核中添加驱动。具体的讲解原理讲解请参考本手册的驱动教程。 Android11 源码如果想要修改内核&#xff0c;可以运行以下命令进行修改: cd ke…...

SaaS 应用深度解析:Marketo

随着数字营销的不断发展&#xff0c;企业需要强大而智能的工具来管理营销活动、吸引潜在客户、并实现销售目标。在众多营销自动化工具中&#xff0c;Marketo 是一款备受推崇的 SaaS 应用&#xff0c;为企业提供全面的营销解决方案。本文将深入了解 Marketo&#xff0c;探讨其功…...

闲聊篇-求职的点点滴滴~~

引言 求职之旅是一段充满挑战与机遇的旅程。它不仅仅是寻找工作的过程&#xff0c;更是一个自我探索和成长的过程。在这篇文章中&#xff0c;我们将探讨求职的各个方面&#xff0c;从准备简历到面试&#xff0c;再到最终拿到心仪的offer。 1. 简历&#xff1a;你的敲门砖 精…...

微软最新研究成果:使用GPT-4合成数据来训练AI模型,实现SOTA!

文本嵌入是各项NLP任务的基础&#xff0c;用于将自然语言转换为向量表示。现有的大部分方法通常采用复杂的多阶段训练流程&#xff0c;先在大规模数据上训练&#xff0c;再在小规模标注数据上微调。此过程依赖于手动收集数据制作正负样本对&#xff0c;缺乏任务的多样性和语言多…...

爬虫案例—抓取小米商店应用

爬虫案例—抓取小米商店应用 代码如下&#xff1a; # 抓取第一页的内容 import requests from lxml import etree url ‘https://app.mi.com/catTopList/0?page1’ headers { ‘User-Agent’: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…...

geemap学习笔记047:边缘检测

前言 边缘检测适用于众多的图像处理任务&#xff0c;除了上一节[[geemap046&#xff1a;线性卷积–低通滤波器和拉普拉斯算子|线性卷积]]中描述的边缘检测核之外&#xff0c;Earth Engine 中还有几种专门的边缘检测算法。其中Canny 边缘检测算法使用四个独立的滤波器来识别对角…...

《Git学习笔记:IDEA整合Git》

在IDEA中集成Git去使用 通过Git命令可以完成Git相关操作&#xff0c;为了简化操作过程&#xff0c;我们可以在IDEA中配置Git&#xff0c;配置好后就可以在IDEA中通过图形化的方式来操作Git。 在IDEA开发工具中可以集成Git&#xff1a; 集成后在IDEA中可以看到Git相关图标&…...

Scipy 高级教程——统计学

Python Scipy 高级教程&#xff1a;统计学 Scipy 提供了强大的统计学工具&#xff0c;用于描述、分析和推断数据的分布和性质。本篇博客将深入介绍 Scipy 中的统计学功能&#xff0c;并通过实例演示如何应用这些工具。 1. 描述性统计 描述性统计是统计学中最基本的任务之一&…...

《向量数据库指南》RAG 应用中的指代消解——解决方案初探

随着 ChatGPT 等大语言模型(LLM)的不断发展&#xff0c;越来越多的研究人员开始关注语言模型的应用。 其中&#xff0c;检索增强生成&#xff08;Retrieval-augmented generation&#xff0c;RAG&#xff09;是一种针对知识密集型 NLP 任务的生成方法&#xff0c;它通过在生成过…...

CSS 一行三列布局,可换行(含grid网格布局、flex弹性布局/inline-block布局 + 伪类选择器)

效果 一、HTML <div class"num-wrap"><div class"num-item" v-for"num in 8" :key"num">{{ num }}</div></div> 二、CSS 1、grid网格布局&#xff08;推荐&#xff09; .num-wrap {// grid网格布局display…...

class_3:lambda表达式

1、lambda表达式是c11引入的一种匿名函数的方式&#xff0c;它允许你在需要函数的地方内联的定义函数&#xff0c;而无需单独命名函数&#xff1b; #include <iostream>using namespace std;bool compare(int a,int b) {return a > b; }int getMax(int a,int b,bool (…...

Hadoop 实战 | 词频统计WordCount

词频统计 通过分析大量文本数据中的词频&#xff0c;可以识别常见词汇和短语&#xff0c;从而抽取文本的关键信息和概要&#xff0c;有助于识别文本中频繁出现的关键词&#xff0c;这对于理解文本内容和主题非常关键。同时&#xff0c;通过分析词在文本中的相对频率&#xff0…...

SpringCloud.04.熔断器Hystrix( Spring Cloud Alibaba 熔断(Sentinel))

目录 熔断器概述 使用Sentinel工具 什么是Sentinel 微服务集成Sentinel 配置provider文件&#xff0c;在里面加入有关控制台的配置 实现一个接口的限流 基本概念 重要功能 Sentinel规则 流控规则 简单配置 配置流控模式 配置流控效果 降级规则 SentinelResource…...

python 八大排序_python-打基础-八大排序

## 排序篇 #### 二路归并排序 - 介绍 - 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列…...

运维知识点-Sqlite

Sqlite 引入 依赖 引入 依赖 <dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.36.0.3</version></dependency>import javafx.scene.control.Alert; import java.sql.*;public clas…...