C/C++开发,opencv与qt结合播放视频
目录
一、qt_ui创建
1.1 ui设置
1.2 ui及代码输出保存
二、创建工程
2.1 工程目录及编译设置
2.2 源码设计
三、编译及测试
3.1 程序编译
3.2 程序运行
首先声明,这是一个OpenCV 3学习文档的案例,但是说明有些过于省略,只有一些简短的代码描述,本人在学习验证过程中将其记录下来分享给大家。
一、qt_ui创建
1.1 ui设置
本文采用qt5.8_msvc2015_64版本,
进入qt的bin目录,打开qt_ui设计工具designer.exe
创建一个Widget窗体,即对象QWidget,命名为QMoviePlayer。
随后创建一个QFrame对象,对象名为frame,该对象可以随意在窗体QMoviePlayer拉出一个合适的长宽比显示框,该显示框用来显示视频使用。
完成设置后,保存该UI,例如QMoviePlayer.ui
1.2 ui及代码输出保存
本人的QMoviePlayer.ui文件的xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>QMoviePlayer</class><widget class="QWidget" name="QMoviePlayer"><property name="geometry"><rect><x>0</x><y>0</y><width>600</width><height>303</height></rect></property><property name="windowTitle"><string>Form</string></property><widget class="QFrame" name="frame"><property name="geometry"><rect><x>0</x><y>0</y><width>601</width><height>241</height></rect></property><property name="frameShape"><enum>QFrame::StyledPanel</enum></property><property name="frameShadow"><enum>QFrame::Raised</enum></property></widget></widget><resources/><connections/>
</ui>
点击窗体菜单,进入查看代码,保存该代码文件为ui_QMoviePlayer.h,或新创建一个头文件将该内容直接复制到头文件中保存。
本人的ui_QMoviePlayer.h的代码内容如下。
/********************************************************************************
** Form generated from reading UI file 'QMoviePlayerp15136.ui'
**
** Created by: Qt User Interface Compiler version 5.8.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/#ifndef QMOVIEPLAYERP15136_H
#define QMOVIEPLAYERP15136_H#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QFrame>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QWidget>QT_BEGIN_NAMESPACEclass Ui_QMoviePlayer
{
public:QFrame *frame;void setupUi(QWidget *QMoviePlayer){if (QMoviePlayer->objectName().isEmpty())QMoviePlayer->setObjectName(QStringLiteral("QMoviePlayer"));QMoviePlayer->resize(600, 303);frame = new QFrame(QMoviePlayer);frame->setObjectName(QStringLiteral("frame"));frame->setGeometry(QRect(0, 0, 601, 241));frame->setFrameShape(QFrame::StyledPanel);frame->setFrameShadow(QFrame::Raised);retranslateUi(QMoviePlayer);QMetaObject::connectSlotsByName(QMoviePlayer);} // setupUivoid retranslateUi(QWidget *QMoviePlayer){QMoviePlayer->setWindowTitle(QApplication::translate("QMoviePlayer", "Form", Q_NULLPTR));} // retranslateUi};namespace Ui {class QMoviePlayer: public Ui_QMoviePlayer {};
} // namespace UiQT_END_NAMESPACE#endif // QMOVIEPLAYERP15136_H
二、创建工程
2.1 工程目录及编译设置
创建一个opencv_qt目录的工程文件,工程组织如下:
opencv_qtbinbuild_vcsrcmain.cppui_QMoviePlayer.hQMoviePlayer.hQMoviePlayer.cppQMoviePlayer.uiCMakeLists.txt #cmake工程vcbuild_2015.bat #编译命令
ui_QMoviePlayer.h和QMoviePlayer.ui就是前面采用designer.exe实现的ui及代码头文件。
CMakeLists.txt文件内容如下,本文给出的有win/linux的痕迹,但是本文只实现了基于vc2015+qt_vc2015+opencv_vc的win编译方式,Linux下本文并没有进行测试,有兴趣的读者可以按该模块调整支持实现(关于opencv的Linux下库编译及调用案例看本专栏其他博文)。qt链接采用了动态库,opencv的基于vc2015编译出来的库本文时预先编译好的(C/C++开发,opencv在win下安装及应用_c++安装opencv库_py_free-物联智能的博客-CSDN博客)。
# CMake 最低版本号要求
cmake_minimum_required (VERSION 3.1.0)
# 项目信息
set(proname "opencv_qt")
project(${proname} VERSION 1.0.0 LANGUAGES CXX)if(WIN32)message(STATUS "windows compiling...")set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")add_definitions(-D_PLATFORM_IS_WINDOWS_-D_CRT_SECURE_NO_WARNINGS-D_WINSOCK_DEPRECATED_NO_WARNINGS# -DZLIB_WINAPI-DUNICODE-D_UNICODE# -DQT_DLL# -DQT_CORE_LIB# -DQT_GUI_LIB# -DQT_WIDGETS_LIB# -D CMAKE_CXX_FLAGS="/utf-8")else(WIN32)message(STATUS "linux compiling...")# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -I/usr/include -L/lib/x86_64-linux-gnu -lpthread -pthread -lm -lrt -ldl -lz -luuid ") #qt需要-fPIC编译指定add_definitions(-D_PLATFORM_IS_LINUX_"-g"# "-std=gnu++0x""-std=c++11""-O2"# "-pipe""-Wno-invalid-source-encoding""-Wdeprecated-declarations""-W""-fPIC""-Wall"# "-Werror"# "-Wshadow"# "-Wformat"# "-Wpointer-arith""-D_REENTRANT"# "-D_USE_FAST_MACRO"# "-Wno-long-long"# "-Wuninitialized"# "-D_POSIX_PTHREAD_SEMANTICS"# "-Wno-unused-parameter""-fexceptions""-DQT_NO_DEBUG""-DDQT_QML_DEBUG")
endif(WIN32)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)if(CMAKE_VERSION VERSION_LESS "3.7.0")set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 创建 EXECUTABLE_OUTPUT_PATH 指向的文件夹
execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${EXECUTABLE_OUTPUT_PATH})set(PROJECT_CUR_DIR .)if(WIN32)
set(QTDIR "D:/workForSoftware/Qt/Qt5.8.0/5.8/msvc2015_64")
else(WIN32)
set(QTDIR "/opt/qt-5.8_static")
endif(WIN32)
message("QTDIR = ${QTDIR}")
set(Qt5_DIR "${QTDIR}/lib/cmake/Qt5")
message("Qt5_DIR = ${Qt5_DIR}")set(CMAKE_AUTOMOC ON)
# set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
#查找需要的Qt库文件,最好每一个库都要写,Qt也会根据依赖关系自动添加
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
cmake_policy(SET CMP0020 NEW)set(CMAKE_INCLUDE_CURRENT_DIR ON) #包含编译目录FILE(GLOB srcfile ${PROJECT_CUR_DIR}/src/*.h ${PROJECT_CUR_DIR}/src/*.cpp ) #加载文件夹下的所有源码文件
LIST(APPEND code_file ${srcfile} ) #变量合并include_directories("${PROJECT_CUR_DIR}""${PROJECT_CUR_DIR}/src""${PROJECT_CUR_DIR}/../../opencv_vc/include""${QTDIR}/include""${QTDIR}/include/QtCore""${QTDIR}/include/QtGui""${QTDIR}/include/QtWidgets"
)#link 目录
link_directories("${QTDIR}/lib""${PROJECT_CUR_DIR}/../../opencv_VC/x64/vc14/lib"
)message("RESOURCES = ${RESOURCES}")add_executable(${proname} ${code_file} ${RESOURCES} ${RC_FILE} )# 链接指定
set(link_lib Qt5::Core Qt5::Gui Qt5::Widgets
)
if(WIN32)
if (CMAKE_BUILD_TYPE STREQUAL "release")
set(link_lib_opencv opencv_img_hash460.lib opencv_world460.lib
)
else()
set(link_lib_opencv opencv_img_hash460d.lib opencv_world460d.lib
)
endif()
endif(WIN32)target_link_libraries(${proname} ${link_lib}${link_lib_opencv}
)#去除 CMD 窗口
if(WIN32)
message("CMAKE_BUILD_TYPE =${CMAKE_BUILD_TYPE}")
if (CMAKE_BUILD_TYPE STREQUAL "release")
if(MSVC)set_target_properties(${proname} PROPERTIESWIN32_EXECUTABLE YESLINK_FLAGS "/ENTRY:mainCRTStartup")
elseif(CMAKE_COMPILER_IS_GNUCXX)SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
else()message(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)")
endif(MSVC)
endif()endif(WIN32)
vcbuild_2015.bat是为了编译方便创建的一个脚本,读者也可以按该脚本命令手动编译。
md build_vc
cd ./build_vc
@REM 单独编译时可能需要独立设置环境变量
if [%vccompilerversion%] EQU [] ( set vccompilerversion="Visual Studio 14 2015 Win64" )@REM 工程配置
cmake -G %vccompilerversion% .. -DCMAKE_BUILD_TYPE=debug
@REM 编译
cmake --build . --config debug@REM 工程配置
cmake -G %vccompilerversion% .. -DCMAKE_BUILD_TYPE=release
@REM 编译
cmake --build . --config releasecd ..
2.2 源码设计
下来看看源码如何实现视频读取与播放的。
QMoviePlayer.h内容如下,该头文件定义了一个窗口类型,该窗口显示部分来自于前面的UI设计“Ui::QMoviePlayer ui”,定义了“cv::VideoCapture m_cap”用来捕获视频内容:
#ifndef _QMOVIEPLAYER_H_
#define _QMOVIEPLAYER_H_#include "ui_QMoviePlayer.h"
#include <QtWidgets/QWidget>
#include <QImage>#include <opencv2/opencv.hpp>
#include <string>
using namespace std;QT_BEGIN_NAMESPACE
class QPaintEvent;
class QTimer;
QT_END_NAMESPACEclass QMoviePlayer : public QWidget
{Q_OBJECTpublic:QMoviePlayer(QWidget *parent = NULL);virtual ~QMoviePlayer(){;}bool open( string file );public slots:void nextFrame();private:void paintEvent( QPaintEvent* q);void _copyImage( void);private:Ui::QMoviePlayer ui; //ui界面cv::VideoCapture m_cap; //opencv的视频读取及捕获图像实现QImage m_qt_img;cv::Mat m_cv_img; //图像缓存矩阵QTimer* m_timer;
};#endif //_QMOVIEPLAYER_H_
QMoviePlayer.cpp内容如下,open函数用于打开一个视频文件,并通过QTimer对象来定期读取帧图像数据,nextFrame用于读取图像数据并更新到窗口显示;_copyImage函数是opencv与QT结合的关键,它将opencv捕获的图像m_cv_img转换为qt的图像m_qt_img,这样才能将图片按qt方式刷新到窗口显示:
#include "QMoviePlayer.h"#include <QPainter>
#include <QTimer>QMoviePlayer::QMoviePlayer(QWidget *parent): QWidget(parent)
{ui.setupUi( this );
}bool QMoviePlayer::open( string file)
{if( !m_cap.open( file)) return false;// If we opened the file, set up everything now://m_cap.read( m_cv_img );m_qt_img = QImage(QSize( m_cv_img.cols,m_cv_img.rows),QImage::Format_RGB888);ui.frame->setMinimumSize( m_qt_img.width(),m_qt_img.height());ui.frame->setMaximumSize( m_qt_img.width(),m_qt_img.height());_copyImage();m_timer = new QTimer( this );connect(m_timer, SIGNAL( timeout()), this, SLOT( nextFrame()) );m_timer->start( 1000.0 / m_cap.get( cv::CAP_PROP_FPS));return true;
}void QMoviePlayer::nextFrame()
{// Nothing to do if capture object is not open//if( !m_cap.isOpened()) return;m_cap.read(m_cv_img);if(m_cv_img.empty()) return;_copyImage();this->update();
}void QMoviePlayer::paintEvent( QPaintEvent* e )
{QPainter painter( this );painter.drawImage( QPoint( ui.frame->x(),ui.frame->y()),m_qt_img);
}void QMoviePlayer::_copyImage( void)
{// Copy the image data into the Qt QImage//cv::Mat cv_header_to_qt_image(cv::Size(m_qt_img.width(),m_qt_img.height()),CV_8UC3,m_qt_img.bits());cv::cvtColor(m_cv_img,cv_header_to_qt_image, cv::COLOR_BGR2RGB);
}
main.cpp文件内容如下,就是qt程序启动后,调用前面定义的QMoviePlayer对象,读取视频文件(argv[1])及刷新显示:
#include <QApplication>
#include <QMoviePlayer.h>int main( int argc, char* argv[])
{QApplication app( argc, argv);QMoviePlayer mp;mp.open( argv[1]);mp.show();return app.exec();
}
三、编译及测试
3.1 程序编译
进入opencv_qt目录
运行vcbuild_2015.bat,执行大致如下(本文是直接在vscode命令窗口执行):
3.2 程序运行
进入opencv_qt\bin\Debug,启动命令窗口运行是缺失qt动态库的,因此将qt动态库拷贝到该目录下运行,注意debug和release的区别,为了方便,本文把需要运行的视频文件也拷贝到了该目录下,如下图:
启动命令窗口,并运行opencv_qt.exe
程序启动,加载视频进行播放,如果不能正常播放,可以通过日志输出信息进行定位排查。
相关文章:

C/C++开发,opencv与qt结合播放视频
目录 一、qt_ui创建 1.1 ui设置 1.2 ui及代码输出保存 二、创建工程 2.1 工程目录及编译设置 2.2 源码设计 三、编译及测试 3.1 程序编译 3.2 程序运行 首先声明,这是一个OpenCV 3学习文档的案例,但是说明有些过于省略,只有一些简短的代码…...
磁共振图像处理中 fft1c 和 ifft1c 函数的 Python 实现
fft1c 和 ifft1c 是 MRI 图像处理的常用函数。通常使用如下的 Matlab 实现 (Michael Lustig,2005) function res ifft1c(x,dim)% res fft1c(x) % % orthonormal forward 1D FFT %nsize(x,dim); shftzeros(1,5); shft(dim)ceil(n/2);xcirc…...
阿里云国际站香港地域服务器访问延迟丢包的原因及解决方法
阿里云百科有2台香港地域的轻量应用服务器,国内使用发现Ping值延迟丢包严重,从大陆到香港访问是经过国际链路和运营商国际路由节点,会受到到国际链路拥塞,以及运营商出境路由限制,导致无法正常连接或访问某些网站&…...
GULI PART.1
文章目录 1、尚硅谷-谷粒学院1.1、系统功能模块介绍1.2、系统开发方式 2、Mybatis-Plus2.1、什么是 MyBatis?2.2、什么是Mybatis-Plus?2.3、Mybatis-plus 的特性2.4、支持的数据库 3、Mybatis-Plus入门3.1、创建表和数据3.2、创建SpringBoot工程3.3、安装…...

NetApp FAS2750 和 FAS2820:适用于分布式企业和从远程到核心的 FAS
NetApp FAS2750 和 FAS2820:适用于分布式企业和从远程到核心的 FAS 拥有分布式企业和多个办公位置的客户希望使用这些系统进行虚拟化,以及为大型 FAS 和 AFF 系统提供简单且经济高效的备份和灾难恢复。 为什么要从 NetApp FAS 系列中选择一个型号&…...
剑指YOLOv8改进最新MPDIoU损失函数:超越现有多种G/D/C/EIoU,23年7月首发论文,高效准确的边界框回归的损失
💡本篇内容:剑指YOLOv8改进最新MPDIoU损失函数:超越现有多种G/D/C/EIoU,23年7月首发论文,高效准确的边界框回归的损失 💡🚀🚀🚀本博客 改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 💡:重点:该专栏《剑指YOLOv8原创改进》只更新改进 YOLO…...

SQL-每日一题【1070. 产品销售分析 III】
题目 销售表 Sales: 产品表 Product: 编写一个 SQL 查询,选出每个销售产品 第一年 销售的 产品 id、年份、数量 和 价格。 结果表中的条目可以按 任意顺序 排列。 查询结果格式如下例所示: 示例 1: 解题思路 前置知…...

为何押注AI大模型的微软云,业绩增速反而不如谷歌云?
科技云报道原创。 上周微软、谷歌、Meta等国外科技公司相继发布最新财报。作为与人工智能、云计算和数字广告等领域相关的巨头,它们的一举一动都将对市场产生影响,同时也吸引着众多从业者的关注。 在国外三大云巨头中,谷歌云的市场份额长期…...
CDN加速服务的工作原理
CDN(内容分发网络)加速服务是一种用于提高网站和应用性能的技术,通过将内容分发到全球多个节点,使用户可以从就近的节点获取所需内容,从而实现更快的加载速度和更稳定的访问体验。下面详细介绍CDN加速服务的工作原理&a…...
在CSDN学Golang云原生(Kubernetes Service)
一,service的定义与基本用法 在 Kubernetes 中,Service 是一种抽象概念,用于定义一组 Pod 并为它们提供访问入口。通过 Service,您可以将多个 Pod 组合成一个逻辑单元,并使用标签选择器来确定哪些 Pod 属于该 Service…...

【数据结构篇C++实现】- 图
友情链接:C/C系列系统学习目录 文章目录 🚀一、图的基本概念和术语1、有向图和无向图3、基本图和多重图4、完全图5、子图6、连通、连通图和连通分量7、强连通图、强连通分量8、生成树、生成森林9、顶点的度、入度和出度10、边的权和网11、稠密图、稀疏图…...
Sentinel持久化规则
项目中有用到Sentinel,然后需要将Sentinel上配置的规则做持久化(或者初始化),通过改写Sentinel源码实现了需求,下面记录一下实现过程。 如果不知道Sentinel怎么搭,可以看看: 流控平台Sentinel搭建和接入教程_东皋长歌的博客-CSDN博客 一,背景 Sentinel是Alibaba开源…...

list与sort()
运行代码: //list与sort() #include"std_lib_facilities.h" //声明Item类 struct Item {string name;int iid;double value;Item():name(" "),iid(0),value(0.0){}Item(string ss,int ii,double vv):name(ss),iid(ii),value(vv){}friend istre…...

6个月、21天,GoldenDB分布式数据库核心系统落地中移动
近日,2023“鼎新杯”数字化转型应用大赛入围名单公示,山东移动基于GoldenDB分布式数据库的CRM&BOSS核心系统自主创新实践成功入选。该项目是中兴通讯与中国移动在数据库关键领域的又一个合作范例。 核心系统业务量大,分布式转型迫在眉睫 …...

如何正确培养数据思维?
在大数据时代,数据思维已成了每个人的必备品。下面,我们就来了解一下,什么是数据思维。不过要想弄懂什么是数据思维,首先来打破大家对数据的错误认知,数据不仅仅指数字。 1. 数据思维是什么? 百度百科对数…...
JavaScript中的?.和??的用法
1、?.(可选链运算符) 在JavaScript中,"?.“是一种叫做"Optional Chaining”(可选链)的新操作符。它允许我们在访问一个可能为null或undefined的属性或调用一个可能不存在的方法时,避免出现错误…...
Git for linux
<1> linux 安装git sudo apt-get install git-all <2> 创建git,分为两部分,远程网络部分和本地主机部分 远程网路:登录GitHub: Let’s build from here GitHub 注册帐号,创建登录密码,此密码很长&a…...

uniapp小程序,根据小程序的环境版本,控制的显页面功能按钮的示隐藏
需求:根据小程序环境控制控制页面某个功能按钮的显示隐藏; 下面是官方文档和功能实现的相关代码: 实现上面需要,用到了uni.getAccountInfoSync(): uni.getAccountInfoSync() 是一个 Uniapp 提供的同步方法,…...

kotlin 编写一个简单的天气预报app(二)增加搜索城市功能
增加界面显示openweathermap返回的信息。 在activity_main.xml里增加输入框来输入城市,在输入款旁边增加搜索按钮来进行查询。 然后原来显示helloworld的TextView用来显示结果。 1. 增加输入城市名字的EditText <EditTextandroid:id"id/editTextCity"…...

【分布鲁棒、状态估计】分布式鲁棒优化电力系统状态估计研究[几种算法进行比较](Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...

计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...

倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...

向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...