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

opencv图片处理

目录

  • 1 图片处理
    • 1.1 显示图片
    • 1.2 旋转图片
    • 1.3 合并图片
    • 1.4、Mat类
      • 1.4.1、像素的储存结构
      • 1.4.2、访问像素数据
    • 1.6、rgb转灰度图
    • 1.7、二值化
    • 1.8、对比度和亮度
    • 1.9、图片缩放
      • 1.9.1、resize
        • 临近点算法
        • 双线性内插值
      • 1.9.2、金字塔缩放
    • 1.10、图片叠加


1 图片处理

1.1 显示图片

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat image = imread("test.jpeg");namedWindow("img");imshow("img", image);waitKey(0);
}

1.2 旋转图片

旋转图片用的是rotate(InputArray src, OutputArray dst, int rotateCode)方法,opencv提供了以下3种旋转方式。

enum RotateFlags {ROTATE_90_CLOCKWISE = 0, //顺时针旋转90度ROTATE_180 = 1, //旋转180度ROTATE_90_COUNTERCLOCKWISE = 2 //逆时针旋转90度
};
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat src= imread("test.jpeg");Mat dst;rotate(src, dst, ROTATE_90_CLOCKWISE); //顺时针旋转90度namedWindow("img");imshow("img", dst);waitKey(0);
}

在这里插入图片描述

1.3 合并图片

把两张图片合并到一张。
思路:创建一个能容纳两张图片的Mat,然后对左右两个区域分别填充像素。

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat img1 = imread("test1.jpeg");Mat img2 = imread("test.jpeg");Mat dst;dst.create(img1.rows > img2.rows ? img1.rows : img2.rows,img1.cols + img2.cols, img1.type());Mat r1 = dst(Rect(0, 0, img1.cols, img1.rows));img1.copyTo(r1);Mat r2 = dst(Rect(img1.cols, 0, img2.cols, img2.rows));img2.copyTo(r2);namedWindow("img");imshow("img", dst);waitKey(0);
}

在这里插入图片描述

1.4、Mat类

opencv的Mat类对象可以用来存放图像的像素数据,它有多种储存模式,比较常用的有以下四种。

#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)

它们的含义可以根据名字来判别,比如CV_8UC3,代表一个像素由3个8位的uchar储存,我们平时看到的rgb三色图就可以用这种类型来储存。

1.4.1、像素的储存结构

Mat对象的像素数据存放在一个char类型数据上,成员名叫data。
以一张CV_8UC3类型、大小为2 * 2的图像为例,它对应的储存结构可以以下图表示。
在这里插入图片描述
在显示图像时,映射成下图所示。
在这里插入图片描述

1.4.2、访问像素数据

从上一节我们可以看到,像素数据里的红蓝绿数据是以蓝(0),绿(1),红(2)的顺序来排列的。比如我们要访问第一行第一列的绿色数据,可以用mat.data[1]来访问,访问第二行第一列的红色数据,可以用mat.data[8]。

下面举例说明opencv修改像素数据的方式。
比如我们要用opencv来画一幅红蓝间条的图片,可以用以下程序来实现。

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat mat(400, 300, CV_8UC3); 			//创建一张400 * 300的图片int pixelSize = mat.elemSize();			//单个像素的大小,本例中大小为3int size = mat.rows * mat.cols * pixelSize;	//行*列*像素大小 = 缓存区大小for (int i = 0; i < size; i += pixelSize) {/* 每隔十行切换一次颜色 */int row = i / (mat.cols * pixelSize);	if (row % 20 < 10) {/* 画蓝色像素点 */mat.data[i] = 255;mat.data[i + 1] = 0;mat.data[i + 2] = 0;} else {/* 画红色像素点 */mat.data[i] = 0;mat.data[i + 1] = 0;mat.data[i + 2] = 255;}}namedWindow("mat");imshow("mat", mat);waitKey(0);
}

opencv中除了用mat.data可以访问像素数据外,还提供了几种访问方式,如下表所示。
mat.step代表一行的大小,即colSum * ps。

