【opencv】教程代码 —ShapeDescriptors
检测和显示图像的轮廓
在图像中搜索并显示轮廓边缘多边形、轮廓矩形和包围圆
获取包含检测到的轮廓的椭圆和旋转的矩形
图像轮廓检测和轮廓凸包
计算图像中的轮廓的矩(包括面积、重心等)并进行显示
创建和绘制一个多边形图像然后计算并显示图像上每个点到这个多边形的距离
1. findContours_demo.cpp 检测和显示图像的轮廓


这段代码是使用OpenCV库来检测和显示图像的轮廓。这段代码中包含两个主要函数:main函数和thresh_callback函数。
1. main函数用于加载图像,将其转换为灰度图像并对其进行模糊处理,然后在窗口中显示原始图像并创建一个滑块来调整Canny边缘检测的阈值。主要步骤如下:
加载图像:使用OpenCV函数imread加载图像。
转换图像:使用cvtColor函数将图像从BGR色彩空间转换为灰度空间。之后,使用blur函数对图像进行模糊处理以消除噪声。
创建并显示窗口:使用namedWindow和imshow函数创建窗口并显示源图像。
创建滑块:使用createTrackbar函数创建一个滑块来调整边缘检测的阈值。
调用thresh_callback函数。
2. thresh_callback函数用于边缘检测,找到并绘制轮廓。主要步骤如下:
边缘检测:通过Canny函数检测边缘。
找到轮廓:使用findContours函数找到图像中的轮廓。
绘制轮廓:初始化一个与原图大小、类型相同的全零矩阵。然后在该矩阵上绘制找到的轮廓。每个轮廓有不同的颜色。
显示窗口:调用imshow函数显示绘制过的轮廓图像。
最后,代码中还编写了一些错误处理机制,例如,如果找不到图像,则返回-1并退出程序。
/*** @function findContours_Demo.cpp* @brief 这是一个演示如何在图像中找到轮廓的示例代码* @author OpenCV团队*/#include "opencv2/imgcodecs.hpp" // 引入opencv图像编解码库
#include "opencv2/highgui.hpp" // 引入opencv高级GUI库
#include "opencv2/imgproc.hpp" // 引入opencv图像处理库
#include <iostream> // 引入标准输入输出库using namespace cv; // 使用cv命名空间,该命名空间包含所有OpenCV函数和类
using namespace std; // 使用std命名空间,该命名空间包含所有标准C++库函数和类Mat src_gray; // 声明全局变量src_gray,用于存储灰度图像
int thresh = 100; // 声明全局变量thresh,设定轮廓检测的阈值
RNG rng(12345); // 初始化随机数生成器/// 函数声明
void thresh_callback(int, void* );/*** @function main*/
int main( int argc, char** argv ) // 主函数
{/// 加载源图像CommandLineParser parser( argc, argv, "{@input | HappyFish.jpg | input image}" ); // 创建命令行解析器,解析输入的图像文件路径Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) ); // 读取图像文件if( src.empty() ) // 如果读取的图像为空{cout << "Could not open or find the image!\n" << endl; // 输出错误信息cout << "Usage: " << argv[0] << " <Input image>" << endl; // 输出正确的使用方法return -1;}/// 将图像转换为灰度图并进行模糊处理cvtColor( src, src_gray, COLOR_BGR2GRAY ); // 将图像转换为灰度图blur( src_gray, src_gray, Size(3,3) ); // 对图像进行模糊处理,减少噪声/// 创建窗口const char* source_window = "Source"; // 源图像窗口的名称namedWindow( source_window ); // 创建源图像窗口imshow( source_window, src ); // 显示源图像const int max_thresh = 255; // 设定最大阈值createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback ); // 创建滑动条,调节Canny检测器的阈值thresh_callback( 0, 0 ); // 调用thresh_callback函数,进行轮廓检测waitKey(); // 等待用户按键,以便可以看到图像return 0;
}/*** @function thresh_callback* 轮廓检测回调函数*/
void thresh_callback(int, void* )
{/// 使用Canny算子检测边缘Mat canny_output; // 声明变量,存储Canny检测结果Canny( src_gray, canny_output, thresh, thresh*2 ); // 运用Canny算子进行边缘检测/// 查找轮廓vector<vector<Point> > contours; // 存储找到的轮廓vector<Vec4i> hierarchy; // 存储轮廓的层级信息findContours( canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE ); // 查找轮廓/// 绘制轮廓Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); // 创建空白画布,用来绘制轮廓for( size_t i = 0; i< contours.size(); i++ ) // 遍历找到的所有轮廓{Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) ); // 生成随机颜色drawContours( drawing, contours, (int)i, color, 2, LINE_8, hierarchy, 0 ); // 在drawing上绘制轮廓}/// 显示在窗口中imshow( "Contours", drawing ); // 显示绘制轮廓后的画面
} 这段代码主要功能是载入一个图像进行灰度和模糊处理,然后使用Canny算子进行边缘检测,并找出图像的轮廓,最后将轮廓在窗口中显示出来。图像的路径可以通过命令行参数传入,如果没有参数则默认加载名为"HappyFish.jpg"的图像。在检测轮廓的过程中,可以通过滑动条实时调整Canny算子的阈值,以达到最佳的轮廓检测效果。


2. generalContours_demo1.cpp在图像中搜索并显示轮廓边缘多边形、轮廓矩形和包围圆


