OpenCV4.9关于矩阵上的掩码操作

 返回:OpenCV系列文章目录(持续更新中......)

上一篇:如何使用OpenCV扫描图像、查找表和时间测量

下一篇:OpenCV4.9的是如何进行图像操作 

引言:

矩阵上的掩码操作非常简单。这个想法是,我们根据掩码矩阵(也称为内核)重新计算图像中每个像素的值。此蒙版包含的值将调整相邻像素(和当前像素)对新像素值的影响程度。从数学的角度来看,我们用指定的值做一个加权平均值。

测试用例

考虑图像对比度增强方法的问题。对图像的每个像素基本上应用以下公式:

I(i,j)=5∗I(i,j)−[I(i−1,j)+I(i+1,j)+I(i,j−1)+I(i,j+1)]

⟺I(i,j)∗M,where M=i∖j−10+1−10−100−15−1+10−10

第一种表示法是使用公式,而第二种表示法是第一种表示法的压缩版本,使用蒙版。使用蒙版的方法是将蒙版矩阵的中心(以大写字母表示,由零零索引表示)放在要计算的像素上,并将像素值乘以重叠的矩阵值相加。这是一回事,但是在大型矩阵的情况下,后一种符号更容易查看。

代码

C++

您可以从此处下载此源代码,或查看 OpenCV 源代码库示例目录  samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp.