编号访问方式特点例子(访问第r行第c列的蓝色)
1mat.data[index]遍历速度和访问速度都是最快的,但使用不便。data[r * mat.step + c + 0]
2mat.ptr(row, col)速度比第一种稍慢,可以通过行号和列号来直接访问。mat.ptr(row, col)[0]
3mat.at(row, col)速度最慢,可以通过行号和列号来直接访问。mat.at(row, col)[0]

以上效率是用opencv3.4测得的,不同版本的效率可能不一样。
测试例程:

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <QDebug>
#include <QElapsedTimer>using namespace cv;int main(int argc, char *argv[])
{
//    printMs();Mat mat(3000, 4000, CV_8UC3);int pixelSize = mat.elemSize();QElapsedTimer timer;timer.start();for (int r = 0; r < mat.rows; ++r) {for (int c = 0; c < mat.cols; ++c) {int rowStep = r * mat.step;int colIndex = c * pixelSize ;mat.data[rowStep + colIndex ] = 0;//Bmat.data[rowStep + colIndex + 1] = 255;//Gmat.data[rowStep + colIndex + 2] = 0;//R}}qDebug() << QString("%1: %2ms").arg("step").arg(timer.elapsed());timer.start();for (int r = 0; r < mat.rows; ++r) {for (int c = 0; c < mat.cols; ++c) {Vec3b *pixel = mat.ptr<Vec3b>(r, c);pixel->val[0] = 0;//Bpixel->val[1] = 255;//Gpixel->val[2] = 0;//R}}qDebug() << QString("%1: %2ms").arg("ptr").arg(timer.elapsed());timer.start();for (int r = 0; r < mat.rows; ++r) {for (int c = 0; c < mat.cols; ++c) {Vec3b &pixel = mat.at<Vec3b>(r, c);pixel.val[0] = 0;//Bpixel.val[1] = 255;//Gpixel.val[2] = 0;//R}}qDebug() << QString("%1: %2ms").arg("at").arg(timer.elapsed());timer.start();auto it = mat.begin<Vec3b>(), end = mat.end<Vec3b>();for (; it != end; ++it) {(*it).val[0] = 0;//B(*it).val[1] = 255;//G(*it).val[2] = 255;//R}qDebug() << QString("%1: %2ms").arg("it").arg(timer.elapsed());namedWindow("mat");imshow("mat", mat);waitKey(0);
}
"step: 45ms"
"ptr: 54ms"
"at: 96ms"
"it: 102ms"

1.6、rgb转灰度图

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat img = imread("test.jpeg");Mat gray;cvtColor(img , gray, COLOR_BGR2GRAY);namedWindow("gray");imshow("gray", gray);waitKey(0);
}

在这里插入图片描述

1.7、二值化

二值化含义:把灰度大于阀值的用白色显示,小于阀值的像素用黑色显示。
opencv函数threshold(src, dst, thresh, maxval, type);

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat src = imread("test.jpeg");Mat gray;Mat bin;cvtColor(src, gray, COLOR_BGR2GRAY);threshold(gray, bin, 100, 255, THRESH_BINARY);
//    threshold(gray, bin, 100, 255, THRESH_BINARY_INV);namedWindow("img");imshow("img", bin);waitKey(0);}

在这里插入图片描述

1.8、对比度和亮度

对比度和亮度利用公式来计算:g(i, j) = a * f(i, j) + b
a代表对比度(1.0 ~ 3.0),b代表亮度(0 ~ 100)。

void myConvert(Mat &src, Mat &dst, float a, float b) 
{dst.create(src.rows, src.cols, src.type);for (int r = 0; r < src.rows; ++r) {for (int c = 0; c < src.cols; ++c) {for (int i = 0; i < 3; ++i) {/* saturate_cast<uchar>限制表达式的结果最大为uchar的大小,也就是255 */dst.at<Vec3b>(r,, c)[i]  = saturate_cast<uchar>(a * src.at<Vec3b>(r, c)[i] + b);}}}
}

