opencv c++ Mat CUDA的编译与使用

news2025/1/12 23:14:44

Mat

构造函数

cv::Mat img ; //默认 定义了一个Mat
img = cv::imread("image.jpg");//除了直接读取,还有通过大小构造等

cv::Mat img = cv::imread("image.png", IMREAD_GRAYSCALE);
cv::Mat img_novel = img;

转换 Mat::convertTo(Mat& m, int rtype, double alpha=1, double beta=0)

  • OpenCV中Mat数据类型及相互转换 CV_8U转为CV_16U

转到数组

// https://www.cnblogs.com/xiaoxiaoyibu/p/9491858.html#
//动态创建二维数组,row行col列
    int **La = new int *[row];
    for (int i = 0; i < row; i ++){
        La[i] = new int[col];
    }
    // 循环二维数组和mat,并将mat对应值赋给二维数组对应值,
    for (int i = 0; i < row; i ++){
        for (int j = 0; j < col; j ++){
            La[i][j] = mat.at<uchar>(i, j);
        }
    }
    // 释放分配空间 (直接创建在栈上double La[row][col];就不用delete了)
    for (int i = 0; i < row; i ++){
        delete []La[i];
    }
    delete [] La;
  • cv::Mat的许多操作文档

转到std::vector(注:这个例子将二维图像.reshape(0, 1))

//https://book.mynavi.jp/support/pc/opencv2/c3/opencv_mat.html#cv-vec
#include <iostream>
#include <opencv2/core/core.hpp>

#define OPENCV_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#define OPENCV_VERSION_CODE OPENCV_VERSION(CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION)

int
main(int argc, char *argv[])
{
   cv::Mat m1 = (cv::Mat_<double>(3,3) << 1, 2, 0, 3, 1, 4, 1, 2, 1);
   std::vector<double> v1;

   // Mat -> vector
   m1 = m1.reshape(0, 1); // 1行の行列に変形
#if OPENCV_VERSION_CODE<OPENCV_VERSION(2,3,0)
   m1.copyTo<double>(v1); // データをコピー
#else
   m1.copyTo(v1); // データをコピー
#endif

   std::cout << "m1=" << m1 << std::endl << std::endl;
   for(std::vector<double>::iterator it=v1.begin(); it!=v1.end(); ++it)
     std::cout << *it << ", ";
   std::cout << std::endl;
   
   // vector -> Mat
   cv::Mat m2(v1); // データを共有
   cv::Mat m3(v1, true); // データをコピー
}
  • 还可以去参考一下这个文章
std::vector<uchar> array;
if (mat.isContinuous()) {
  // array.assign(mat.datastart, mat.dataend); // <- has problems for sub-matrix like mat = big_mat.row(i)
  array.assign(mat.data, mat.data + mat.total()*mat.channels());
} else {
  for (int i = 0; i < mat.rows; ++i) {
    array.insert(array.end(), mat.ptr<uchar>(i), mat.ptr<uchar>(i)+mat.cols*mat.channels());
  }
}

操作

  • 操作的官方手册

比如:

cv::Mat中最值和均值的求解

在这里插入图片描述

保存mat为图片

		vector<int> compression_params;//可选参数
		compression_params.push_back(IMWRITE_PNG_COMPRESSION); //PNG格式图像压缩标志
		compression_params.push_back(9); //设置最高压缩质量
		bool result = imwrite("alpha.png", _frame2, compression_params);

制作掩膜图像

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/video.hpp>
#include <opencv2/highgui/highgui_c.h>//https://blog.csdn.net/weixin_44312186/article/details/89000922
using namespace cv;
using namespace std;

void colorReduce(Mat& image, int div)// 这里使用了Mat_instance.at<typename>(i,j) https://www.cnblogs.com/ybqjymy/p/15935894.html
{
	for (int i = 0; i<image.rows; i++)
	{
		for (int j = 0; j<image.cols; j++)
		{
			if (image.at<Vec3b>(i, j)[0] - 0 != 0) {
				image.at<Vec3b>(i, j)[0] = 255;
				image.at<Vec3b>(i, j)[1] = 255;
				image.at<Vec3b>(i, j)[2] = 255;
			}
			//cout<< image.at<Vec3b>(i, j)[0]-0 << endl;//灰度图像元素类型为<uchar>, 彩色图像元素类型为<cv::Vec3b>
		}
	}

	bool result = imwrite("hahaah.png", image);
}

