OpenCV Mat实例详解 六

         本文将接着OpenCV Mat实例详解继续介绍OpenCV Mat类的操作符及公有成员函数。

 Mat &  operator =

        Mat & operator= (const Mat &m)

        将一个Mat对象赋值个另一个Mat对象。

        Mat & operator= (const MatExpr &expr)

         将一个Mat表达式值赋值给Mat对象

         Mat &  operator= (const Scalar &s)

        将一个标量赋值给Mat对象。

        Mat & operator= (Mat &&m)

       是一个移动赋值操作符,它允许你将一个 Mat 对象的资源“移动”到另一个 Mat 对象,而不是进行传统的拷贝。这样做可以节省大量时间和内存,因为资源只是在指针级别上被转移,而不是实际的数据。

        新建一个控制台应用程序,来演示上面赋值操作符的应用方法,在程序中加入如下代码:

// OpenCVMatTest6.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{//**********Example for operator = Mat src = imread("1.png");if (src.empty()){cout << "Cann't open the image!" << endl;return -1;}Mat dst = src;imshow("Dst", dst);Mat m1 = (Mat_<uchar>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);Mat m2 = (Mat_<uchar>(3, 3) << 10, 11, 12, 13, 14, 15, 16, 17, 18);MatExpr me = m1.mul(m2, 1);Mat dst1 = me;cout << "dst1:" << endl;cout << dst1 << endl;Mat dst2(5, 5, CV_8UC3);dst2 = Scalar(255, 0, 0);cout << "dst2:" << endl;cout << dst2 << endl;Mat dst3 = move(src);imshow("Dst3", dst3);waitKey(0);return 1;
}

试运行,结果如下: 

void pop_back (size_t nelems=1)

从Mat对象矩阵的底部移除元素,该方法从矩阵底部删除一行或多行。

nelems 移除元素的行数。

void push_back (const _Tp &elem)

将元素添加到Mat对象数据矩阵的底部。这些方法将一个或多个元素添加到矩阵的底部。它们模拟STL向量类的相应方法。当 elem 为 Mat 时,其类型和列数必须与容器矩阵中的相同。

elem 添加的元素

将上面示例程序中无关的代码注释掉,插入新代码来演示上面两个函数的用法,插入的代码如下:

//**********Example for pop_back(),push_back()
Mat m1 = (Mat_<uchar>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
m1.pop_back(1);
cout << "m1 rows after pop back:" << endl;
cout << m1.rows << endl;Mat m2 = (Mat_<uchar>(1, 3) << 11, 11, 11);
m1.push_back(m2);
cout << "m1 rows after push back:" << endl;
cout << m1.rows << endl;
cout << "m1 after push back:" << endl;
cout << m1 << endl;

试运行,结果如下:

数据指针ptr

uchar * ptr (int i0=0)

const uchar *  ptr (int i0=0) const

返回指向指定矩阵行的指针。这些方法返回 uchar* 或指向指定矩阵行的类型化指针。上面两个函数的区别在与接受的参数不同

i0 从0开始的行索引。

重载函数:

        为方便起见OpenCV Mat提供l了很多重载成员函数。它与上述函数的不同之处仅在于它接受的参数。

uchar *  ptr (int row, int col)

const uchar *  ptr (int row, int col) const

uchar *  ptr (int i0, int i1, int i2)

const uchar * ptr  (int i0, int i1, int i2) const

uchar *  ptr (const int *idx)

const uchar *   ptr (const int *idx) const

template<int n>  _Tp * ptr (const Vec< int, n > &idx)

template<int n>   const _Tp *  ptr (const Vec< int, n > &idx) const

template<typename _Tp > _Tp * ptr (int i0=0)

template<typename _Tp >  const _Tp * ptr (int i0=0) const

template<typename _Tp > _Tp *  ptr (int row, int col)

template<typename _Tp > const _Tp * ptr (int row, int col) const

template<typename _Tp > _Tp *  ptr (int i0, int i1, int i2)

template<typename _Tp > const _Tp * ptr (int i0, int i1, int i2) const

template<typename _Tp > _Tp * ptr (const int *idx)

template<typename _Tp > const _Tp * ptr (const int *idx) const

template<typename _Tp , int n> _Tp * ptr (const Vec< int, n > &idx)

template<typename _Tp , int n> const _Tp * ptr (const Vec< int, n > &idx) const

将上面示例程序中无关的代码注释掉,插入新代码来演示上面函数的用法,插入的代码如下:

//*********Example for ptr//uchar* ptr(int i0 =0), cost uchar* ptr(int i0 =0) const
Mat m1(3, 3, CV_8UC1);
for (size_t i = 0; i <3; i++)
{int j = 0;while (j<3){uchar* puchar= m1.ptr(i);puchar[j] = j;j++;}
}
cout << "m1:" << endl;
for (size_t i = 0; i < 3; i++)
{int j = 0;while (j < 3){uchar* puchar = m1.ptr(i);cout << (int)puchar[j] << "  ";j++;}cout << endl;
}//uchar* ptr(int row, int col), const uchar* ptr(int row, int col) const
Mat m2(3, 3, CV_8UC1);for (size_t i = 0; i < 3; i++)
{int j = 0;while (j < 3){uchar* puchar = m2.ptr(i, j);*puchar = j + 1;j++;}
}
cout << "m2:" << endl;
for (size_t i = 0; i < 3; i++)
{int j = 0;while (j < 3){uchar* puchar = m2.ptr(i, j);cout << (int)*puchar << "  ";j++;}cout << endl;
}//ucahr* ptr(int i0, int i1, int in2), const ucahr* ptr(int i0, int i1, int in2) const
Mat m3(5, 5, CV_8UC3);
for (size_t i = 0; i < 5; i++)
{for (size_t j = 0; j < 5; j++){int k = 0;while (k < 3){uchar* puchar = m3.ptr((i, j), k);*puchar = k;k++;}}
}
cout << "m3:" << endl;
for (size_t i = 0; i < 5; i++)
{for (size_t j = 0; j < 5; j++){int k = 0;while (k < 3){uchar* puchar = m3.ptr((i, j), k);cout <<(int)*puchar << "  ";k++;}}cout << endl;
}//uchar* ptr(onst int* idx), const uchar* ptr(onst int* idx) const
Mat m4(5, 5, CV_8UC1);
int idx[] = {0,1,2,3,4};for (size_t i = 0; i < 5; i++)
{uchar* puchar = m4.ptr(idx);int j = 0;while(j < 5){puchar[j] = j;j++;}puchar++;
}
cout << "m4:" << endl;
for (size_t i = 0; i < 5; i++)
{uchar* puchar = m4.ptr(idx);int j = 0;while (j < 5){cout << (int)puchar[j] << " ";j++;}cout << endl;puchar++;
}//​template<int n> _Tp* ptr (const Vec< int, n > &idx), template<int n> ​_Tp* ptr (const Vec< int, n > &idx),​ const _Tp* ptr (const Vec< int, n > &idx) const​
Mat m5(5, 5, CV_8UC1);
Vec<int, 5> vec1 = {0,1,2,3,4};for (size_t i = 0; i < 5; i++)
{uchar* puchar = m5.ptr(vec1);int j = 0;while (j < 5){puchar[j] = 255 -j;j++;}puchar++;
}
cout << "m5:" << endl;
for (size_t i = 0; i < 5; i++)
{uchar* puchar = m5.ptr(vec1);int j = 0;while (j < 5){cout <<(int) puchar[j] << "  ";j++;}puchar++;cout << endl;
}//​template<typename _Tp > _Tp* ptr (int i0 = 0),​ template<typename _Tp >  const _Tp* ptr (int i0 = 0) const
Mat M6(5, 5, CV_8UC1);
for (size_t i = 0; i < 5; i++)
{uchar* puchar = M6.ptr(i);int j = 0;while (j < 5){puchar[j] = 127 - j;j++;}puchar++;
}
cout << "m6:" << endl;
for (size_t i = 0; i < 5; i++)
{uchar* puchar = M6.ptr(i);int j = 0;while (j < 5){cout << (int)puchar[j] <<"  ";j++;}cout << endl;puchar++;
}//​template<typename _Tp > _Tp* ptr (int row, int col), ​template<typename _Tp > const _Tp* ptr (int row, int col) const
Mat m7(3, 3, CV_8UC3);
for (size_t i = 0; i < 3; i++)
{int j = 0;while (j < 3){uchar*  puchar = m7.ptr(i,j);puchar[0] = 255;puchar[1] = 0;puchar[2] = 0;j++;}
}
cout << "m7:" << endl;
for (size_t i = 0; i < 3; i++)
{int j = 0;while (j < 3){uchar* puchar = m7.ptr(i,j);cout <<(int) puchar[0] << "  " << (int)puchar[1] << "  " << (int)puchar[2] << endl;j++;}
}//​template<typename _Tp > _Tp* ptr (int i0, int i1, int i2),  template<typename _Tp >  const _Tp* ptr (int i0, int i1, int i2) const
Mat m8(5, 5, CV_8UC3);
for (size_t i = 0; i < 5; i++)
{for (size_t j = 0; j < 5; j++){int k = 0;while (k < 3){uchar* puchar = m8.ptr((i, j), k);*puchar = k;k++;}}
}
cout << "m8:" << endl;
for (size_t i = 0; i < 5; i++)
{for (size_t j = 0; j < 5; j++){int k = 0;while (k < 3){uchar* puchar = m8.ptr((i, j), k);cout <<(int)*puchar;k++;}}cout << endl;
}//​template<typename _Tp > _Tp* ptr (const int* idx), ​template<typename _Tp > const _Tp* ptr (const int* idx) const
//Mat m9(5, 5, CV_8UC1);
Mat m9 = Mat_<uchar>(5, 5);
int idx1[] = { 0,1,2,3,4 };for (size_t i = 0; i < 5; i++)
{uchar* puchar = m9.ptr(idx1);int j = 0;while (j < 5){puchar[j] = j;j++;}puchar++;
}
cout << "m9:" << endl;
for (size_t i = 0; i < 5; i++)
{uchar* puchar = m9.ptr(idx1);int j = 0;while (j < 5){cout << (int)puchar[j] << " ";j++;}cout << endl;puchar++;
}//​template<typename _Tp, int n> _Tp* ptr (const Vec< int, n > &idx), ​template<typename _Tp, int n> const _Tp* ptr (const Vec< int, n > &idx) const​
//Mat m10(5, 5, CV_8UC1);
Mat m10 = Mat_<uchar>(5, 5);
Vec<int, 5> vec2 = { 0,1,2,3,4 };for (size_t i = 0; i < 5; i++)
{uchar* puchar = m10.ptr(vec2);int j = 0;while (j < 5){puchar[j] = 255 - j;j++;}puchar++;
}
cout << "m10:" << endl;
for (size_t i = 0; i < 5; i++)
{uchar* puchar = m10.ptr(vec2);int j = 0;while (j < 5){cout << (int)puchar[j] << "  ";j++;}puchar++;cout << endl;
}

试运行,结果如下:

       

template<typename _Tp >  std::reverse_iterator< MatIterator_< _Tp > > rbegin ()

template<typename _Tp > std::reverse_iterator< MatConstIterator_< _Tp > > const

template<typename _Tp >  std::reverse_iterator< MatIterator_< _Tp > >  rend ()

template<typename _Tp > std::reverse_iterator< MatConstIterator_< _Tp > >  rend () const

rebegin()与begin()相同,但是反向遍历。

rend()与end()相同,但是反向遍历。 

将上面示例程序中无关的代码注释掉,插入新代码来演示上面函数的用法,插入的代码如下:

//for template<typename _Tp >  ​reverse_iterator< MatIterator_​<_Tp>> rbegin(),rend();
Mat m(3, 3, CV_8UC1);
typedef MatIterator_<uchar> T1;
typedef MatConstIterator_<uchar> T2;reverse_iterator<T1> it1 = m.rbegin<uchar>();
reverse_iterator<T1> it2 = m.rend<uchar>();reverse_iterator<T2> it3 = m.rbegin<uchar>();
reverse_iterator<T2> it4 = m.rend<uchar>();int i = 1;
while (it1 < it2)
{*it1 = i;i++;it1++;
}
cout << "m:  " << endl;
cout << m << endl;
while (it3 <it4)
{cout << (int)*it3 << "  ";it3++;
}
cout << endl;

试运行,结果如下:

 void  release ()

递减参考计数器并取消分配矩阵。

该方法递减与矩阵数据相关联的参考计数器。当引用计数器达到 0 时,矩阵数据被释放,数据和引用计数器指针被设置为 NULL。如果矩阵头指向外部数据集(参见 Mat::Mat ),则引用计数器为 NULL,并且该方法在这种情况下不起作用。

在上面程序中插入以下代码:

试运行,结果如下:

可见输出矩阵为一个空矩阵。

 void reserve (size_t sz)

为一定数量的行保留空间。

该方法为 sz 行保留空间。如果矩阵已经有足够的空间来存储 sz 行,则不会发生任何情况。如果重新分配矩阵,则保留前 Mat::rows 行。该方法模拟STL向量类的相应方法。

sz 行数

void reserveBuffer (size_t sz)

为一定数量的字节保留空间。

该方法保留 sz 字节的空间。如果矩阵已经有足够的空间来存储 sz 字节,则不会发生任何情况。如果必须重新分配矩阵,其先前的内容可能会丢失。

sz 字节数

上面两个程序的调用十分简单,这里就不做实例演示了。

Mat reshape (int cn, int rows=0) const

更改 2D 矩阵的形状和/或通道数,而不复制数据。

Mat reshape (int cn, int newndims, const int *newsz) const

Mat reshape (int cn, const std::vector< int > &newshape) const

后两个函数是重载函数,其作用相似,接受的参数不同。

参数:

cn 新的通道数

rows 新的rows

newndims 新的维度

newsz 所有维度均具有新矩阵大小的数组。如果某些尺寸为零,则假定这些尺寸中的原始尺寸。

newshape  所有维度具有新矩阵大小的向量。如果某些尺寸为零,则假定这些尺寸中的原始尺寸。

注释掉上面程序的无关代码,插入新代码来演示改程序的用法。插入的代码如下:

//for resahpe()
Mat src = imread("1.png");
if (src.empty())
{cout << "Cann't open the image!" << endl;return -1;
}
imshow("src", src);
Mat dst1 = src.reshape(src.channels(), src.rows/2);
imshow("Dst1", dst1);Mat src1 = (Mat_<uchar>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
const int newsz[] = {3, 4};Mat dst2 = src1.reshape(1,2, newsz);
cout << "dst2 cols:"<< dst2.cols << endl;
cout <<"dst2 rows: "<< dst2.rows << endl;
cout << "dst2 channels: "<< dst2.channels() << endl;
cout << "dst2 size: " << dst2.size() << endl;
cout << "dst2 type: " << dst2.type() << endl;Mat src2(Size(2, 2), CV_8UC3, Scalar(1, 2, 3));
vector<int> new_shape{ 4, 3 };
Mat dst3 = src2.reshape(1, new_shape);cout << "dst3 cols:" << dst3.cols << endl;
cout << "dst3 rows: " << dst3.rows << endl;
cout << "dst3 channels: " << dst3.channels() << endl;
cout << "dst3 size: " << dst3.size() << endl;
cout << "dst23 type: " << dst3.type() << endl;

试运行,结果如下:

void resize (size_t sz)

改变矩阵的rows

void resize (size_t sz, const Scalar &s)

改变矩阵的rows及矩阵值

参数 :

sz 新的矩阵rows

s 矩阵的新值。

注释掉上面程序中无关的代码,添加新代码,来演示该函数的用法,添加的新代码如下:

//Example for resize()
Mat src(500, 500, CV_8UC3, Scalar(255, 0, 0));
imshow("src", src);src.resize(300);
imshow("src resied first", src);src.resize(400, Scalar(0, 0, (uchar)255));
imshow("src resied second", src);

试运行,结果如下:

Mat row (int y) const

为指定的矩阵行创建矩阵头,不copy数据

Mat  rowRange (int startrow, int endrow) const

为指定的row跨度创建矩阵头,不copy数据

Mat rowRange (const Range &r) const

为指定的row跨度创建矩阵头,不copy数据

这几个函数与前面讲过的col (int x) const,colRange (int startcol, int endcol) const,colRange (const Range &r) const原理类似前者是针对row,后面针对的是row,这里就不再做演示。

Mat & setTo (InputArray value, InputArray mask=noArray())

将全部或部分数组元素设置为指定值。

This is an advanced variant of the Mat::operator=(const Scalar& s) operator.

参数:

Value 分配的标量转换为实际的数组类型。

mask  与 *this 大小相同的操作掩码。它的非零元素表示哪些矩阵元素需要复制。掩码必须为 CV_8U 类型,并且可以有 1 个或多个通道。

注释掉上面程序中无关的代码,插入新代码,来演示·该·函数的用法,插入代码如下:

//Example for setTo (InputArray value, InputArray mask=noArray())
Mat m1(5, 5, CV_8UC1, Scalar(110));
Mat mask(5, 5, CV_8UC1, Scalar(255));
for (size_t i = 0; i < 5; i++)
{int j = 1;while (j <3){mask.at<uchar>(j, i) = 0;j++;}}
Scalar newVal(115);
m1.setTo(newVal, mask);m1.setTo(newVal, mask);
cout << m1 << endl;

试运行,结果如下:

size_t  step1 (int i=0) const

返回一个标准化步长。

该方法返回除以 Mat::elemSize1() 的矩阵步长。快速访问任意矩阵元素非常有用。

注释掉上面程序中无关代码,插入新代码,来演示该函数的用法,插入代码如下:

//Example for step1()Mat m1(5, 5, CV_8UC3, Scalar(0,0,255));cout << "m1 elmentsize: " << m1.elemSize() << endl;cout << "m1 elmentsize1: " << m1.elemSize1() << endl;cout << "m1 step: " << m1.step << endl;cout << "m1 step1: " << m1.step1() << endl;

试运行,结果如下:

MatExpr      t () const

转置矩阵,即返回该Mat对象数据矩阵的转置矩阵。

注释掉上面演示程序的无关代码,插入新代码,来演示该函数的用法,插入代码如下:

//Example for t()
Mat m1 = (Mat_<uchar>(3,3) <<1,2,3,4,5,6,7,8,9);
cout << "m1:" << endl;
cout << m1 << endl;
Mat m2 = m1.t();
cout << "m2:" << endl;
cout << m2 << endl;

试运行,结果如下:

size_t  total () const 

返回Mat对象数据矩阵element的总数。

size_t  total(int startDim, int endDim=INT_MAX) const

该方法返回某个子数组切片内的元素数量

int   type() const

返回element type

注释掉上面演示程序中无关的代码,插入新代码,演示上面几个函数的用法,插入代码如下:

//Example for total(),type()
Mat m1(10, 10, CV_8UC3,Scalar(0,0,255));
cout <<"m1 total: "<< m1.total() << endl;
cout << "m1  total2: " << m1.total((int)3, (int)9) << endl;
cout << "m1 type: " << m1.type() << endl;

试运行,结果如下:

         到此,OpenCV Mat类的成员函数已介绍完毕。 

        博文示例是基于OpenCV4.8(opencv目录位于d盘根目录下)及VS2022。示例源码已上传到CSDN,其链接为:https://download.csdn.net/download/billliu66/88874033

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

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

相关文章

备考2024年汉字小达人:历年考题练一练-18道选择题

今天为大家分享汉字小达人的备考学习资源&#xff0c;通过参加没有报名费、人人可参加的汉字小达人比赛&#xff0c;激发孩子学习语文的兴趣&#xff0c;并且提升语文学习成绩。 汉字小达人的两轮比赛&#xff08;区级自由报名活动、市级活动&#xff09;的选择题主要有六种题型…

Mac安装Appium

一、环境依赖 一、JDK环境二、Android-SDK环境&#xff08;android自动化&#xff09;三、Homebrew环境四、Nodejs 安装cnpm 五、安装appium六、安装appium-doctor来确认安装环境是否完成七、安装相关依赖 二、重头大戏&#xff0c; 配置wda&#xff08;WebDriverAgent&#x…

华为---RSTP(三)---P/A机制及RSTP的生成树形成过程

目录 1. P/A机制简介 1.1 P/A机制的作用 1.2 P/A协商的前提条件 1.3 RSTP选举思路 2. P/A协商过程 3. 举例说明RSTP的生成树形成过程 3.1 示例环境要求 3.2 RSTP的生成树形成过程 3.2.1 SW和SW1之间链路上抓包分析 3.2.2 SW和SW2之间链路上抓包分析 3.2.3 SW1和SW2之…

实现外网手机或者电脑随时随地远程访问家里的电脑主机(linux为例)

文章目录 一、背景概要二、安装配置花生壳软件(linux版本)三、手机端(外网)验证连接四、安装ubuntu20server版系统遇到的问题记录 一、背景概要 由于经常在遇到某些问题的时候&#xff0c;针对某一个场景的理解&#xff0c;需要借助于自己的电脑去编译(aosp/linux/qemu)代码查…

5.2.鸿蒙LiteOS-M los_dispatch

目录 一、cortex-m4 los_dispatch.S代码分析坚持就有收获 一、cortex-m4 los_dispatch.S代码分析 .syntax unified #.syntax [unified | divided], 指定arm 汇编语法规则 .arch armv7e-m #指定平台, 与命令行参数-march同样的作用 .fpu fpv4-sp-d16 #指定浮点运算…

苹果分拣检测YOLOV8NANO

苹果分拣&#xff0c;可以检测成熟、切片、损坏、不成熟四种类型&#xff0c;YOLOV8NANO&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C,PYTHON 苹果分拣检测YOLOV8NANO&#xff0c;检测四种类型苹果

C++ 学习之函数对象

C++ 函数对象基本概念 在C++中,函数对象(Function Objects)是一种类或结构体,它重载了函数调用运算符operator(),因此可以像函数一样被调用。函数对象有时也被称为仿函数(Functor)。 以下是关于C++函数对象的基本概念: 使用函数对象:函数对象可以像普通函数一样被调…

【Flink精讲】Flink 内存管理

面临的问题 目前&#xff0c; 大数据计算引擎主要用 Java 或是基于 JVM 的编程语言实现的&#xff0c;例如 Apache Hadoop、 Apache Spark、 Apache Drill、 Apache Flink 等。 Java 语言的好处在于程序员不需要太关注底层内存资源的管理&#xff0c;但同样会面临一个问题&…

从零开始学习Netty - 学习笔记 -Netty入门-EventLoop

5.Neety入门 什么是Netty Netty是一个基于Java NIO的异步事件驱动的网络应用框架。它被广泛用于开发高性能、高可靠性的网络通信程序&#xff0c;特别是服务器端和客户端程序。Netty提供了简洁而强大的API&#xff0c;使得开发者能够轻松地构建各种网络应用&#xff0c;包括实…

LiveQing视频点播流媒体RTMP推流服务功能-支持配置开启 HTTPS 服务什么时候需要开启HTTPS服务

LiveQing视频点播流媒体RTMP推流服务功能支持配置开启 HTTPS 服务什么时候需要开启HTTPS服务 1、配置开启HTTPS1.1、准备https证书1.1.1、选择Nginx类型证书下载 1.2、配置 开启 HTTPS1.2.1 web页面配置1.2.2 配置文件配置 2、验证HTTPS服务3、为什么要开启HTTPS3.1、安全性要求…

Mysql运维篇(四) MHA

大佬博文 https://www.cnblogs.com/gomysql/p/3675429.html MySQL 高可用&#xff08;MHA&#xff09; - 知乎 一、MHA简介&#xff1a; MHA&#xff08;Master High Availability&#xff09;目前在MySQL高可用方面是一个相对成熟的解决方案&#xff0c;它由日本DeNA公司y…

freeswitch 权威指南 --- 高级篇

官网文档&#xff1a;https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/ 关于 freeswitch 的公开教程&#xff1a;https://zhuanlan.zhihu.com/p/451981734 内容来自 《FreeSWITCH 权威指南》&#xff1a;目录&#xff1a;https://juejin.cn/post/702058079…

人力资源管理信息化系统如何支持企业开展管理诊断

人力资源顾问有限公司致力于帮助企业开展人力资源管理方面的各项提升改进工作&#xff0c;在长期的咨询工作中&#xff0c;最常听到企业提到的问题莫过于管理诊断方面的问题&#xff0c;事实上&#xff0c;很多企业在日常工作中&#xff0c;都意识到企业内部存在管理方面的问题…

vue3+js 实现记住密码功能

常见的几种实现方式 1 基于spring security 的remember me 功能 ​​​​​​​ localStorage 除非主动清除localStorage 里的信息 &#xff0c;不然永远存在&#xff0c;关闭浏览器之后下次启动仍然存在 存放数据大小一般为5M 不与服务器进行交互通信 cookies 可以…

第11章 互连网络体系结构

之前&#xff0c;我们尚未讨论如何可靠、快速地将消息从一个节点发送到另一个节点。本章目的是讨论多个处理器互连的结构。互连网络最重要的两个性能指标是延迟和带宽。 基于共享存储多处理器的几个通信特性&#xff0c;与诸如局域网或因特网等其他网络系统相比&#xff0c;共…

react hook使用UEditor引入秀米图文排版

里面坑比较多&#xff0c;细节也比较多 以下使用的是react 18 ice3.0&#xff0c;使用其他react脚手架的配置基本相同&#xff0c;例如umi4 1.下载UEditor 进入UEditor仓库&#xff0c;找到版本v1.4.3.3&#xff0c;点击进去 接着下载ueditor1_4_3_3-utf8-jsp.zip版本 下载好…

CentOS 7 定时任务 + Shell 脚本自动备份 MySQL 数据库(一次 Halo 建站数据库丢失的教训)

文章目录 前置条件创建备份脚本设置 Cron 任务测试备份脚本备份安全和维护一键恢复自动清除备份文件常见问题总结 TIP&#xff1a; 原文链接阅读体验更佳&#xff1a;CentOS 7 自动备份 MySQL 数据库 最近抽空简单搭了一个博客&#xff0c;目前内容较少&#xff0c;后续陆续发…

Supermaven惊艳亮相:300,000个Tokens的超大上下文窗口,能否超越Copilot成为代码补全新王者?

当我看到GitHub宣布Copilot的年经常性收入突破1亿美元时&#xff0c;我意识到代码补全技术已经迈入了新的时代。 大型模型的崛起使得这些工具变得更加智能和实用&#xff0c;吸引了越来越多的开发者加入AI编码的行列。 在这个背景下&#xff0c;Supermaven发布了。这是第一个…

TikTok直播网络不稳定是什么原因

在当今社交媒体平台中&#xff0c;TikTok以其独特的视频内容和社交互动功能而备受欢迎。然而&#xff0c;尽管TikTok为用户提供了直播功能&#xff0c;但一些用户可能会遇到TikTok直播网络不稳定的问题。那么&#xff0c;TikTok直播网络不稳定的原因是什么呢&#xff1f;以下是…

(每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第11章 项目成本管理(五)

博主2023年11月通过了信息系统项目管理的考试&#xff0c;考试过程中发现考试的内容全部是教材中的内容&#xff0c;非常符合我学习的思路&#xff0c;因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家&#xff0c;希望更多的人能够通过考试&a…