opencv提供的接口是convertTo。

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat src = imread("test.jpeg");Mat dst;src.convertTo(dst, -1, 2.0, 50);    //类型填负数代表与src一致namedWindow("img");imshow("img", dst);waitKey(0);
}

在这里插入图片描述

1.9、图片缩放

1.9.1、resize

opencv为图片缩放提供了resize(src, dst, dsize, fx = 0, fy = 0, interpolation = INTER_LINEAR)函数。

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat src = imread("test.jpeg");Mat dst;resize(src, dst, Size(300, 300), 0, 0, INTER_NEAREST);namedWindow("src");imshow("src", src);namedWindow("dst");imshow("dst", dst);waitKey(0);
}

在这里插入图片描述
resize的最后一个参数interpolation是缩放使用的算法类型,opencv提供了以下几种算法。

enum InterpolationFlags{/** nearest neighbor interpolation */INTER_NEAREST        = 0,/** bilinear interpolation */INTER_LINEAR         = 1,/** bicubic interpolation */INTER_CUBIC          = 2,/** resampling using pixel area relation. It may be a preferred method for image decimation, asit gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEARESTmethod. */INTER_AREA           = 3,/** Lanczos interpolation over 8x8 neighborhood */INTER_LANCZOS4       = 4,/** Bit exact bilinear interpolation */INTER_LINEAR_EXACT = 5,/** mask for interpolation codes */INTER_MAX            = 7,/** flag, fills all of the destination image pixels. If some of them correspond to outliers in thesource image, they are set to zero */WARP_FILL_OUTLIERS   = 8,/** flag, inverse transformationFor example, #linearPolar or #logPolar transforms:- flag is __not__ set: \f$dst( \rho , \phi ) = src(x,y)\f$- flag is set: \f$dst(x,y) = src( \rho , \phi )\f$*/WARP_INVERSE_MAP     = 16
};

下面对INTER_NEAREST(临近点算法)和INTER_LINEAR(双线性内插值)做介绍。

临近点算法

原理:
在这里插入图片描述

特点:速度最快,会失真,不够平滑。

双线性内插值

原理:用像素点的临近四个点做平均计算。
在这里插入图片描述

特点:速度稍慢一点,平滑效果比临近点算法好,但图像的边界的棱角会被平均而模糊掉。

1.9.2、金字塔缩放

opencv提供了向上重建(拉普拉斯金字塔,放大)的pyrUp()和向下采样(高斯金字塔,缩小)的pyrDown(),可以比较好地还原图像特征,它们无法指定放大的倍数,只能成倍地放大或缩小,比如1616的图片调用pyrUp,就变为6464,而调用pyrDown,就变为4*4。
用法如下:

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat src = imread("test.jpeg");Mat gdst;   //高斯,缩小Mat ldst;   //拉普拉斯,放大pyrDown(src, gdst);pyrUp(src, ldst);namedWindow("src");imshow("src", src);namedWindow("gdst");imshow("gdst", gdst);namedWindow("ldst");imshow("ldst", ldst);waitKey(0);
}

在这里插入图片描述

1.10、图片叠加