int main(int argc, char** argv) {
	Mat src = imread("C:/Users/admin/Desktop/mask.jpg"); 
	colorReduce(src, 3);
	
	waitKey(0);
	destroyAllWindows();
	return 0;
}

Mat矩阵相乘相关

一个掩膜的例子:
	Mat A = imread("C:/Users/admin/Pictures/mask.jpg");
	Mat B = imread("C:/Users/admin/Pictures/fm.png");
	Mat C = A.mul(B);
	imshow("输入窗口", C);

C++ Opencv split()通道分离函数 merge()通道合并函数 使用操作详解

split(const Mat &src,//输入图像 Mat* mbegin//输出图像的数组)

C++ opencv之图像直方图(calcHist)

绘制

cv::Point   CvPoint:表示一个坐标为整数的二维点,是一个包含integer类型成员x和y的简单结构体。
cv::scalar   表示四个元素地向量 Scalar(a,b,c) ;//a =blue,b=green,c=red表示RGB的三个通道
  • 简单几何
cv::line 线
cv::rectangle 矩形
cv::circle ⚪

CUDA编译

需要有GPU硬件

在这里插入图片描述

需要的源代码 opencv 编译好的build和source(用source部分) + opencv扩展模块的代码

  • opencv扩展模块
    在这里插入图片描述

Cmake编译一下源码,当然官方有编译的教程(并且还有参数细节):

  • 注:直接选中额外模块的源代码是无法编译的
    在这里插入图片描述

  • 这个教程挺详细的,

  • 这个版本是在04:38 时有额外路径的选项,和这个文字教程一样,stackoverflow的英文教程

  • 还有直接建议复制源码过去的Pasted the modules I want from opencv_contrib into opencv/modules.

在这里插入图片描述

  • 在cmake-gui,先选择源码与目标路径

在这里插入图片描述

  • config选项

在这里插入图片描述

  • 设置:OPENCV_EXTRA_MODULES_PATH

在这里插入图片描述

  • 勾选与cuda有关的

在这里插入图片描述

  • 再次点击config

在这里插入图片描述

  • 好多这个错误
=======================================================================
  Couldn't download files from the Internet.
  Please check the Internet access on this host.
=======================================================================

CMake Warning at cmake/OpenCVDownload.cmake:248 (message):
  IPPICV: Download failed: 6;"Couldn't resolve host name"

  For details please refer to the download log file:

  C:/Users/admin/Documents/Visual Studio
  2015/Projects/opencv-4.6.0-vc14_vc15/opencv/build/CMakeDownloadLog.txt

Call Stack (most recent call first):
  3rdparty/ippicv/ippicv.cmake:37 (ocv_download)
  cmake/OpenCVFindIPP.cmake:259 (download_ippicv)
  cmake/OpenCVFindLibsPerf.cmake:12 (include)
  CMakeLists.txt:733 (include)
  • 解决 IPPICV: Downloading ippicv_2020_win_intel64_20191018_general.zip from https://raw.githubusercontent.com/opencv/opencv_3rdparty/a56b6ac6f030c312b2dce17430eef13aed9af274/ippicv/ippicv_2020_win_intel64_20191018_general.zip

  • 新增的是关于contribute模块的

  • 在这里插入图片描述

  • 继续config

  • 在这里插入图片描述

  • 最后generate

  • 在这里插入图片描述

  • 有错误手动下载
    在这里插入图片描述

  • 双击 C:\Users\admin\Documents\Visual Studio 2015\Projects\opencv-4.6.0-vc14_vc15\opencv\build\OpenCV.sln

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 然后下边的INSTALL生成

在这里插入图片描述

  • C:\Users\admin\Documents\Visual Studio 2015\Projects\opencv-4.6.0-vc14_vc15\opencv\build\install
  • 就可以将以下bin加到环境变量中了

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 将C:\Users\admin\Documents\Visual Studio 2015\Projects\opencv-4.6.0-vc14_vc15\opencv\build\install\x64\vc14\bin加到path
    在这里插入图片描述

添加链接描述

简单使用

  • cuda的简单使用
  • 设置完重启就不会有这个错误了
    在这里插入图片描述

GpuMat cv::gpu::GpuMat(在Python是cv2.cuda_GpuMat)

  • 主要看的这个,略微修改与注释
  • 官方文档

upload+download()

#include <opencv2/highgui.hpp>
#include <opencv2/cudaimgproc.hpp>
 
cv::Mat img = cv::imread("image.png", IMREAD_GRAYSCALE);
cv::cuda::GpuMat dst, src;
src.upload(img);
 
cv::Ptr<cv::cuda::CLAHE> ptr_clahe = cv::cuda::createCLAHE(5.0, cv::Size(8, 8));
ptr_clahe->apply(src, dst);
 
cv::Mat result;
dst.download(result);
 
cv::imshow("result", result);
cv::waitKey();
# python 实现
img = cv2.imread("image.png", cv2.IMREAD_GRAYSCALE)
src = cv2.cuda_GpuMat()
src.upload(img)
 
clahe = cv2.cuda.createCLAHE(clipLimit=5.0, tileGridSize=(8, 8))# 使用对比度受限自适应直方图均衡化来均衡灰度图像的直方图。  https://docs.opencv.org/3.4/db/d79/classcv_1_1cuda_1_1CLAHE.html
dst = clahe.apply(src, cv2.cuda_Stream.Null())# 使用对比度受限自适应直方图均衡化来均衡灰度图像的直方图 https://docs.opencv.org/4.x/d6/db6/classcv_1_1CLAHE.html
 
result = dst.download()
 
cv2.imshow("result", result)
cv2.waitKey(0)

使用多GPU 略

打开视频流(这没有用到cuda)

// init video capture with video
VideoCapture capture(videoFileName);
if (!capture.isOpened())
{
    // error in opening the video file
    cout << "Unable to open file!" << endl;
    return;
}
 
// get default video FPS
double fps = capture.get(CAP_PROP_FPS);
 
// get total number of video frames
int num_frames = int(capture.get(CAP_PROP_FRAME_COUNT));
  • python实现
# init video capture with video
cap = cv2.VideoCapture(video)
 
# get default video FPS
fps = cap.get(cv2.CAP_PROP_FPS)
 
# get total number of video frames
num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)