这段代码主要用于在图像中寻找轮廓。作者使用OpenCV库编写了代码。下面是我对您提供的代码片段的详细解析和总结:
整个代码中包含两个主要函数:"main" 和 "thresh_callback"。
"main" 函数:
该函数的主要任务是加载图片,将图片转换为灰度图像,模糊处理,并创建窗口显示源图像。接着创建了一个滑条用于调节阈值。完成以上设置后,程序将调用“thresh_callback”回调函数处理边缘检测和轮廓提取。最后,通过waitKey()函数等待用户按键操作。
关键过程如下:
- 加载图像: 使用imread函数读取输入的图像文件。
- 灰度转换: 调用cvtColor函数将RGB图像转化为灰度图像。
- 模糊处理: 使用blur函数对灰度图像进行模糊处理,以去除图像中的噪声。
- 显示窗口: 使用namedWindow创建一个图像窗口,imshow在该窗口中显示源图像。
- 创建滑条: 使用createTrackbar函数创建了滑动条,可以调节Canny边缘检测阈值。
"thresh_callback" 函数:
这个函数执行的主要任务是使用Canny算法进行边缘检测,接着找到图像的轮廓。最后,通过绘制多边形轮廓,包围矩形和圆,将处理后的图像显示在窗口中。
关键过程如下:
- 边缘检测: 调用Canny函数对图像进行边缘检测,生成边缘图像。
- 轮廓提取: 使用findContours函数在二值化图像canny_output中寻找轮廓。
- 对轮廓进行处理: 利用approxPolyDP将轮廓近似为多边形,使用boundingRect获取轮廓的最小外接矩形,使用minEnclosingCircle获取轮廓的最小外接圆。
- 绘制结果:绘制所有的包围矩形,圆和对应的多边形轮廓到图像上。
- 结果展示: 使用imshow函数在窗口中展示处理结果。
/*** @function generalContours_demo1.cpp* @brief Demo code to find contours in an image(用于在图片中找到轮廓的演示代码)* @author OpenCV team (OpenCV团队)*/#include "opencv2/imgcodecs.hpp" // 引入处理图像编码的头文件
#include "opencv2/highgui.hpp" // 引入GUI的头文件
#include "opencv2/imgproc.hpp" // 引入处理图像的头文件
#include <iostream> // 引入基础输入输出流的头文件using namespace cv; // 使用cv命名空间
using namespace std; // 使用std命名空间Mat src_gray; // 声明灰度图像对象
int thresh = 100; // 设置阈值
RNG rng(12345); // 初始化随机数生成器/// Function header
void thresh_callback(int, void* );// 声明阈值处理函数/*** @function main*/
int main( int argc, char** argv ) // 主函数开始
{/// Load source image (加载源图片)CommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );if( src.empty() ) // 如果无法加载图片,则输出错误信息并返回-1退出程序{cout << "Could not open or find the image!\n" << endl;cout << "usage: " << argv[0] << " <Input image>" << endl;return -1;}/// Convert image to gray and blur it (将图片转为灰度并进行模糊处理)cvtColor( src, src_gray, COLOR_BGR2GRAY ); // BGR转换成灰度blur( src_gray, src_gray, Size(3,3) ); // 对灰度图进行模糊处理/// Create Window (创建窗口)const char* source_window = "Source";namedWindow( source_window );imshow( source_window, src ); // 展示原图/// Create Trackbar (创建滑动条)const int max_thresh = 255;createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );thresh_callback( 0, 0 ); // 调用阈值处理函数waitKey(); // 等待用户操作return 0; // 程序正常退出
}/*** @function thresh_callback*/
void thresh_callback(int, void* ) // 阈值处理函数定义
{/// Detect edges using Canny (使用Canny算法进行边缘检测)Mat canny_output; Canny( src_gray, canny_output, thresh, thresh*2 ); /// Find contours (查找轮廓)vector<vector<Point> > contours;findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE ); /// Approximate contours to polygons + get bounding rects and circles (将轮廓近似为多边形,并找到它们的边界矩形和圆)vector<vector<Point> > contours_poly( contours.size() ); // 用于存储多边形轮廓的向量vector<Rect> boundRect( contours.size() ); // 用于存储边界矩形的向量vector<Point2f>centers( contours.size() ); // 用于存储圆心的向量vector<float>radius( contours.size() ); // 用于存储半径的向量for( size_t i = 0; i < contours.size(); i++ ) // 遍历每一个轮廓{approxPolyDP( contours[i], contours_poly[i], 3, true ); // 近似多边形boundRect[i] = boundingRect( contours_poly[i] ); // 计算边界矩形minEnclosingCircle( contours_poly[i], centers[i], radius[i] ); // 计算最小闭合圆}Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); // 创建一个全零矩阵,用于绘制结果图/// Draw polygonal contour + bonding rects + circles (绘制多边形轮廓、边界矩形和圆)for( size_t i = 0; i< contours.size(); i++ ){Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) ); //生成随机颜色drawContours( drawing, contours_poly, (int)i, color ); // 绘制轮廓rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2 ); // 绘制矩形circle( drawing, centers[i], (int)radius[i], color, 2 ); // 绘制圆}/// Show in a window (显示结果图)imshow( "Contours", drawing ); // 显示轮廓图
} 这段代码是一个在图像中搜索并显示轮廓的OpenCV程序,它首先将给定图像转换为灰度图像,然后使用Canny算法检测其边缘,进而使用函数findContours查找这些边缘。找到的边缘以多边形形式近似,并计算其边界矩形和包围圆。最后,所有的轮廓、边框矩形和包围圆都绘制在一张空白图像上并显示出来。
3. generalContours_demo2.cpp 获取包含检测到的轮廓的椭圆和旋转的矩形