​#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
static void help(char* progName)
{
cout << endl
<< "This program shows how to filter images with mask: the write it yourself and the"
<< "filter2d way. " << endl
<< "Usage:" << endl
<< progName << " [image_path -- default lena.jpg] [G -- grayscale] " << endl << endl;
}
void Sharpen(const Mat& myImage,Mat& Result);
int main( int argc, char* argv[])
{
help(argv[0]);
const char* filename = argc >=2 ? argv[1] : "lena.jpg";
Mat src, dst0, dst1;
if (argc >= 3 && !strcmp("G", argv[2]))
src = imread( samples::findFile( filename ), IMREAD_GRAYSCALE);
else
src = imread( samples::findFile( filename ), IMREAD_COLOR);
if (src.empty())
{
cerr << "Can't open image [" << filename << "]" << endl;
return EXIT_FAILURE;
}
namedWindow("Input", WINDOW_AUTOSIZE);
namedWindow("Output", WINDOW_AUTOSIZE);
imshow( "Input", src );
double t = (double)getTickCount();
Sharpen( src, dst0 );
t = ((double)getTickCount() - t)/getTickFrequency();
cout << "Hand written function time passed in seconds: " << t << endl;
imshow( "Output", dst0 );
waitKey();
Mat kernel = (Mat_<char>(3,3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
t = (double)getTickCount();
filter2D( src, dst1, src.depth(), kernel );
t = ((double)getTickCount() - t)/getTickFrequency();
cout << "Built-in filter2D time passed in seconds: " << t << endl;
imshow( "Output", dst1 );
waitKey();
return EXIT_SUCCESS;
}
void Sharpen(const Mat& myImage,Mat& Result)
{
CV_Assert(myImage.depth() == CV_8U); // accept only uchar images
const int nChannels = myImage.channels();
Result.create(myImage.size(),myImage.type());
for(int j = 1 ; j < myImage.rows-1; ++j)
{
const uchar* previous = myImage.ptr<uchar>(j - 1);
const uchar* current = myImage.ptr<uchar>(j );
const uchar* next = myImage.ptr<uchar>(j + 1);
uchar* output = Result.ptr<uchar>(j);
for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i)
{
output[i] = saturate_cast<uchar>(5*current[i]
-current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
}
}
Result.row(0).setTo(Scalar(0));
Result.row(Result.rows-1).setTo(Scalar(0));
Result.col(0).setTo(Scalar(0));
Result.col(Result.cols-1).setTo(Scalar(0));
}

Java代码:samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java.

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class MatMaskOperationsRun {
 public void run(String[] args) {
 String filename = "../data/lena.jpg";
 int img_codec = Imgcodecs.IMREAD_COLOR;
 if (args.length != 0) {
 filename = args[0];
 if (args.length >= 2 && args[1].equals("G"))
 img_codec = Imgcodecs.IMREAD_GRAYSCALE;
 }
 Mat src = Imgcodecs.imread(filename, img_codec);
 if (src.empty()) {
 System.out.println("Can't open image [" + filename + "]");
 System.out.println("Program Arguments: [image_path -- default ../data/lena.jpg] [G -- grayscale]");
 System.exit(-1);
 }
 HighGui.namedWindow("Input", HighGui.WINDOW_AUTOSIZE);
 HighGui.namedWindow("Output", HighGui.WINDOW_AUTOSIZE);
 HighGui.imshow( "Input", src );
 double t = System.currentTimeMillis();
 Mat dst0 = sharpen(src, new Mat());
 t = ((double) System.currentTimeMillis() - t) / 1000;
 System.out.println("Hand written function time passed in seconds: " + t);
 HighGui.imshow( "Output", dst0 );
 HighGui.moveWindow("Output", 400, 400);
 HighGui.waitKey();
 Mat kern = new Mat(3, 3, CvType.CV_8S);
 int row = 0, col = 0;
 kern.put(row, col, 0, -1, 0, -1, 5, -1, 0, -1, 0);
 t = System.currentTimeMillis();
 Mat dst1 = new Mat();
 Imgproc.filter2D(src, dst1, src.depth(), kern);
 t = ((double) System.currentTimeMillis() - t) / 1000;
 System.out.println("Built-in filter2D time passed in seconds: " + t);
 HighGui.imshow( "Output", dst1 );
 HighGui.waitKey();
 System.exit(0);
 }
 public static double saturate(double x) {
 return x > 255.0 ? 255.0 : (x < 0.0 ? 0.0 : x);
 }
 public Mat sharpen(Mat myImage, Mat Result) {
 myImage.convertTo(myImage, CvType.CV_8U);
 int nChannels = myImage.channels();
 Result.create(myImage.size(), myImage.type());
 for (int j = 1; j < myImage.rows() - 1; ++j) {
 for (int i = 1; i < myImage.cols() - 1; ++i) {
 double sum[] = new double[nChannels];
 for (int k = 0; k < nChannels; ++k) {
 double top = -myImage.get(j - 1, i)[k];
 double bottom = -myImage.get(j + 1, i)[k];
 double center = (5 * myImage.get(j, i)[k]);
 double left = -myImage.get(j, i - 1)[k];
 double right = -myImage.get(j, i + 1)[k];
 sum[k] = saturate(top + bottom + center + left + right);
 }
 Result.put(j, i, sum);
 }
 }
 Result.row(0).setTo(new Scalar(0));
 Result.row(Result.rows() - 1).setTo(new Scalar(0));
 Result.col(0).setTo(new Scalar(0));
 Result.col(Result.cols() - 1).setTo(new Scalar(0));
 return Result;
 }
}
public class MatMaskOperations {
 public static void main(String[] args) {
 // Load the native library.
 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
 new MatMaskOperationsRun().run(args);
 }
}

Python代码:

samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py.

from __future__ import print_function
import sys
import time
import numpy as np
import cv2 as cv
def is_grayscale(my_image):
 return len(my_image.shape) < 3
def saturated(sum_value):
 if sum_value > 255:
 sum_value = 255
 if sum_value < 0:
 sum_value = 0
 return sum_value
def sharpen(my_image):
 if is_grayscale(my_image):
 height, width = my_image.shape
 else:
 my_image = cv.cvtColor(my_image, cv.CV_8U)
 height, width, n_channels = my_image.shape
 result = np.zeros(my_image.shape, my_image.dtype) 
 for j in range(1, height - 1):
 for i in range(1, width - 1):
 if is_grayscale(my_image):
 sum_value = 5 * my_image[j, i] - my_image[j + 1, i] - my_image[j - 1, i] \
 - my_image[j, i + 1] - my_image[j, i - 1]
 result[j, i] = saturated(sum_value)
 else:
 for k in range(0, n_channels):
 sum_value = 5 * my_image[j, i, k] - my_image[j + 1, i, k] \
 - my_image[j - 1, i, k] - my_image[j, i + 1, k]\
 - my_image[j, i - 1, k]
 result[j, i, k] = saturated(sum_value) 
 return result
def main(argv):
 filename = 'lena.jpg'
 img_codec = cv.IMREAD_COLOR
 if argv:
 filename = sys.argv[1]
 if len(argv) >= 2 and sys.argv[2] == "G":
 img_codec = cv.IMREAD_GRAYSCALE
 src = cv.imread(cv.samples.findFile(filename), img_codec)
 if src is None:
 print("Can't open image [" + filename + "]")
 print("Usage:")
 print("mat_mask_operations.py [image_path -- default lena.jpg] [G -- grayscale]")
 return -1
 cv.namedWindow("Input", cv.WINDOW_AUTOSIZE)
 cv.namedWindow("Output", cv.WINDOW_AUTOSIZE)
 cv.imshow("Input", src)
 t = round(time.time())
 dst0 = sharpen(src)
 t = (time.time() - t)
 print("Hand written function time passed in seconds: %s" % t)
 cv.imshow("Output", dst0)
 cv.waitKey()
 t = time.time() 
 kernel = np.array([[0, -1, 0],
 [-1, 5, -1],
 [0, -1, 0]], np.float32) # kernel should be floating point type 
 dst1 = cv.filter2D(src, -1, kernel)
 # ddepth = -1, means destination image has depth same as input image 
 t = (time.time() - t)
 print("Built-in filter2D time passed in seconds: %s" % t)
 cv.imshow("Output", dst1)
 cv.waitKey(0)
 cv.destroyAllWindows()
 return 0
if __name__ == "__main__":
 main(sys.argv[1:])

基本方法

现在让我们看看如何通过使用基本的像素访问方法或使用 filter2D() 函数来实现这一点。

下面是一个函数,可以执行此操作:

C++代码;

def is_grayscale(my_image):
 return len(my_image.shape) < 3
def saturated(sum_value):
 if sum_value > 255:
 sum_value = 255
 if sum_value < 0:
 sum_value = 0
 return sum_value
def sharpen(my_image):
 if is_grayscale(my_image):
 height, width = my_image.shape
 else:
 my_image = cv.cvtColor(my_image, cv.CV_8U)
 height, width, n_channels = my_image.shape
 result = np.zeros(my_image.shape, my_image.dtype) 
 for j in range(1, height - 1):
 for i in range(1, width - 1):
 if is_grayscale(my_image):
 sum_value = 5 * my_image[j, i] - my_image[j + 1, i] - my_image[j - 1, i] \
 - my_image[j, i + 1] - my_image[j, i - 1]
 result[j, i] = saturated(sum_value)
 else:
 for k in range(0, n_channels):
 sum_value = 5 * my_image[j, i, k] - my_image[j + 1, i, k] \
 - my_image[j - 1, i, k] - my_image[j, i + 1, k]\
 - my_image[j, i - 1, k]
 result[j, i, k] = saturated(sum_value) 
 return result

Java代码:

 public static double saturate(double x) {
 return x > 255.0 ? 255.0 : (x < 0.0 ? 0.0 : x);
 }
 public Mat sharpen(Mat myImage, Mat Result) {
 myImage.convertTo(myImage, CvType.CV_8U);
 int nChannels = myImage.channels();
 Result.create(myImage.size(), myImage.type());
 for (int j = 1; j < myImage.rows() - 1; ++j) {
 for (int i = 1; i < myImage.cols() - 1; ++i) {
 double sum[] = new double[nChannels];
 for (int k = 0; k < nChannels; ++k) {
 double top = -myImage.get(j - 1, i)[k];
 double bottom = -myImage.get(j + 1, i)[k];
 double center = (5 * myImage.get(j, i)[k]);
 double left = -myImage.get(j, i - 1)[k];
 double right = -myImage.get(j, i + 1)[k];
 sum[k] = saturate(top + bottom + center + left + right);
 }
 Result.put(j, i, sum);
 }
 }
 Result.row(0).setTo(new Scalar(0));
 Result.row(Result.rows() - 1).setTo(new Scalar(0));
 Result.col(0).setTo(new Scalar(0));
 Result.col(Result.cols() - 1).setTo(new Scalar(0));
 return Result;
 }

Python代码

def is_grayscale(my_image):
 return len(my_image.shape) < 3
def saturated(sum_value):
 if sum_value > 255:
 sum_value = 255
 if sum_value < 0:
 sum_value = 0
 return sum_value
def sharpen(my_image):
 if is_grayscale(my_image):
 height, width = my_image.shape
 else:
 my_image = cv.cvtColor(my_image, cv.CV_8U)
 height, width, n_channels = my_image.shape
 result = np.zeros(my_image.shape, my_image.dtype) 
 for j in range(1, height - 1):
 for i in range(1, width - 1):
 if is_grayscale(my_image):
 sum_value = 5 * my_image[j, i] - my_image[j + 1, i] - my_image[j - 1, i] \
 - my_image[j, i + 1] - my_image[j, i - 1]
 result[j, i] = saturated(sum_value)
 else:
 for k in range(0, n_channels):
 sum_value = 5 * my_image[j, i, k] - my_image[j + 1, i, k] \
 - my_image[j - 1, i, k] - my_image[j, i + 1, k]\
 - my_image[j, i - 1, k]
 result[j, i, k] = saturated(sum_value) 
 return result

首先,我们确保输入图像数据采用无符号字符格式。为此,我们使用cv::CV_Assert 函数,当其中的表达式为 false 时,该函数会抛出错误。

 CV_Assert(myImage.depth() == CV_8U); // 只接受 uchar 图片

我们创建一个与输入具有相同大小和类型的输出图像。正如您在存储部分中看到的那样,根据通道的数量,我们可能有一个或多个子列。

我们将通过指针遍历它们,因此元素的总数取决于这个数字。

const int nChannels = myImage.channels();
Result.create(myImage.size(),myImage.type());

我们将使用普通的 C [] 运算符来访问像素。因为我们需要同时访问多行,所以我们将获取每行的指针(上一行、当前行和下一行)。我们需要另一个指向要保存计算位置的指针。然后,只需使用 [] 运算符访问正确的项目即可。为了将输出指针向前移动,我们只需在每次操作后增加此值(一个字节):

 for(int j = 1 ; j < myImage.rows-1; ++j)
 {
 const uchar* previous = myImage.ptr<uchar>(j - 1);
 const uchar* current = myImage.ptr<uchar>(j );
 const uchar* next = myImage.ptr<uchar>(j + 1);
 uchar* output = Result.ptr<uchar>(j);
 for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i)
 {
 output[i] = saturate_cast<uchar>(5*current[i]
 -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
 }
 }

在图像的边框上,上面的符号会导致不存在的像素位置(如负一 - 负一)。在这些方面,我们的公式是未定义的。一个简单的解决方案是不在这些点上应用内核,例如,将边框上的像素设置为零:

 Result.row(0).setTo(Scalar(0));
 Result.row(Result.rows-1).setTo(Scalar(0));
 Result.col(0).setTo(Scalar(0));
 Result.col(Result.cols-1).setTo(Scalar(0));

filter2D 函数
 

应用这种过滤器在图像处理中非常普遍,以至于在 OpenCV 中有一个函数可以负责应用掩码(在某些地方也称为内核)。为此,您首先需要定义一个包含掩码的对象:

C++代码:

 Mat kernel = (Mat_<char>(3,3) << 0, -1, 0,
 -1, 5, -1,
 0, -1, 0);

 然后调用 filter2D() 函数,指定要使用的输入、输出图像和内核:

 filter2D( src, dst1, src.depth(), kernel );

 Java代码:

 Mat kern = new Mat(3, 3, CvType.CV_8S);
 int row = 0, col = 0;
 kern.put(row, col, 0, -1, 0, -1, 5, -1, 0, -1, 0);

 然后调用 filter2D() 函数,指定要使用的输入、输出图像和内核:

 Imgproc.filter2D(src, dst1, src.depth(), kern);

Python代码:

 kernel = np.array([[0, -1, 0],
 [-1, 5, -1],
 [0, -1, 0]], np.float32) # kernel should be floating point type

 然后调用 filter2D() 函数,指定要使用的输入、输出图像和内核: 

 dst1 = cv.filter2D(src, -1, kernel)
 # ddepth = -1, means destination image has depth same as input image

该函数甚至还有第五个可选参数来指定内核的中心,第六个参数用于在将过滤后的像素存储在 K 中之前向它们添加可选值,第七个参数用于确定在未定义操作的区域(边界)中执行的操作。

此函数更短,更不冗长,并且由于进行了一些优化,因此通常比手动编码方法更快。例如,在我的测试中,第二个测试只用了 13 毫秒,而第一个测试大约需要 31 毫秒。相当有区别。

例如:

resultMatMaskFilter2D.png

在我们的 YouTube 频道上查看运行该程序的实例。

参考文章:

1、《Mask operations on matrices》-----Bernát Gábor

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PTA题解 --- 浪漫侧影(思路题解)

今天是PTA题库解法讲解的第九天&#xff0c;今天我们要讲解浪漫侧影&#xff0c;题目如下&#xff1a; 题解思路&#xff1a; 要解决这个问题&#xff0c;首先需要根据给定的中序遍历和后序遍历序列重建二叉树。然后&#xff0c;通过分别进行层序遍历的方式&#xff0c;记录每…

阿里CICD流水线Docker部署,将阿里镜像私仓中的镜像部署到服务器中

文章目录 阿里CICD流水线Docker部署&#xff0c;将阿里镜像私仓中的镜像部署到服务器中一、CICD流水线的初步使用可以看我之前的两篇文章二、添加部署任务&#xff0c;进行Docker部署&#xff0c;创建一个阿里的试用主机1、选择主机部署&#xff0c;并添加服务主机2、创建免费体…

设计模式学习笔记 - 设计模式与范式 -结构型:2.桥接模式:如何实现支持不同类型和渠道的消息推送系统?

概述 今天学习另外一种结构型模式&#xff1a;桥接模式。桥接模式的代码实现非常简单&#xff0c;但是理解起来稍微优点难度&#xff0c;并且应用场景也比较局限&#xff0c;所以&#xff0c;相对于代理模式来说&#xff0c;桥接模式在实际的项目中并没有那么常用&#xff0c;…

全新Mistral-7B v0.2基础模型开源:32K上下文,开源界的性能巨兽

前言 在人工智能领域的发展历程中&#xff0c;开源大模型始终是推动技术进步与创新应用的关键力量。近日&#xff0c;Mistral AI再次引领开源潮流&#xff0c;发布了Mistral-7B v0.2基础模型&#xff0c;这不仅是对之前版本的升级&#xff0c;更是在性能与功能上的一次质的飞跃…

选择最佳图像处理工具OpenCV、JAI、ImageJ、Thumbnailator和Graphics2D

文章目录 1、前言2、 图像处理工具效果对比2.1 Graphics2D实现2.2 Thumbnailator实现2.3 ImageJ实现2.4 JAI&#xff08;Java Advanced Imaging&#xff09;实现2.5 OpenCV实现 3、图像处理工具结果 1、前言 SVD(stable video diffusion)开放了图生视频的API&#xff0c;但是限…

Mysql数据库:日志管理、备份与恢复

目录 前言 一、MySQL日志管理 1、存放日志和数据文件的目录 2、日志的分类 2.1 错误日志 2.2 通用查询日志 2.3 二进制日志 2.4 慢查询日志 2.5 中继日志 3、日志综合配置 4、查询日志是否开启 二、数据备份概述 1、数据备份的重要性 2、备份类型 2.1 从物理与…

【IJCAI‘23】港大提出社会推荐中的去噪自增强学习

论文标题&#xff1a; Denoised Self-Augmented Learning for Social Recommendation 收录会议&#xff1a; IJCAI 2023 论文链接&#xff1a; https://arxiv.org/abs/2305.12685 代码链接&#xff08;欢迎 ✨&#xff09;&#xff1a; https://github.com/HKUDS/DSL 港…

密码学及其应用1 —— 密码学概述

1 密码学的基本概念 1.1 网络安全的定义 网络安全是网络领域的一个专业领域&#xff0c;它涵盖了在基础计算机网络基础设施中所采取的措施、网络管理员为保护网络及网络可访问资源免受未授权访问而采纳的政策&#xff0c;以及对其有效性&#xff08;或无效性&#xff09;的持续…

Capture One Pro 23中文---颠覆性的图像编辑与色彩配置

Capture One Pro 23是一款功能强大且专业的RAW图像编辑处理软件。它拥有全球领先的色彩管理技术和精细的图像编辑工具&#xff0c;可以对图片进行多种精细调整&#xff0c;包括曝光、色温、对比度、锐度等&#xff0c;以满足用户特定的后期处理需求。此外&#xff0c;Capture O…

Linux离线安装mysql,node,forever

PS:本文是基于centos7实现的,要求系统能够查看ifconfig和unzip解压命令, 实现无网络可安装运行 首先现在百度网盘的离线文件包****安装Xftp 和 Xshell 把机房压缩包传到 home目录下****解压unzip 包名.zip 获取IP先获取到 linux 主机的ip ifconfig Xftp 连接输入IP,然后按照…

CentOS使用Docker部署Halo并结合内网穿透实现公网访问本地博客

文章目录 1. Docker部署Halo1.1 检查Docker版本如果未安装Docker可参考已安装Docker步骤&#xff1a;1.2 在Docker中部署Halo 2. Linux安装Cpolar2.1 打开服务器防火墙2.2 安装cpolar内网穿透 3. 配置Halo个人博客公网地址4. 固定Halo公网地址 本文主要介绍如何在CentOS 7系统使…

【Monero】Wallet RPC | Wallet CLI | 门罗币命令行查询余额、种子、地址等命令方法教程

ubuntu22.04 首先在运行daemon&#xff0c;详细安装运行教程可参考&#xff1a;The Monero daemon (monerod) ./monerodWallet CLI run ./monero-wallet-cli如果还没有钱包就根据提示创建钱包即可 输入密码 查询余额 balance查询种子 seed其他可执行命令操作&#xff1…

Spring Cloud - Openfeign 实现原理分析

OpenFeign简介 OpenFeign 是一个声明式 RESTful 网络请求客户端。OpenFeign 会根据带有注解的函数信息构建出网络请求的模板,在发送网络请求之前,OpenFeign 会将函数的参数值设置到这些请求模板中。虽然 OpenFeign 只能支持基于文本的网络请求,但是它可以极大简化网络请求的…

QT(3/22)

1>使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数&#xff0c;将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#…

【笔记】MJ Prompt

参数 --chaos 10 or --c 10, 0-10, defalut 0 --quality 1 or --q, 0.25-1, defalut 1 --iw 2, 0.5-2, --stylize 100 or --s 100, 0-1000, defalut 100 --cref URL --cw 100, 0-100stylize 风格化&#xff0c;MJ不同的出图模式&#xff0c;有默认的艺术风格&#xff0c;该值…

企业微信主体变更的公证书怎么办?

企业微信变更主体有什么作用&#xff1f; 企业微信推出到现在已经很多年了&#xff0c;但是之前一直不支持主体变更。于是很多公司好不容易积累的客户&#xff0c;因为换了营业执照经营&#xff0c;原来的客户就都只能流失了。近期企业微信终于放开了变更主体的功能&#xff0c…

C++细节

背景知识&#xff1a; 面向对象的编程中&#xff0c;类&#xff08;Class&#xff09;是创建对象的蓝图或模板&#xff0c;它包含了数据&#xff08;通常称为属性或变量&#xff09;和行为&#xff08;通常称为方法或函数&#xff09;。将数据封装为私有&#xff08;private&am…

babel起手式

Babel7 以下是各个 ECMAScript 版本引入的一些主要新语法和功能的汇总 ES5 / ECMAScript 5&#xff08;2009年&#xff09; 严格模式 "use strict"。JSON 对象。Array.prototype.forEach()、Array.prototype.map()、Array.prototype.filter()、Array.prototype.redu…

畅捷通T+ Ufida.T.DI.UIP.RRA.RRATableController 远程命令执行漏洞

一、漏洞信息 漏洞名称:畅捷通T+ Ufida.T.DI.UIP.RRA.RRATableController 远程命令执行漏洞 漏洞类别:远程命令执行漏洞 风险等级:高危 二、漏洞描述 畅捷通TPlus适用于异地多组织、多机构对企业财务汇总的管理需求;全面支持企业对远程仓库、异地办事处的管理需求;全…

2015年认证杯SPSSPRO杯数学建模A题(第二阶段)绳结全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 A题 绳结 原题再现&#xff1a; 给绳索打结是人们在日常生活中常用的技能。对登山、航海、垂钓、野外生存等专门用途&#xff0c;结绳更是必不可少的技能之一。针对不同用途&#xff0c;有多种绳结的编制方法。最简单的绳结&#xff0c;有时称…