读取视频(这里我跳过了源文章地大段基本c++方法地解释)

  • 请注意,我们使用相同的 CPU 函数来读取和调整大小,但将结果上传到cv::cuda::GpuMat (cuda_GpuMat)实例:
// resize frame
cv::resize(frame, frame, Size(960, 540), 0, 0, INTER_LINEAR);
 
// convert to gray
cv::cvtColor(frame, previous_frame, COLOR_BGR2GRAY);
 
// upload pre-processed frame to GPU
cv::cuda::GpuMat gpu_previous;
gpu_previous.upload(previous_frame);
 
// declare cpu outputs for optical flow
cv::Mat hsv[3], angle, bgr;
 
// cv::cuda::GpuMat声明  declare gpu outputs for optical flow
cv::cuda::GpuMat gpu_magnitude, gpu_normalized_magnitude, gpu_angle;
cv::cuda::GpuMat gpu_hsv[3], gpu_merged_hsv, gpu_hsv_8u, gpu_bgr;
 
// set saturation to 1
hsv[1] = cv::Mat::ones(frame.size(), CV_32F);
gpu_hsv[1].upload(hsv[1]);
  • python实现
# proceed if frame reading was successful
if ret:
    # resize frame
    frame = cv2.resize(previous_frame, (960, 540))
 
    # upload resized frame to GPU  --- 多了这一段
    gpu_frame = cv2.cuda_GpuMat()
    gpu_frame.upload(frame)
 
    # convert to gray  ---- 没变
    previous_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    # upload pre-processed frame to GPU
    gpu_previous = cv2.cuda_GpuMat()
    gpu_previous.upload(previous_frame)
 
    # create gpu_hsv output for optical flow  ----- hsv = np.zeros_like(frame, np.float32)
    gpu_hsv = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC3)
    gpu_hsv_8u = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_8UC3)
 
    gpu_h = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC1)
    gpu_s = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC1)
    gpu_v = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC1)
 
    # set saturation to 1   ----  hsv[..., 1] = 1.0
    gpu_s.upload(np.ones_like(previous_frame, np.float32))