这段代码是一个OpenCV的演示程序,用于获取包含检测到的轮廓的椭圆和旋转的矩形。主要包含以下函数:
thresh_callback: 该函数用于检测边缘及寻找轮廓,并通过minAreaRect和fitEllipse方法获取每个轮廓的旋转矩阵和椭圆,然后绘制轮廓、椭圆和旋转矩形。main: 该函数用于加载源图像并转换为灰度图,然后进行模糊处理,最后创建一个窗口并在其中显示源图像。还在窗口中创建了一个跟踪条,用于调整Canny算法的阈值参数。
具体来讲,我来详细解释下这两个函数的工作流程与方法:
main: 首先加载输入的图像,并将其转换为灰度图像,然后对该灰度图像进行模糊处理。然后创建一个窗口在其中显示转换后的图像,并在这个窗口中创建一个跟踪条,来调整使用Canny方法进行边缘检测的阈值。在跟踪条的回调函数中,调用了thresh_callback方法进行边缘检测和轮廓寻找。thresh_callback: 在这个函数中,首先使用Canny方法进行边缘检测。然后使用findContours方法寻找图像的轮廓。接着使用minAreaRect方法获取每个轮廓的最小面积旋转矩形,如果轮廓的点数大于5,则使用fitEllipse方法获取该轮廓的拟合椭圆。然后创建一个全零的Mat对象,然后在这个Mat对象上绘制轮廓、椭圆及旋转矩形。最后将这个Mat对象在窗口中显示。
该程序主要用于练习边缘检测、寻找轮廓以及如何在寻找到的轮廓上拟合旋转矩形和椭圆。
/**
* @function generalContours_demo2.cpp
* @brief 这是一个演示代码,用于获取包含检测到的轮廓的椭圆和旋转矩形
* @author OpenCV 团队
*/ #include "opencv2/imgcodecs.hpp" // 包括OpenCV的读写头文件
#include "opencv2/highgui.hpp" // 包括OpenCV的GUI头文件
#include "opencv2/imgproc.hpp" // 包括OpenCV的图像处理头文件
#include <iostream> // 包括输入输出流头文件using namespace cv; // 声明使用OpenCV的命名空间
using namespace std; // 声明使用标准模板库命名空间Mat src_gray; // 创建一个空的Mat对象,用于存放灰度图像
int thresh = 100; // 设定初始阈值为100
RNG rng(12345); // 创建一个随机数生成器对象/// 函数声明
void thresh_callback(int, void* );/*** @function main*/
int main( int argc, char** argv )
{/// 加载源图像并转化为灰度 CommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );if( src.empty() ) // 检查读取的图像是否为空{cout << "Could not open or find the image!\n" << endl; // 输出错误信息cout << "Usage: " << argv[0] << " <Input image>" << endl; // 提示正确的使用方式return -1;}/// 将图像转化为灰度图并模糊处理cvtColor( src, src_gray, COLOR_BGR2GRAY ); // 将图像从BGR色彩空间转化为灰度空间blur( src_gray, src_gray, Size(3,3) ); // 对图像进行模糊(平滑)处理/// 创建窗口 const char* source_window = "Source";namedWindow( source_window );imshow( source_window, src );const int max_thresh = 255; // 设定阈值调节的最大值createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );thresh_callback( 0, 0 );waitKey(); // 等待键盘操作return 0;
}/*** @function thresh_callback*/
void thresh_callback(int, void* )
{/// 用Canny算子进行边缘检测Mat canny_output;Canny( src_gray, canny_output, thresh, thresh*2 );/// 找到轮廓vector<vector<Point> > contours;findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );/// 计算每个轮廓对应的旋转矩形和椭圆形状vector<RotatedRect> minRect( contours.size() ); // 创建一个旋转矩形的向量,数量等于轮廓数量vector<RotatedRect> minEllipse( contours.size() ); // 创建一个轮廓对应椭圆的向量,数量等于轮廓数量for( size_t i = 0; i < contours.size(); i++ ) // 遍历每一个轮廓{minRect[i] = minAreaRect( contours[i] ); // 计算每个轮廓的最小区域旋转矩形if( contours[i].size() > 5 ) // 当轮廓包含的点多于5个时,即可以拟合为椭圆{minEllipse[i] = fitEllipse( contours[i] ); // 计算每个轮廓的拟合椭圆}}/// 画出轮廓 + 旋转矩形 + 椭圆Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); // 创建一个空白画布,尺寸与canny_output相同for( size_t i = 0; i< contours.size(); i++ ){Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) ); // 生成一个随机颜色// 画出轮廓drawContours( drawing, contours, (int)i, color );// 画出椭圆ellipse( drawing, minEllipse[i], color, 2 );// 画出旋转矩形Point2f rect_points[4];minRect[i].points( rect_points );for ( int j = 0; j < 4; j++ ){line( drawing, rect_points[j], rect_points[(j+1)%4], color );}}/// 在窗口中展示结果 imshow( "Contours", drawing );
} 此代码段是一个 OpenCV 的示例,演示了如何查找图像中的所有轮廓并查找每个轮廓的最小区域旋转矩形和拟合椭圆。在迭代访问每个轮廓的过程中,根据轮廓大小检查是否可以拟合椭圆(轮廓中的点数大于5)。最后,它会在新创建的 Mat 对象上绘制轮廓、旋转的矩形和椭圆,然后在窗口中显示这个 Mat 对象。
4. hull_demo.cpp 图像轮廓检测和轮廓凸包