原理:
dst = src1 * a + src2 * (1 - a) + gamma;
a代表透明度(0 ~ 1.0),gamma代表增益,用来调整颜色深度。
opencv提供了addWeighted(src1, alpha, src2, beta, gamma, dst, dtype = -1)函数,可以用来叠加图片。

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;int main(int argc, char *argv[])
{Mat src = imread("test1.jpeg");Mat src2 = imread("test.jpeg");Mat src1 = src(Rect(0, 0, src2.cols, src2.rows));	//把在图一中截取图二相同大小的部分Mat dst;float a = 0.5;		//透明度addWeighted(src1, a, src2, 1 - a, 1, dst);namedWindow("blending");imshow("blending", dst);waitKey(0);}

在这里插入图片描述

相关文章:

opencv图片处理

目录1 图片处理1.1 显示图片1.2 旋转图片1.3 合并图片1.4、Mat类1.4.1、像素的储存结构1.4.2、访问像素数据1.6、rgb转灰度图1.7、二值化1.8、对比度和亮度1.9、图片缩放1.9.1、resize临近点算法双线性内插值1.9.2、金字塔缩放1.10、图片叠加1 图片处理 1.1 显示图片 #includ…...

C++ Primer Plus 学习笔记(二)—— 复合类型

数组 当我们只是定义了数组&#xff0c;而没有对数组进行初始化时&#xff0c;那数组的值将是未定义的。 在对数组进行初始化时&#xff0c;如果只对数组的一部分进行初始化&#xff0c;编译器会将把其他元素自动设置为0。 #include <iostream>using namespace std;in…...

代码随想录算法训练营第七天 | 454.四数相加II 、 383. 赎金信、15. 三数之和、18. 四数之和 、总结

打卡第七天&#xff0c;还是哈希表。 今日任务 454.四数相加II383.赎金信15.三数之和18.四数之和总结 454.四数相加II 代码随想录 class Solution { public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, ve…...

apply函数族

apply函数族 apply函数族是R语言中帮助用户实现高效的向量化运算的一系列函数&#xff0c;包括apply,lapply,sapply,vapply等。 apply() apply函数以列或行为单位进行循环操作&#xff0c;可以处理matrix、array数据&#xff0c;返回一个向量或matrix。 apply(data,1/2,fuc…...

读书笔记可读性素材

《深入理解Java虚拟机》 《深入理解Java虚拟机》 《深入理解Java虚拟机》 本地方法栈&#xff08;Native Method Stacks&#xff09; 本地方法栈&#xff08;Native Method Stacks&#xff09; 本地方法栈&#xff08;Native Method Stacks&#xff09; -----------------…...

【C++】vector 模拟实现

vectorvector 容器vector 基本使用vector 定义库中各类接口的使用迭代器容量相关接口元素访问相关接口元素修改相关接口模拟实现 vector前期准备构造与析构赋值运算符重载迭代器相关容量相关元素访问相关元素的修改相关二维数组的创建对于自定义类型数据的测试vector 容器 C S…...

canvas初体验

canvas介绍 Canvas 最初由Apple于2004 年引入&#xff0c;用于Mac OS X WebKit组件&#xff0c;为仪表板小部件和Safari浏览器等应用程序提供支持。后来&#xff0c;它被Gecko内核的浏览器&#xff08;尤其是Mozilla Firefox&#xff09;&#xff0c;Opera和Chrome实现&#x…...

JavaWeb12-线程通讯(线程等待和唤醒)

目录 1.方法介绍 1.1.wait()/wait(long timeout)&#xff1a;让当前线程进入等待状态。 1.1.1.wait执行流程 1.1.2.wait结束等待的条件 1.1.3.wait() VS wait(long timeout) 1.1.4.为什么wait要放在Object中&#xff1f; --->PS&#xff1a;wait(0) 和 sleep(0) 的区…...

江苏专转本如何事半功倍的备考

专转本如何事半功倍的备考 一个人学习成绩的优劣取决于他的学习能力&#xff0c;学习能力包括三个要素&#xff1a;规范的学习行为&#xff1b;良好的学习习惯&#xff1b;有效的学习方法。有了规范的学习行为才能培养出良好的学习习惯&#xff0c;形成了良好的学习习惯就会形成…...

linux下安装mongoDB

一、下载mongoDB包 下载地址&#xff1a; https://www.mongodb.com/try/download/community 个人建议&#xff1a;如果是学习阶段&#xff0c;使用5以下版本更好些。 二、安装及配置 1、安装 # 1、解压 $ tar -zxvf mongodb-linux-x86_64-rhel70-4.4.19-rc1.tgz# 2、迁移目…...

掌握MySQL分库分表(七)广播表、绑定表实战,水平分库+分表实现及之后的查询和删除操作

文章目录什么是广播表广播表实战数据库配置表Java配置实体类配置文件测试广播表水平分库分表配置文件运行测试什么是绑定表&#xff1f;绑定表实战配置数据库配置Java实体类配置文件运行测试水平分库分表后的查询和删除操作查询操作什么是广播表 指所有的分片数据源中都存在的…...

企业为什么需要数据可视化报表

数据可视化报表是在商业环境、市场环境已经改变之后&#xff0c;发展出来为当前企业提供替代解决办法的重要方案。而且信息化、数字化时代&#xff0c;很多企业已经进行了初步的信息化建设&#xff0c;沉淀了大量业务数据&#xff0c;这些数据作为企业的资产&#xff0c;是需要…...

5个有效的华为(HUAWEI)手机数据恢复方法

5个有效的手机数据恢复方法 华为智能手机中的数据丢失比许多人认为的更为普遍。发生这种类型的丢失有多种不同的原因&#xff0c;因此数据恢复软件的重要性。您永远不知道您的智能手机何时会在这方面垮台&#xff1b;因此&#xff0c;预防总比哀叹好&#xff0c;这就是为什么众…...

【Java并发编程】线程安全(一)Synchronized原理

Synchronized底层实现 简单来说&#xff0c;Synchronized关键字的执行主体是线程对象&#xff0c;加锁是通过一个锁对象来完成的是&#xff0c;而锁对象底层关联了一个c源码的monitor的对象&#xff0c;monitor对象底层又对应了操作系统级别的互斥锁&#xff0c;同一时刻只有一…...

[apollo]vue3.x中apollo的使用

[apollo]vue3.x中apollo的使用通过客户端获取Apollo配置环境工具的安装获取Apollo配置相关代码错误提示Uncaught (in promise) Error: Apollo client with id default not found. Use provideApolloClient() if you are outside of a component setup通过开放接口获取Apollo配置…...

system()函数启用新进程占有原进程的文件描述符表的问题

我在A程序中占用了/dev/video0这个独占模式的设备文件&#xff0c;在A中用system函数启用了B程序&#xff0c;B程序的代码中并不包含对/dev/video0的访问&#xff0c;但是我发现B程序也占用了/dev/video0&#xff0c;并且我在A程序中关闭了/dev/video0后&#xff0c;A程序不再占…...

nignx(安装,正反代理,安装tomcat设置反向代理,ip透传)

1安装nginx 安装wget Yum install -y wget 下载(链接从官网找到右键获取) 以下过程root 安装gcc Yum -y install gcc c 安装pcre Yum install -y pcre pcre-devel Openssl Yum install -y openssl openssl-devel 安装zlib Yum install -y zlib zlib-devel 安装make Yum inst…...

sklearn模块常用内容解析笔记

文章目录 回归模型评价指标R2_score预备知识R2_score计算公式r2_score使用方法注意事项参考文献回归模型评价指标R2_score 回归模型的性能的评价指标主要有:RMSE(平方根误差)、MAE(平均绝对误差)、MSE(平均平方误差)、R2_score。但是当量纲不同时,RMSE、MAE、MSE难以衡量模…...

我的 System Verilog 学习记录(2)

引言 从本文开始&#xff0c;就开始系统学习 System Verilog &#xff0c;不只是语法&#xff0c;还有结合 Questa Sim 的实际编程练习、Debug。 本文简单介绍 System Verilog 语言的用途以及学习的必要性。 前文链接&#xff1a; 我的 System Verilog 学习记录&#xff08…...

【调研报告】Monorepo 和 Multirepo 的风格对比及使用示例

带有权重的Monorepo和Multirepo对比 功能/特性MonorepoMultirepoMonorepo权重值Multirepo权重值代码管理管理多个代码库更加复杂管理单个代码库更加简单37依赖管理可以简化依赖管理依赖冲突可能会更加困难73构建和部署构建和部署更加容易构建和部署可能需要更多的配置82团队协…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除

目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作&#xf…...

[KCTF]CORE CrackMe v2.0

这个Reverse比较古老&#xff0c;已经有20多年了&#xff0c;但难度确实不小。 先查壳 upx压缩壳&#xff0c;0.72&#xff0c;废弃版本&#xff0c;工具无法解压。 反正不用IDA进行调试&#xff0c;直接x32dbg中&#xff0c;dump内存&#xff0c;保存后拖入IDA。 这里说一下…...