读取视频帧

while (true)//我删除了计时部分
{

    // capture frame-by-frame
    capture >> frame;if (frame.empty())break;
 
    // 增加了上传
    cv::cuda::GpuMat gpu_frame;  gpu_frame.upload(frame);
 
    // resize frame
    cv::cuda::resize(gpu_frame, gpu_frame, Size(960, 540), 0, 0, INTER_LINEAR);//类似 cv::resize(frame, frame, Size(960, 540), 0, 0, INTER_LINEAR);
 
    // 这里也类似cv::Mat换成 cv::cuda::GpuMat,cv::cvtColor换成cv::cuda::cvtColor
    cv::cuda::GpuMat gpu_current;
    cv::cuda::cvtColor(gpu_frame, gpu_current, COLOR_BGR2GRAY);

计算密集光流

// calculate optical flow
cv::Mat flow;
calcOpticalFlowFarneback(previous_frame, current_frame, flow, 0.5, 5, 15, 3, 5, 1.2, 0);

// create optical flow instance
Ptr<cuda::FarnebackOpticalFlow> ptr_calc = cuda::FarnebackOpticalFlow::create(5, 0.5, false, 15, 3, 5, 1.2, 0);
// calculate optical flow
cv::cuda::GpuMat gpu_flow;
ptr_calc->calc(gpu_previous, gpu_current, gpu_flow);

可视化前处理

// start post-process timer
auto start_post_time = high_resolution_clock::now();
 
// split the output flow into 2 vectors
cv::Mat flow_xy[2], flow_x, flow_y;
split(flow, flow_xy);
 
// get the result
flow_x = flow_xy[0];
flow_y = flow_xy[1];
 
// convert from cartesian to polar coordinates
cv::cartToPolar(flow_x, flow_y, magnitude, angle, true);
// normalize magnitude from 0 to 1
cv::normalize(magnitude, normalized_magnitude, 0.0, 1.0, NORM_MINMAX);
// get angle of optical flow
angle *= ((1 / 360.0) * (180 / 255.0));
 
// build hsv image
hsv[0] = angle;
hsv[2] = normalized_magnitude;
merge(hsv, 3, merged_hsv);
 
// multiply each pixel value to 255
merged_hsv.convertTo(hsv_8u, CV_8U, 255);
 
// convert hsv to bgr
cv::cvtColor(hsv_8u, bgr, COLOR_HSV2BGR);
 
// update previous_frame value
previous_frame = current_frame;
// start post-process timer
auto start_post_time = high_resolution_clock::now();
 
// split the output flow into 2 vectors
cv::cuda::GpuMat gpu_flow_xy[2];
cv::cuda::split(gpu_flow, gpu_flow_xy);
 
// convert from cartesian to polar coordinates
cv::cuda::cartToPolar(gpu_flow_xy[0], gpu_flow_xy[1], gpu_magnitude, gpu_angle, true);
 
// normalize magnitude from 0 to 1
cv::cuda::normalize(gpu_magnitude, gpu_normalized_magnitude, 0.0, 1.0, NORM_MINMAX, -1);
 
// get angle of optical flow
gpu_angle.download(angle);
angle *= ((1 / 360.0) * (180 / 255.0));
 
// build hsv image
gpu_hsv[0].upload(angle);
gpu_hsv[2] = gpu_normalized_magnitude;
cv::cuda::merge(gpu_hsv, 3, gpu_merged_hsv);
 
// multiply each pixel value to 255
gpu_merged_hsv.cv::cuda::GpuMat::convertTo(gpu_hsv_8u, CV_8U, 255.0);
 
// convert hsv to bgr
cv::cuda::cvtColor(gpu_hsv_8u, gpu_bgr, COLOR_HSV2BGR);
 
// send original frame from GPU back to CPU
gpu_frame.download(frame);
 
// send result from GPU back to CPU !!!!!!
gpu_bgr.download(bgr);
 
// update previous_frame value
gpu_previous = gpu_current;

可视化(不变)

// visualization
imshow("original", frame);
imshow("result", bgr);
int keyboard = waitKey(1);
if (keyboard == 27)
    break;

CG

  • opencv中文war3school

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
cuda下载

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • file:///C:/Program%20Files/NVIDIA%20GPU%20Computing%20Toolkit/CUDA/v10.2/doc/html/index.html

  • C:\ProgramData\NVIDIA Corporation\CUDA Samples\v10.2

  • 安装完重启电脑
    在这里插入图片描述

  • 下载需要注册,我用qq邮箱注册了一个账号,才下载下来
    cudnn
    将bin、include、lib文件夹里的文件复制到CUDA安装路径C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2 同名文件夹即可。

learnopencv

添加链接描述
https://github.com/spmallick/learnopencv/blob/master/README.md

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

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

相关文章

【自学Java】Java方法

Java方法 Java方法教程 在 Java 语言 中&#xff0c;方法就是一段可重复调用的代码段。在平时开发直接交流中&#xff0c;也有一些同学喜欢把方法叫做函数&#xff0c;这两个其实是一个概念。 Java语言方法详解 语法 public void fun(Object param1,...){//do something }…

多线程与高并发(四)

【Exchanger】&#xff1a; package Ten_Class.t04.no139;import java.util.concurrent.Exchanger;public class T12_TestExchanger {static Exchanger<String> exchanger new Exchanger<>();public static void main(String[] args) {new Thread(() -> {Stri…

实验二十四 策略路由配置

实验二十四 策略路由配置实验要求&#xff1a; 某企业通过路由器AR1连接互联网&#xff0c;由于业务儒要&#xff0c;与两家运营商ISPA和ISPB相连。 企业网内的数据流从业务类型上可以分为两类&#xff0c; 一类来自于网络172.16.0.0/16&#xff0c;另 一类 来自于网络172.17.0…

百趣代谢组学分享:黑木耳多糖对小鼠肠道微生物及代谢表型的影响

文章标题&#xff1a;Effects of Auricularia auricula Polysaccharides on Gut Microbiota and Metabolic Phenotype in Mice 发表期刊&#xff1a;Foods 影响因子&#xff1a;5.561 作者单位&#xff1a;西北大学 百趣提供服务&#xff1a;发现代谢组学Standard-亲水版、1…

dataCompare大数据对比之异源数据对比

在从0到1介绍一下开源大数据比对平台dataCompare 已经详细介绍了dataCompare 的功能&#xff0c;目前dataCompare 已经实现同源数据的对比 一、dataCompare 现有核心功能如下&#xff1a; (1)数量级对比 (2)一致性对比 (3)差异case 自动发现 (4)定时调度自动对比数据 二、…

【个人解答版】笔试题-2023禾赛-FPGA

题目背景 笔试时间&#xff1a;2022.06.22应聘岗位&#xff1a;FPGA开发工程师 题目评价 难易程度&#xff1a;★★☆☆☆知识覆盖&#xff1a;★☆☆☆☆超纲范围&#xff1a;☆☆☆☆☆值得一刷&#xff1a;★☆☆☆☆ 文章目录1. 使用最少的电路实现二分频&#xff0c;给出…

《机器学习实战》chap1 机器学习概览

《机器学习实战》chap1 机器学习概览 Chap1 The Machine Learning Landscape 这本书第三版也已经出版了:https://github.com/ageron/handson-ml3 Hands-on Machine Learning with Scikit-Learn,Keras & TensorFlow 引入 很早的应用&#xff1a;光学字符识别(OCR&#xff0…

远程办公之怎样在外网登录在线答题网站

很多学校或企业因为教学、测试需要&#xff0c;为学生或员工提供了在线答题平台网站&#xff0c;但弊端是这种在线答题平台只能在校内或在企业内网访问使用&#xff0c;在外网是无法登录访问的。在无公网Ip服务器上部署的web&#xff0c;默认情况下只能内网访问&#xff0c;公网…

TLE4943C/CH505C轮速传感器芯片的输出协议介绍

Infineon公司的TLE4943是一款集成式有源磁场传感器&#xff0c;适用于基于霍尔技术的车轮速度应用。它的基本功能是测量磁极轮或铁磁齿轮的速度。它具有使用AK协议进行通信的两线电流接口。该协议除了提供速度信号外&#xff0c;还提供其他信息&#xff0c;如车轮旋转方向和气隙…

java安装教程-windows

检查是否已经安装过jav打开cmd命令窗口 输入 java -v下载java安装包网址&#xff1a;https://www.oracle.com/java/technologies/downloads/安装java双击运行程序jdk-19_windows-x64_bin.exe&#xff0c;点击下一步进行安装可以更改安装路径&#xff0c;注意安装路径不能有中文…

【TypeScript】TS类型守卫(六)

&#x1f431;个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️作者简介&#xff1a;前端领域新星创作者、华为云享专家、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff…

独立开发变现周刊(第86期):月收入4000美元的日程规划器

分享独立开发、产品变现相关内容&#xff0c;每周五发布。目录1、NotionReads: 在Notion中管理你的阅读书籍2、Zaap.ai: 面向创作者的一站式工具3、microfeed: 开源的可自我托管的轻量级内容管理系统(CMS)4、Reactive Resume&#xff1a;一个免费的开源简历生成器5、一个月收入…

2019年1月政企终端安全态势分析报告

声明 本文是学习2019年1月政企终端安全态势分析报告. 下载地址 http://github5.com/view/55037而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 漏洞利用病毒攻击政企分析 奇安信终端安全实验室监测数据显示&#xff0c;2019年4月&#xff0c;有6.7%的…

JavaScript中的元编程

紧接上回&#xff0c;伴随着Reflect&#xff0c;Proxy降世&#xff0c;为js带来了更便捷的元编程&#xff01; 什么是元编程&#xff1f;这词第一次听&#xff0c;有点懵&#xff0c;好像有点高级&#xff0c;这不得学一下装…进自己的知识库 概念 元编程是一种编程技术&…

【数据结构与算法】Collection接口迭代器

Java合集框架 数据结构是以某种形式将数据组织在一起的合集&#xff08;collection&#xff09;。数据结构不仅存储数据&#xff0c;还支持访问和处理数据的操作 在面向对象的思想里&#xff0c;一种数据结构也被认为是一个容器&#xff08;container&#xff09;或者容器对象…

【MySQL】MySQL表的七大约束

序号系列文章1【MySQL】MySQL介绍及安装2【MySQL】MySQL基本操作详解3【MySQL】MySQL基本数据类型4【MySQL】MySQL表的七大约束文章目录MySQL表的约束1&#xff0c;默认约束2&#xff0c;非空约束3&#xff0c;唯一约束4&#xff0c;主键约束5&#xff0c;自增约束6&#xff0c…

详细分析单调栈,及正确性证明

什么是单调栈 对于一个数组&#xff0c;需要对每个位置生成&#xff0c;左右两边离它最近的&#xff0c;比它小&#xff08;或比它大&#xff09;的位置在哪 例如&#xff1a; 如果对每个位置都遍历下左右两边&#xff0c;找到第一个比它小的位置&#xff0c;就是O(N ^ 2)的…

IPv6 时代如何防御 DDoS 攻击?

在互联网世界&#xff0c;每台联网的设备都被分配了一个用于标识和位置定义的 IP 地址。20 世纪 90 年代以来互联网的快速发展&#xff0c;联网设备所需的地址远远多于可用 IPv4 地址的数量&#xff0c;导致了 IPv4 地址耗尽。因此&#xff0c;协议 IPv6 的开发和部署已经刻不容…

从第三方平台导出大数据量本地Excel怎么解决性能问题?

对于日常需要做分析的我们来说&#xff0c;周期性需要从第三方系统导出数据&#xff0c;日积月累数据量越来愈大&#xff0c;由开始的几百条数据慢慢增至十几万甚至百万级的数据量&#xff0c;在本地Excel直接做分析汇总老是卡顿等半天&#xff0c;效率日益低下&#xff0c;每天…

连续四年发布科技趋势预测,他们在探索中国科技的“主干道”

&#xff0c;*本文配图由百度飞桨文心一格提供AI绘画技术支持。古希腊流传着一句谚语&#xff1a;智慧不仅是能够明察眼前&#xff0c;更要能够预测未来。身处科技界&#xff0c;一到年底年初我们就会看到各种各样的趋势预测。这些预测五花八门&#xff0c;神奇多变。但大多数科…