/*** @function hull_demo.cpp // 声明hull_demo.cpp这个函数* @brief Demo code to find contours in an image // 对图像进行轮廓检测的演示代码* @author OpenCV team // 作者为OpenCV团队*/#include "opencv2/imgcodecs.hpp" // 导入编解码库
#include "opencv2/highgui.hpp" // 导入高级GUI库
#include "opencv2/imgproc.hpp" // 导入图像处理库
#include <iostream> // 导入输入输出库using namespace cv;
using namespace std;Mat src_gray; // 定义源图像的灰度图
int thresh = 100; // 定义阈值为100
RNG rng(12345); // 定义一个随机数/// Function header
void thresh_callback(int, void* ); // 声明一个阈值回调函数/*** @function main // 主函数*/
int main( int argc, char** argv )
{/// Load source image and convert it to gray // 加载源图像并转化为灰度图CommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );if( src.empty() ){cout << "Could not open or find the image!\n" << endl;cout << "Usage: " << argv[0] << " <Input image>" << endl;return -1;}/// Convert image to gray and blur it // 将图像转为灰度并进行模糊处理cvtColor( src, src_gray, COLOR_BGR2GRAY );blur( src_gray, src_gray, Size(3,3) );/// Create Window // 创建窗口const char* source_window = "Source";namedWindow( source_window );imshow( source_window, src );const int max_thresh = 255; // 定义阈值上限createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback ); // 创建滑动条thresh_callback( 0, 0 );waitKey(); // 等待用户按键退出return 0;
}/*** @function thresh_callback // 阈值回调函数*/
void thresh_callback(int, void* )
{/// Detect edges using Canny // 使用Canny方法进行边缘检测Mat canny_output;Canny( src_gray, canny_output, thresh, thresh*2 );/// Find contours // 寻找轮廓vector<vector<Point> > contours;findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );/// Find the convex hull object for each contour // 对每个轮廓寻找凸包物体vector<vector<Point> >hull( contours.size() );for( size_t i = 0; i < contours.size(); i++ ){convexHull( contours[i], hull[i] );}/// Draw contours + hull results // 将轮廓和凸包结果绘制出来Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );for( size_t i = 0; i< contours.size(); i++ ){Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );drawContours( drawing, contours, (int)i, color );drawContours( drawing, hull, (int)i, color );}/// Show in a window // 在窗口中显示结果imshow( "Hull demo", drawing );
} 上述代码是一个使用OpenCV进行图像轮廓检测的示例。主函数中先将图像从彩色图转化为灰度图,并进行了模糊处理,然后通过Canny边缘检测器寻找图像的边缘,定义阈值滑动条来动态改变Canny检测的阈值。接着通过findContours函数找到所有的轮廓,convexHull函数找到每个轮廓的凸包物体,最后将所有的轮廓和凸包物体绘制在一个全黑的图像上,颜色随机生成,然后在窗口中展示出来。
5. moments_demo.cpp计算图像中的轮廓的矩(包括面积、重心等)并进行显示


此源文件是用来演示如何使用OpenCV库进行图像轮廓分析的。其中定义了两个函数:main和thresh_callback。
main函数是程序的入口函数。尝试从命令行参数中读取输入的图像文件(如果没有给出图像,则默认读取stuff.jpg),然后将图像转化为灰度图,最后对其进行模糊处理。创建一个窗口显示原始图像,并创建一个滑动条来调整Canny算子阈值。然后调用thresh_callback函数对图像进行处理,并等待用户关闭窗口。thresh_callback函数负责接受Canny算子阈值,并使用该值对灰度图像进行边缘检测。然后,它找到检测到的边缘的轮廓,并计算出这些轮廓的几何中心。最后,它在一个新的图像上绘制出这些轮廓,并在每个轮廓的几何中心处画一个圆点。画出的图像会在一个新窗口中显示出来。然后,此函数将根据计算出来的几何中心,对于每一个轮廓,打印其面积(即轮廓内部的像素点数)以及轮廓的长度(即轮廓上的像素点数)。
/*** @function moments_demo.cpp* @brief 演示如何计算图像的矩* @author OpenCV团队*/#include "opencv2/imgcodecs.hpp" // 引入OpenCV中用于图像编码解码的函数库
#include "opencv2/highgui.hpp" // 引入OpenCV中用于创建GUI界面的函数库
#include "opencv2/imgproc.hpp" // 引入OpenCV的图像处理库
#include <iostream> // 引入C++标准库中提供的函数对象来进行输入/输出的库
#include <iomanip> // using namespace cv; // 使用OpenCV中的所有函数和类
using namespace std; // 使用C++标准库中的所有函数和类Mat src_gray; // 定义存储灰度图的Mat类型变量
int thresh = 100; // 定义阈值
RNG rng(12345); // 定义随机数生成器/// 函数声明
void thresh_callback(int, void* );/*** @function main* 主函数*/
int main( int argc, char** argv )
{/// 加载源图片CommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );// 读取图片Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );if( src.empty() ) // 如果图片为空{cout << "Could not open or find the image!\n" << endl; // 打印错误信息cout << "usage: " << argv[0] << " <Input image>" << endl; // 打印使用说明return -1; // 返回-1退出}/// 将图片转换为灰度图并进行模糊处理cvtColor( src, src_gray, COLOR_BGR2GRAY ); // 转为灰度图blur( src_gray, src_gray, Size(3,3) ); // 进行模糊处理/// 创建窗口const char* source_window = "Source"; // 定义窗口名称namedWindow( source_window ); // 创建窗口imshow( source_window, src ); // 在窗口中显示图像const int max_thresh = 255; // 定义最大阈值// 创建阈值滑动条,并绑定thresh_callback函数createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );// 调用thresh_callback函数thresh_callback( 0, 0 );// 等待用户动作waitKey();return 0;
}/*** @function thresh_callback* 阈值回调函数*/
void thresh_callback(int, void* )
{/// 使用Canny算子检测边缘Mat canny_output; // 声明一个Mat对象用来存储Canny检测的结果Canny( src_gray, canny_output, thresh, thresh*2, 3 ); // 执行Canny边缘检测/// 寻找轮廓vector<vector<Point> > contours; // 定义容器存储寻找到的轮廓// 使用findContours函数在二值图像中寻找轮廓findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );/// 计算矩vector<Moments> mu(contours.size() ); // 定义一个容器存储所有轮廓的矩for( size_t i = 0; i < contours.size(); i++ ) // 遍历所有的轮廓{mu[i] = moments( contours[i] ); // 计算每一个轮廓的矩}/// 获取质心vector<Point2f> mc( contours.size() ); // 申明一个容器存储每一个轮廓的质心for( size_t i = 0; i < contours.size(); i++ ) // 遍历所有轮廓{// 计算每个轮廓的质心,避免零除错误mc[i] = Point2f( static_cast<float>(mu[i].m10 / (mu[i].m00 + 1e-5)),static_cast<float>(mu[i].m01 / (mu[i].m00 + 1e-5)) );cout << "mc[" << i << "]=" << mc[i] << endl; // 输出计算结果}/// 画出轮廓Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); // 创建一个用于绘制轮廓的黑色画布for( size_t i = 0; i< contours.size(); i++ ) // 遍历所有轮廓{// 随机生成颜色值Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );drawContours( drawing, contours, (int)i, color, 2 ); // 将轮廓画到画布上circle( drawing, mc[i], 4, color, -1 ); // 将质心画到画布上}/// 在窗口中显示结果imshow( "Contours", drawing );/// 使用矩的00计算面积,并与OpenCV函数的结果比较cout << "\t Info: Area and Contour Length \n";for( size_t i = 0; i < contours.size(); i++ ) // 遍历所有轮廓{cout << " * Contour[" << i << "] - Area (M_00) = " << std::fixed << std::setprecision(2) << mu[i].m00<< " - Area OpenCV: " << contourArea(contours[i]) << " - Length: " << arcLength( contours[i], true ) << endl;}
} 这段代码是使用OpenCV的C++接口进行图像处理的示例程序,它主要的功能是计算图像中的轮廓的矩(包括面积、重心等)并进行显示。具体步骤包括:读入图像、转成灰度图、进行模糊处理、使用Canny算法进行边缘检测、寻找和绘制轮廓、计算轮廓的矩并获取质心、比较矩计算的面积和OpenCV函数计算的面积。
终端输出:
mc[0]=[328.222, 331.944]
mc[1]=[334.476, 323.523]
mc[2]=[213.035, 312.397]
mc[3]=[194.211, 171.352]
mc[4]=[75.8505, 101.182]
mc[5]=[75.9116, 101.259]
mc[6]=[197.533, 57.6664]
mc[7]=[197.166, 64.3331]
mc[8]=[225.274, 57.9121]Info: Area and Contour Length* Contour[0] - Area (M_00) = 9.00 - Area OpenCV: 9.00 - Length: 148.08* Contour[1] - Area (M_00) = 7.00 - Area OpenCV: 7.00 - Length: 140.77* Contour[2] - Area (M_00) = 23.50 - Area OpenCV: 23.50 - Length: 176.75* Contour[3] - Area (M_00) = 269.00 - Area OpenCV: 269.00 - Length: 1217.62* Contour[4] - Area (M_00) = 233.00 - Area OpenCV: 233.00 - Length: 80.91* Contour[5] - Area (M_00) = 207.50 - Area OpenCV: 207.50 - Length: 72.67* Contour[6] - Area (M_00) = 2.50 - Area OpenCV: 2.50 - Length: 35.56* Contour[7] - Area (M_00) = 3.00 - Area OpenCV: 3.00 - Length: 38.97* Contour[8] - Area (M_00) = 64.50 - Area OpenCV: 64.50 - Length: 511.63
mc[0]=[328.22, 331.94]
mc[1]=[334.48, 323.52]
mc[2]=[213.04, 312.40]
mc[3]=[194.21, 171.35]
mc[4]=[75.85, 101.18]
mc[5]=[75.91, 101.26]
mc[6]=[197.53, 57.67]
mc[7]=[197.17, 64.33]
mc[8]=[225.27, 57.91]Info: Area and Contour Length* Contour[0] - Area (M_00) = 9.00 - Area OpenCV: 9.00 - Length: 148.08* Contour[1] - Area (M_00) = 7.00 - Area OpenCV: 7.00 - Length: 140.77* Contour[2] - Area (M_00) = 23.50 - Area OpenCV: 23.50 - Length: 176.75* Contour[3] - Area (M_00) = 269.00 - Area OpenCV: 269.00 - Length: 1217.62* Contour[4] - Area (M_00) = 233.00 - Area OpenCV: 233.00 - Length: 80.91* Contour[5] - Area (M_00) = 207.50 - Area OpenCV: 207.50 - Length: 72.67* Contour[6] - Area (M_00) = 2.50 - Area OpenCV: 2.50 - Length: 35.56* Contour[7] - Area (M_00) = 3.00 - Area OpenCV: 3.00 - Length: 38.97* Contour[8] - Area (M_00) = 64.50 - Area OpenCV: 64.50 - Length: 511.63
mc[0]=[328.22, 331.94]
mc[1]=[334.48, 323.52]
mc[2]=[213.04, 312.40]
mc[3]=[194.21, 171.35]
mc[4]=[75.85, 101.18]
mc[5]=[75.91, 101.26]
mc[6]=[197.53, 57.67]
mc[7]=[197.17, 64.33]
mc[8]=[225.27, 57.91]Info: Area and Contour Length* Contour[0] - Area (M_00) = 9.00 - Area OpenCV: 9.00 - Length: 148.08* Contour[1] - Area (M_00) = 7.00 - Area OpenCV: 7.00 - Length: 140.77* Contour[2] - Area (M_00) = 23.50 - Area OpenCV: 23.50 - Length: 176.75* Contour[3] - Area (M_00) = 269.00 - Area OpenCV: 269.00 - Length: 1217.62* Contour[4] - Area (M_00) = 233.00 - Area OpenCV: 233.00 - Length: 80.91* Contour[5] - Area (M_00) = 207.50 - Area OpenCV: 207.50 - Length: 72.67* Contour[6] - Area (M_00) = 2.50 - Area OpenCV: 2.50 - Length: 35.56* Contour[7] - Area (M_00) = 3.00 - Area OpenCV: 3.00 - Length: 38.97* Contour[8] - Area (M_00) = 64.50 - Area OpenCV: 64.50 - Length: 511.63
mc[0]=[328.22, 331.94]
mc[1]=[334.48, 323.52]
mc[2]=[213.04, 312.40]
mc[3]=[194.21, 171.35]
mc[4]=[75.85, 101.18]
mc[5]=[75.91, 101.26]
mc[6]=[197.53, 57.67]
mc[7]=[197.17, 64.33]
mc[8]=[225.27, 57.91]Info: Area and Contour Length* Contour[0] - Area (M_00) = 9.00 - Area OpenCV: 9.00 - Length: 148.08* Contour[1] - Area (M_00) = 7.00 - Area OpenCV: 7.00 - Length: 140.77* Contour[2] - Area (M_00) = 23.50 - Area OpenCV: 23.50 - Length: 176.75* Contour[3] - Area (M_00) = 269.00 - Area OpenCV: 269.00 - Length: 1217.62* Contour[4] - Area (M_00) = 233.00 - Area OpenCV: 233.00 - Length: 80.91* Contour[5] - Area (M_00) = 207.50 - Area OpenCV: 207.50 - Length: 72.67* Contour[6] - Area (M_00) = 2.50 - Area OpenCV: 2.50 - Length: 35.56* Contour[7] - Area (M_00) = 3.00 - Area OpenCV: 3.00 - Length: 38.97* Contour[8] - Area (M_00) = 64.50 - Area OpenCV: 64.50 - Length: 511.63
mc[0]=[328.22, 331.94]
mc[1]=[334.48, 323.52]
mc[2]=[213.04, 312.40]
mc[3]=[194.21, 171.35]
mc[4]=[75.85, 101.18]
mc[5]=[75.91, 101.26]
mc[6]=[197.53, 57.67]
mc[7]=[197.17, 64.33]
mc[8]=[225.27, 57.91]Info: Area and Contour Length* Contour[0] - Area (M_00) = 9.00 - Area OpenCV: 9.00 - Length: 148.08* Contour[1] - Area (M_00) = 7.00 - Area OpenCV: 7.00 - Length: 140.77* Contour[2] - Area (M_00) = 23.50 - Area OpenCV: 23.50 - Length: 176.75* Contour[3] - Area (M_00) = 269.00 - Area OpenCV: 269.00 - Length: 1217.62* Contour[4] - Area (M_00) = 233.00 - Area OpenCV: 233.00 - Length: 80.91* Contour[5] - Area (M_00) = 207.50 - Area OpenCV: 207.50 - Length: 72.67* Contour[6] - Area (M_00) = 2.50 - Area OpenCV: 2.50 - Length: 35.56* Contour[7] - Area (M_00) = 3.00 - Area OpenCV: 3.00 - Length: 38.97* Contour[8] - Area (M_00) = 64.50 - Area OpenCV: 64.50 - Length: 511.63
mc[0]=[328.22, 331.94]
mc[1]=[334.48, 323.52]
mc[2]=[213.04, 312.40]
mc[3]=[194.21, 171.35]
mc[4]=[75.88, 101.20]
mc[5]=[75.91, 101.26]
mc[6]=[197.53, 57.67]
mc[7]=[197.17, 64.33]
mc[8]=[225.27, 57.91]Info: Area and Contour Length* Contour[0] - Area (M_00) = 9.00 - Area OpenCV: 9.00 - Length: 148.08* Contour[1] - Area (M_00) = 7.00 - Area OpenCV: 7.00 - Length: 140.77* Contour[2] - Area (M_00) = 23.50 - Area OpenCV: 23.50 - Length: 174.75* Contour[3] - Area (M_00) = 269.00 - Area OpenCV: 269.00 - Length: 1217.62* Contour[4] - Area (M_00) = 232.50 - Area OpenCV: 232.50 - Length: 79.50* Contour[5] - Area (M_00) = 207.50 - Area OpenCV: 207.50 - Length: 72.67* Contour[6] - Area (M_00) = 2.50 - Area OpenCV: 2.50 - Length: 35.56* Contour[7] - Area (M_00) = 3.00 - Area OpenCV: 3.00 - Length: 38.97* Contour[8] - Area (M_00) = 64.50 - Area OpenCV: 64.50 - Length: 511.63 6. pointPolygonTest_demo.cpp 创建和绘制一个多边形图像然后计算并显示图像上每个点到这个多边形的距离

这段代码是一个C++程序,使用了OpenCV库,主要实现了创建和绘制一个多边形图像然后计算并显示图像上每个点到这个多边形的距离。
主要步骤如下:
创建一个4r x 4r的全零矩阵作为图像(r=100,因此图像的大小为400x400;
定义一个六边形的顶点,并将几何图形画在图像上;
使用
findContours方法从图像中提取轮廓;计算图像上每个点到轮廓的距离,并存储在一个单独的矩阵中;
查找离多边形最远和最近的点,获取最大和最小的距离值;
为距离图像上色,表示点到多边形的距离,其中蓝色表示该点在多边形内部,红色表示在外部,白色表示在边界上;
在距离最远的点处画一个圆,圆心为此点,半径为最大距离;
最后展示原始图像和距离图像。
典型的方法和数据结构包括:
Mat:是OpenCV库中的一个主要数据结构,用于存储图像和矩阵数据;
Point:OpenCV中的一个数据结构,储存2D点的坐标(x,y);
findContours:OpenCV的一个函数,用于在二值图像中查找轮廓;
pointPolygonTest:OpenCV中的一个函数,用于计算2D点到一个多边形的最短距离;
imshow:OpenCV的一个函数,用于显示图像;
waitKey:OpenCV的一个函数,用于等待用户按键,如果没有这行代码,imshow显示的图像窗口会立即消失;如果参数为0,表示窗口将持续显示,直到用户关闭它为止。
同时需要注意的是,这段代码只针对单通道黑白图像进行处理。如果要处理多通道图像,还需要进行相应的修改。
/*** @function pointPolygonTest_demo.cpp //定义了程序的入口函数main函数* @brief Demo用来距离检测函数示例——相当简单 //描述了这段代码的主要功能* @author OpenCV team //说明这段代码的作者*/// 导入opencv的用户选择界面(UI)库和图像处理库
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"// 导入C++标准输入输出库
#include <iostream> // 名字空间的定义,方便在代码中使用opencv和std库的函数和对象
using namespace cv;
using namespace std; /*** @function main //定义了程序的入口函数main函数*/
int main( void ) //定义了程序的入口函数main函数
{/// 创建一个图像// 初始化图像src的大小与类型 const int r = 100; //定义了一个常量r,用于确定绘制图形边长的依赖参数Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8U ); //使用opencv的Mat类创建一个4r*4r大小的8位无符号整型全黑色(所有像素值都为0)图像,作为绘制六边形的画布/// 创建一系列的坐标点来生成一个轮廓// 建立一个包含6个Point2f对象的vert数组,用于存储六边形的六个顶点坐标vector<Point2f> vert(6);// 为数组的每个元素赋值,确定各顶点的坐标vert[0] = Point( 3*r/2, static_cast<int>(1.34*r) ); vert[1] = Point( 1*r, 2*r );vert[2] = Point( 3*r/2, static_cast<int>(2.866*r) );vert[3] = Point( 5*r/2, static_cast<int>(2.866*r) );vert[4] = Point( 3*r, 2*r );vert[5] = Point( 5*r/2, static_cast<int>(1.34*r) );/// 在src上绘制图形// 对vert数组中的每个元素都执行循环操作,用line函数在src图像上绘制从第i个顶点到下一个顶点的线段,颜色为白色,线条粗细为3。总的效果就是在src上绘制了一个白色边框的六边形for( int i = 0; i < 6; i++ ){line( src, vert[i], vert[(i+1)%6], Scalar( 255 ), 3 );}/// 获取轮廓// 建立一个contours二维数组,作为存储src中所有轮廓的容器vector<vector<Point> > contours;// 使用findContours方法在src图像中寻找轮廓,findContours会先使用阈值将图像二值化,然后寻找二值化图像中的轮廓。经过该操作后,contours中将包含src图像中所有轮廓的顶点坐标的列表findContours( src, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);/// 计算到轮廓的最短距离// 创建raw_dist图像,用于存储src中每个点到最近轮廓的最短距离Mat raw_dist( src.size(), CV_32F );// 对src中的每个像素都执行循环操作:for( int i = 0; i < src.rows; i++ ){for( int j = 0; j < src.cols; j++ ){// 使用pointPolygonTest方法计算src中点(j,i)到最近轮廓的最短距离,然后将计算结果存入raw_dist相应位置raw_dist.at<float>(i,j) = (float)pointPolygonTest( contours[0], Point2f((float)j, (float)i), true );}}// 创建minVal和maxVal两个变量,作为存储raw_dist中的最小值和最大值的容器double minVal, maxVal;// 创建maxDistPt对象,作为存储最大距离对应坐标的容器Point maxDistPt;// minMaxLoc方法会在raw_dist矩阵中寻找最小和最大值,然后分别赋值给minVal和maxVal。同时,minMaxLoc找到的最大值的坐标将赋值给maxDistPtminMaxLoc(raw_dist, &minVal, &maxVal, NULL, &maxDistPt);// minVal和maxVal都取绝对值minVal = abs(minVal);maxVal = abs(maxVal);// 创建drawing空白图像,用于后续的绘制操作Mat drawing = Mat::zeros( src.size(), CV_8UC3 );// 对于src图像中的每个像素,依次执行以下操作for( int i = 0; i < src.rows; i++ ){for( int j = 0; j < src.cols; j++ ){// 如果raw_dist中存储的距离值小于零,则在drawing中的对应位置绘制蓝色,蓝色程度按照距离值的绝对值的大小确定if( raw_dist.at<float>(i,j) < 0 ){drawing.at<Vec3b>(i,j)[0] = (uchar)(255 - abs(raw_dist.at<float>(i,j)) * 255 / minVal);}// 如果raw_dist中存储的距离值大于零,则在drawing中的对应位置绘制红色,红色程度按照距离值的大小确定else if( raw_dist.at<float>(i,j) > 0 ){drawing.at<Vec3b>(i,j)[2] = (uchar)(255 - raw_dist.at<float>(i,j) * 255 / maxVal);}// 如果raw_dist中存储的距离值等于零,则在drawing中的对应位置绘制白色else{drawing.at<Vec3b>(i,j)[0] = 255;drawing.at<Vec3b>(i,j)[1] = 255;drawing.at<Vec3b>(i,j)[2] = 255;}}}// 绘制一个以最大距离所在的点为圆心,最大距离为半径的白色圆形circle(drawing, maxDistPt, (int)maxVal, Scalar(255,255,255));/// 旋轉圖像imshow( "Source", src ); //显示原始图像imshow( "Distance and inscribed circle", drawing ); //显示带距离颜色及内切圆或者外接圆的图像// 一直等待,直到用户按下任意键waitKey();// 返回程序退出状态值return 0;
} 以上提供了代码,主要是在OpenCV中使用pointPolygonTest函数来计算点和多边形之间的最短距离,并且在图中绘制了点和多边形的关系。该代码中使用了C++和OpenCV库,是一个实际的图像处理过程,具有一定的实用价值,尤其是在图像处理、机器视觉等领域。点到线的距离往往是一个重要的参考因素,可以用于轮廓识别、影像匹配和匹配评分等任务。
相关文章:
【opencv】教程代码 —ShapeDescriptors
检测和显示图像的轮廓 在图像中搜索并显示轮廓边缘多边形、轮廓矩形和包围圆 获取包含检测到的轮廓的椭圆和旋转的矩形 图像轮廓检测和轮廓凸包 计算图像中的轮廓的矩(包括面积、重心等)并进行显示 创建和绘制一个多边形图像然后计算并显示图像上每个点到…...
2024-03-28 Java8之Collectors类
Collectors类常用方法 文章目录 Collectors类常用方法1.toList、toSet、toMap2.joining、counting、summingInt、minBy3.groupingBy 1.toList、toSet、toMap Collector<T, ?, List<T>> toList(); //收集为List集合 Collector<T, ?, Set<T>> toSet()…...
第116讲:使用Mycat-eye管理Mycat数据库服务
文章目录 1.Mycat的管理工具2.Mycat-eye介绍3.部署Mycat-eye3.1.安装Zookeep3.2.安装Mycat-eye3.3.访问Mycat-eye 4.在Mycat-eye中导入Mycat服务的信息 1.Mycat的管理工具 Mycat默认开通2个端口,可以在server.xml中进行修改。 8066 数据访问端口,即进行…...
XR虚拟直播间,引领创新风潮,打破直播局限!
随着互联网技术日新月异的发展,直播行业也迎来了蓬勃发展的春天。然而,大多数直播间在吸引观众眼球和延长用户观看时长方面,仍然面临着巨大的挑战。正是在这样的背景下,XR虚拟直播系统应运而生,以其多维度的直播场景、…...
unity双层滑动实现
实现功能: 当滑动列表中内容处于顶端的时候,向上滑动优先滑动整个滑动列表,当滑动列表移动到设置位置,即设定的最高处时,继续移动列表内内容。向下移动亦然,当内容处于滑动列表顶端时,移动整个滑…...
浅谈AI技术创业有哪些机会?
一、AI技术创业概念简介 AI技术创业指的是利用人工智能(Artificial Intelligence,AI)技术进行创业活动。人工智能是指计算机系统能够模拟和展现出人类智能的一种技术。在AI技术创业中,创业者利用AI技术来解决现实生活中的问题&…...
大数据-TXT文本重复行计数工具
支持系统类型:Windows 64位系统 Linux 64位系统 苹果64位系统 硬盘要求:固态硬盘(有效剩余磁盘空间大小最低3倍于大数据文件的大小) 内存要求:最低8G(例如只有几百G数据) 如果处理TB级大数据文…...
【无标题】331
2024年3月31日19:26:09 和一个好感度为40的女生完成了一次基础的对话 2024年3月31日19:26:26 在群里完成了一个毫无所谓的对话 2024年3月31日19:40:04开始准备写论文了 2024年3月31日19:40:11好感度为40的女生回复了我本质上是回复率只有40的人回复了我那应该感到高兴才对 …...
MIT最新研究成果 机器人能够从错误中纠偏 无需编程介入和重复演示
目前科学家们正在努力让机器人变得更加智能,教会他们完成诸如擦拭桌面,端盘子等复杂技能。以往机器人要在非结构化环境执行这样的任务,需要依靠固定编程进行,缺乏场景通用性,而现在机器人的学习过程主要在于模仿&#…...
C语言—指针数组
从键盘任意输入一个整型表示的月份值,用指针数组编程输出该月份的英文表示,若输入的月份值不在1~12之间,则输出“Illegal month”。 **输入格式要求:"%d" 提示信息:"Input month number:&q…...
OpenCV图像二值化
1.二值图像 灰度图像 0 - 255二值图像 0(黑) / 255(白) 2.二值分割 五种阈值分割方法(阈值T): 大于T为255,小于T为0 大于T为0,小于T为255 小于T为原值 else T 小于…...
java中的抽象类
抽象类是指包含了抽象方法的类。在java中,抽象方法指的是用abstract关键字进行修饰的方法,抽象方法与普通的方法的最大区别就是抽象方法没有方法体,也就是说抽象方法是没有具体的实现的。这也就意味着在抽象类的子类中调用抽象方法时…...
代码随想录算法训练营第二十天| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
系列文章目录 目录 系列文章目录654.最大二叉树递归法[左闭右开)[左闭右闭] 617.合并二叉树递归法(前中后序都可,以前序为例)迭代法(类似 101. 对称二叉树 写法,可用双端队列/单端队列<栈>,以单端队列…...
2014年认证杯SPSSPRO杯数学建模A题(第二阶段)轮胎的花纹全过程文档及程序
2014年认证杯SPSSPRO杯数学建模 A题 轮胎的花纹 原题再现: 轮胎被广泛使用在多种陆地交通工具上。根据性能的需要,轮胎表面常会加工出不同形状的花纹。在设计轮胎时,往往要针对其使用环境,设计出相应的花纹形状。 第二阶段问…...
C#全新一代医院手术麻醉系统围术期全流程源码
目录 一、麻醉学科的起源 二、麻醉前访视与评估记录单 患者基本信息 临床诊断 患者重要器官功能及疾病情况 病人体格情况分级 手术麻醉风险评估 拟施麻醉方法及辅助措施 其他需要说明的情况 访视麻醉医师签名 访视时间 与麻醉相关的检查结果 三、手术麻醉信息系统…...
Python 神器:一键下载 M3U8 并转换为 MP4
在这个数字时代,我们经常在网页上遇到各种精彩的视频,但往往只能观看而无法下载。今天,我将向大家介绍如何使用 Python 自动下载网页中的 M3U8 链接,并将其转换为 MP4 格式,让你轻松保存喜欢的视频! 一、准…...
vue3全局控制Element plus所有组件的文字大小
项目框架vue-右上角有控制全文的文字大小 实现: 只能控制element组件的文字及输入框等大小变化,如果是自行添加div,text, span之类的控制不了。 配置流程 APP.vue 使用element的provide,包含app <el-config-provider :locale"loca…...
区间预测 | Matlab实现带有置信区间的BP神经网络时间序列未来趋势预测
区间预测 | Matlab实现带有置信区间的BP神经网络时间序列未来趋势预测 目录 区间预测 | Matlab实现带有置信区间的BP神经网络时间序列未来趋势预测预测效果基本介绍研究回顾程序设计参考资料预测效果 基本介绍 BP神经网络(Backpropagation neural network)是一种常用的人工神…...
Matlab中的脚本和函数
Matlab中的脚本和函数 文章目录 Matlab中的脚本和函数脚本创建脚本代码注释函数创建函数局部函数嵌套函数私有函数匿名函数补充知识函数句柄测试环境:Win11 + Matlab R2021a 脚本 Matlab脚本是最简单的程序文件类型。它们可用于自动执行一系列 Matlab 命令,如命令行重复执…...
使用 nohup java - jar 不输出nohup日志
使用 nohup 命令来运行 Java 程序,并且不让输出写入 nohup.out 文件,可以使用重定向操作符 > 将标准输出重定向到 /dev/null 文件中。这样可以将输出丢弃,而不会写入日志文件。下面是具体的命令: nohup java -jar your_progra…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...
