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

【opencv】示例-grabcut.cpp 使用OpenCV库的GrabCut算法进行图像分割

41f08706f303066b2ff6f1dc27fbfc16.png

left mouse button - set rectangle

33bae4d5ad6bf1e6d3d10211a597a22c.png

bd1a7f237d6a0e78aeb8b84c86f86330.png

SHIFT+left mouse button - set GC_FGD pixels

CTRL+left mouse button - set GC_BGD pixels

这段代码是一个使用OpenCV库的GrabCut算法进行图像分割的C++程序。它允许用户通过交互式方式选择图像中的一个区域,并利用GrabCut算法尝试将其分割出来。代码中包含用户操作指南、颜色定义、事件处理以及GrabCut算法的迭代过程,实现了用户通过鼠标交互和按键控制来迭代分割效果。程序逻辑结构清晰,采用面向对象的方式封装了GrabCut分割相关的操作。

// 引入OpenCV库中处理图像编解码的相关头文件
#include "opencv2/imgcodecs.hpp"
// 引入OpenCV库中高级GUI的相关头文件
#include "opencv2/highgui.hpp"
// 引入OpenCV库中图像处理的相关头文件
#include "opencv2/imgproc.hpp"// 引入输入输出流的库文件
#include <iostream>// 使用标准命名空间std,免去std::前缀
using namespace std;
// 使用OpenCV命名空间cv,免去cv::前缀
using namespace cv;// 定义静态辅助函数,用于显示程序帮助信息
static void help(char** argv)
{cout << "\nThis program demonstrates GrabCut segmentation -- select an object in a region\n""and then grabcut will attempt to segment it out.\n""Call:\n"<< argv[0] << " <image_name>\n" // 显示如何调用程序"\nSelect a rectangular area around the object you want to segment\n"// 以下是热键操作说明"\nHot keys: \n""\tESC - quit the program\n" // 按ESC键退出程序"\tr - restore the original image\n" // 按'r'键还原到原始图像"\tn - next iteration\n" // 按'n'键执行下一迭代步骤"\n"// 以下是鼠标操作说明"\tleft mouse button - set rectangle\n" // 左键点击设置矩形区域"\n""\tCTRL+left mouse button - set GC_BGD pixels\n" // 按住CTRL键同时左键点击设置背景像素"\tSHIFT+left mouse button - set GC_FGD pixels\n" // 按住SHIFT键同时左键点击设置前景像素"\n""\tCTRL+right mouse button - set GC_PR_BGD pixels\n" // 按住CTRL键同时右键点击设置可能的背景像素"\tSHIFT+right mouse button - set GC_PR_FGD pixels\n" << endl; // 按住SHIFT键同时右键点击设置可能的前景像素
}// 定义一些标量常量表示不同的颜色
const Scalar RED = Scalar(0,0,255);
const Scalar PINK = Scalar(230,130,255);
const Scalar BLUE = Scalar(255,0,0);
const Scalar LIGHTBLUE = Scalar(255,255,160);
const Scalar GREEN = Scalar(0,255,0);// 定义背景键和前景键的标志,用于鼠标操作事件中
const int BGD_KEY = EVENT_FLAG_CTRLKEY;
const int FGD_KEY = EVENT_FLAG_SHIFTKEY;// 声明静态函数,用于从复合掩模图中提取二值掩模图
static void getBinMask( const Mat& comMask, Mat& binMask )
{// 确保comMask非空且类型为CV_8UC1,否则抛出错误if( comMask.empty() || comMask.type()!=CV_8UC1 )CV_Error( Error::StsBadArg, "comMask is empty or has incorrect type (not CV_8UC1)" );// 如果binMask为空或大小与comMask不一致,则重新创建与comMask大小一致的binMaskif( binMask.empty() || binMask.rows!=comMask.rows || binMask.cols!=comMask.cols )binMask.create( comMask.size(), CV_8UC1 );// 将comMask中的最低位复制到binMask中binMask = comMask & 1;
}// 声明GrabCut应用类,用于实现GrabCut算法的交互操作
// 定义用于GrabCut算法的应用类
class GCApplication
{
public:// 定义选择状态的枚举类型enum{ NOT_SET = 0, IN_PROCESS = 1, SET = 2 };// 定义圆的半径static const int radius = 2;// 定义圆的线条厚度,-1表示填充圆static const int thickness = -1;// 成员函数声明void reset();  // 重置函数void setImageAndWinName( const Mat& _image, const string& _winName );  // 设置图像和窗口名void showImage() const;  // 展示图像void mouseClick( int event, int x, int y, int flags, void* param );  // 鼠标点击事件处理函数int nextIter();  // 迭代处理函数int getIterCount() const { return iterCount; }  // 获取迭代次数的函数private:// 私有成员函数和变量声明void setRectInMask();  // 设置矩形到掩模中void setLblsInMask( int flags, Point p, bool isPr );  // 设置标签到掩模中的函数const string* winName;  // 窗口名称const Mat* image;  // 图像引用Mat mask;  // 掩模矩阵Mat bgdModel, fgdModel;  // 背景和前景模型uchar rectState, lblsState, prLblsState;  // 矩形和标签状态变量bool isInitialized;  // 是否已经初始化的标志Rect rect;  // 矩形区域vector<Point> fgdPxls, bgdPxls, prFgdPxls, prBgdPxls;  // 记录前景和背景像素位置的向量int iterCount;  // 迭代计数
};// 成员函数定义
// 重置GCApplication
void GCApplication::reset()
{if( !mask.empty() )mask.setTo(Scalar::all(GC_BGD));  // 如果掩模非空,设置掩模的所有值为GC_BGD// 清除前景、背景像素位置的记录bgdPxls.clear(); fgdPxls.clear();prBgdPxls.clear();  prFgdPxls.clear();// 重置相关的状态标志和迭代计数isInitialized = false;rectState = NOT_SET;lblsState = NOT_SET;prLblsState = NOT_SET;iterCount = 0;
}// 设置图像和窗口名
void GCApplication::setImageAndWinName( const Mat& _image, const string& _winName  )
{if( _image.empty() || _winName.empty() )return;  // 如果图像或窗口名为空,直接返回image = &_image;  // 设置图像引用winName = &_winName;  // 设置窗口名mask.create( image->size(), CV_8UC1);  // 创建与图像相同大小的掩模矩阵reset();  // 重置GCApplication
}// 展示图像
void GCApplication::showImage() const
{if( image->empty() || winName->empty() )return;  // 如果图像为空或窗口名为空,直接返回Mat res;Mat binMask;image->copyTo( res );  // 复制图像到resif( isInitialized ){getBinMask( mask, binMask);  // 如果已经初始化,获取二值掩模Mat black (binMask.rows, binMask.cols, CV_8UC3, cv::Scalar(0,0,0));black.setTo(Scalar::all(255), binMask);  // 设置黑色图像的掩模区域为白色addWeighted(black, 0.5, res, 0.5, 0.0, res);  // 将黑色图像与原图混合}vector<Point>::const_iterator it;// 绘制背景和前景像素位置for( it = bgdPxls.begin(); it != bgdPxls.end(); ++it )circle( res, *it, radius, BLUE, thickness );for( it = fgdPxls.begin(); it != fgdPxls.end(); ++it )circle( res, *it, radius, RED, thickness );for( it = prBgdPxls.begin(); it != prBgdPxls.end(); ++it )circle( res, *it, radius, LIGHTBLUE, thickness );for( it = prFgdPxls.begin(); it != prFgdPxls.end(); ++it )circle( res, *it, radius, PINK, thickness );// 绘制矩形框if( rectState == IN_PROCESS || rectState == SET )rectangle( res, Point( rect.x, rect.y ), Point(rect.x + rect.width, rect.y + rect.height ), GREEN, 2);imshow( *winName, res );  // 显示图像
}   // GCApplication类的成员函数:设置矩形框到掩模中
void GCApplication::setRectInMask()
{CV_Assert( !mask.empty() ); // 确认掩模不为空mask.setTo( GC_BGD ); // 将掩模的全部像素值设置为背景// 修正矩形坐标,确保矩形框不会超出图像范围rect.x = max(0, rect.x);rect.y = max(0, rect.y);rect.width = min(rect.width, image->cols-rect.x);rect.height = min(rect.height, image->rows-rect.y);// 将矩形框内的像素值设置为可能的前景(mask(rect)).setTo( Scalar(GC_PR_FGD) );
}// GCApplication类的成员函数:根据用户输入,在掩模上设置前景或背景标签
void GCApplication::setLblsInMask( int flags, Point p, bool isPr )
{vector<Point> *bpxls, *fpxls; // 指向背景和前景像素点的向量uchar bvalue, fvalue; // 背景和前景的像素值// 根据是否是概率图(isPr)设置不同的指针和像素值if( !isPr ){bpxls = &bgdPxls;fpxls = &fgdPxls;bvalue = GC_BGD;fvalue = GC_FGD;}else{bpxls = &prBgdPxls;fpxls = &prFgdPxls;bvalue = GC_PR_BGD;fvalue = GC_PR_FGD;}// flags中对应的按键标志位被设置,更新背景像素点向量,并在掩模上画圆if( flags & BGD_KEY ){bpxls->push_back(p);circle( mask, p, radius, bvalue, thickness );}// flags中对应的按键标志位被设置,更新前景像素点向量,并在掩模上画圆if( flags & FGD_KEY ){fpxls->push_back(p);circle( mask, p, radius, fvalue, thickness );}
}// GCApplication类的成员函数:处理鼠标点击事件
void GCApplication::mouseClick( int event, int x, int y, int flags, void* )
{switch( event ){// 左键按下事件:设置矩形或者GC_BGD/GC_FGD像素标签case EVENT_LBUTTONDOWN: {bool isb = (flags & BGD_KEY) != 0,isf = (flags & FGD_KEY) != 0;if( rectState == NOT_SET && !isb && !isf ){rectState = IN_PROCESS; // 开始绘制矩形框rect = Rect( x, y, 1, 1 ); // 初始化矩形框大小}if ( (isb || isf) && rectState == SET )lblsState = IN_PROCESS; // 开始设置标签状态}break;// 右键按下事件:设置GC_PR_BGD/GC_PR_FGD像素标签case EVENT_RBUTTONDOWN: {bool isb = (flags & BGD_KEY) != 0,isf = (flags & FGD_KEY) != 0;if ( (isb || isf) && rectState == SET )prLblsState = IN_PROCESS; // 开始设置概率标签状态}break;// 左键释放事件:完成矩形绘制或者设置像素标签case EVENT_LBUTTONUP:if( rectState == IN_PROCESS ){// 如果起点和终点一样,则不设置矩形框if(rect.x == x || rect.y == y){rectState = NOT_SET;}else{rect = Rect( Point(rect.x, rect.y), Point(x,y) );rectState = SET; // 设置矩形框状态为已设置setRectInMask(); // 在掩模上绘制矩形框CV_Assert( bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() && prFgdPxls.empty() );}showImage(); // 显示图像}if( lblsState == IN_PROCESS ){setLblsInMask(flags, Point(x,y), false); // 设置像素标签lblsState = SET; // 设置标签状态为已设置nextIter(); // 进行一次迭代showImage(); // 显示图像}else{// 如果矩形框状态已设置,进行一次迭代后显示图像if(rectState == SET){nextIter();showImage();}}break;// 右键释放事件:完成概率标签的设置case EVENT_RBUTTONUP:if( prLblsState == IN_PROCESS ){setLblsInMask(flags, Point(x,y), true); // 设置概率标签prLblsState = SET; // 设置概率标签状态为已设置}// 如果矩形框状态已设置,进行一次迭代后显示图像if(rectState == SET){nextIter();showImage();}break;// 鼠标移动事件:更新矩形框大小或者继续设置像素标签case EVENT_MOUSEMOVE:if( rectState == IN_PROCESS ){rect = Rect( Point(rect.x, rect.y), Point(x,y) );CV_Assert( bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() && prFgdPxls.empty() );showImage(); // 显示图像}else if( lblsState == IN_PROCESS ){setLblsInMask(flags, Point(x,y), false); // 设置像素标签showImage(); // 显示图像}else if( prLblsState == IN_PROCESS ){setLblsInMask(flags, Point(x,y), true); // 设置概率标签showImage(); // 显示图像}break;}
}// 主函数入口
int main( int argc, char** argv )
{// 解析命令行参数cv::CommandLineParser parser(argc, argv, "{@input| messi5.jpg |}");// 调用help函数显示帮助信息help(argv);// 获取图片文件名string filename = parser.get<string>("@input");// 如果文件名为空,输出错误信息并返回1if( filename.empty() ){cout << "\nDurn, empty filename" << endl;return 1;}// 读取图片Mat image = imread(samples::findFile(filename), IMREAD_COLOR);// 如果读取失败,输出错误信息并返回1if( image.empty() ){cout << "\n Durn, couldn't read image filename " << filename << endl;return 1;}// 创建窗口const string winName = "image";namedWindow( winName, WINDOW_AUTOSIZE );// 设置鼠标回调函数setMouseCallback( winName, on_mouse, 0 );// 设置gcapp对象的图片和窗口名称gcapp.setImageAndWinName( image, winName );// 显示图片gcapp.showImage();// 无限循环,等待用户按键for (;;){// 等待按键事件char c = (char)waitKey(0);switch (c){case '\x1b': // 按Esc键退出cout << "Exiting ..." << endl;goto exit_main;case 'r': // 按'r'键重置cout << endl;gcapp.reset(); // 调用重置函数gcapp.showImage(); // 显示图像break;case 'n': // 按'n'键进行下一次迭代int iterCount = gcapp.getIterCount(); // 获取当前迭代次数cout << "<" << iterCount << "... ";int newIterCount = gcapp.nextIter(); // 调用下一个迭代if (newIterCount > iterCount){gcapp.showImage(); // 显示新的图像cout << iterCount << ">" << endl;}elsecout << "rect must be determined>" << endl; // 提示需要先确定矩形框break;}}exit_main:// 销毁窗口并退出destroyWindow( winName );return 0;
}

4396662620bffcce3c85a06b8f6b8519.png

vector<Point>::const_iterator it;// 绘制背景和前景像素位置for (it = bgdPxls.begin(); it != bgdPxls.end(); ++it)circle(res, *it, radius, BLUE, thickness);for (it = fgdPxls.begin(); it != fgdPxls.end(); ++it)circle(res, *it, radius, RED, thickness);for (it = prBgdPxls.begin(); it != prBgdPxls.end(); ++it)circle(res, *it, radius, LIGHTBLUE, thickness);for (it = prFgdPxls.begin(); it != prFgdPxls.end(); ++it)circle(res, *it, radius, PINK, thickness);

f7e7b43a3df3c230bdc740bf725eeb2f.png

de922bc6f830506138ace52857ca324d.png

grabCut(*image, mask, rect, bgdModel, fgdModel, 1);

70dc097b43f56b2b7747b1df365b07ad.png

// 如果标签已经设置或概率标签已经设置,用mask初始化grabCutif (lblsState == SET || prLblsState == SET)grabCut(*image, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_MASK);else// 否则,用rect初始化grabCutgrabCut(*image, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_RECT);

a69d4dac7b64bbaebfd262eea01fcebe.png

相关文章:

【opencv】示例-grabcut.cpp 使用OpenCV库的GrabCut算法进行图像分割

left mouse button - set rectangle SHIFTleft mouse button - set GC_FGD pixels CTRLleft mouse button - set GC_BGD pixels 这段代码是一个使用OpenCV库的GrabCut算法进行图像分割的C程序。它允许用户通过交互式方式选择图像中的一个区域&#xff0c;并利用GrabCut算法尝试…...

GEE数据集——巴基斯坦国家级土壤侵蚀数据集(2005 年和 2015 年)

简介 巴基斯坦国家级土壤侵蚀数据集&#xff08;2005 年和 2015 年&#xff09; 该数据集采用修订的通用土壤流失方程 (RUSLE)&#xff0c;并考虑了六个关键影响因素&#xff1a;降雨侵蚀率 (R)、土壤可侵蚀性 (K)、坡长 (L)、坡陡 (S)、覆盖管理 (C) 和保护措施 (P)&#xff…...

服务器代理

服务器代理 配置&#xff1a;64G内存1 3090&#xff08;24g&#xff09;1P4000&#xff08;8g&#xff09; SSH连接 工作路径&#xff1a;/home/ubuntu/workspace/python Anaconda路径&#xff1a;/home/Ubuntu 1.在工作路径下创建自己的文件夹作为workspace 2.以用户ubunbtu登…...

【SGDR】《SGDR:Stochastic Gradient Descent with Warm Restarts》

arXiv-2016 code: https://github.com/loshchil/SGDR/blob/master/SGDR_WRNs.py 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method5 Experiments5.1 Datasets and Metric5.2 Single-Model Results5.3 Ensemble Results5.4 Experiment…...

如何将arping以及所有依赖打包安装到另外一台离线ubuntu机器

ubuntu系统下可以使用arping命令检测局域网内一些ip是否冲突&#xff0c;使用方式为&#xff1a; arping xx.xx.xx.xx 在线情况下&#xff0c;可以使用下面命令下载arping&#xff0c;然后使用即可 apt install arping 但是有些情况下机器可能不能上网&#xff0c;这时就需要将…...

mac上如何安装python3

mac上如何安装python3&#xff1f; 安装homebrew 在终端执行命令 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 执行完成后&#xff0c;homebrew和pip等工具就自动安装好了。 接下来安装python3.在终端…...

Java 那些诗一般的 数据类型 (下篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能接…...

WEB3.0:互联网的下一阶段

随着互联网的发展&#xff0c;WEB3.0时代正在逐步到来。本文将深入探讨WEB3.0的定义、特点、技术应用以及未来展望&#xff0c;为读者带来全新的思考。 一、什么是WEB3.0&#xff1f; WEB3.0可以被理解为互联网发展的下一阶段&#xff0c;是当前WEB2.0的升级版。相较于2.0时代…...

Fastgpt配合chatglm+m3e或ollama+m3e搭建个人知识库

概述&#xff1a; 人工智能大语言模型是近年来人工智能领域的一项重要技术&#xff0c;它的出现标志着自然语言处理领域的重大突破。这些模型利用深度学习和大规模数据训练&#xff0c;能够理解和生成人类语言&#xff0c;为各种应用场景提供了强大的文本处理能力。AI大语言模…...

如何使用选择器精确地控制网页中每一个元素的样式?

1. 基础知识 什么是 CSS 元素选择器 CSS 元素选择器是一种在网页中通过元素类型来应用样式的方法。 简单来说&#xff0c;它就像是一个指挥棒&#xff0c;告诉浏览器哪些 HTML 元素需要应用我们定义的 CSS 样式规则。 为何要使用 CSS 元素选择器 使用元素选择器可以让我们…...

各个微前端框架的优劣浅谈

各个微前端框架都有其独特的优势和劣势&#xff0c;下面我将针对几个主流的微前端框架进行简要的优劣分析&#xff1a; single-spa 优势&#xff1a; 轻量级&#xff1a;single-spa是一个非常轻量级的微前端框架&#xff0c;它主要提供了一个加载和管理微应用的机制&#xff0c…...

自动化运维(二十二)Ansible实战 之Jenkins模块

Ansible提供了一些模块,可以用来与Jenkins进行交互,执行各种操作,如创建任务、触发构建、获取构建结果等。通过使用这些模块,我们可以将Jenkins的配置和管理集成到Ansible的自动化流程中。 以下是一些常用的Ansible Jenkins模块: 1、jenkins_job模块 jenkins_job模块用于创建…...

Python数据分析与应用 |第4章 使用pandas进行数据预处理 (实训)

表1-1healthcare-dataset-stroke.xlsx 部分中风患者的基础信息和体检数据 编号性别高血压是否结婚工作类型居住类型体重指数吸烟史中风9046男否是私人城市36.6以前吸烟是51676女否是私营企业农村N/A从不吸烟是31112男否是私人农村32.5从不吸烟...

基于双向长短期神经网络BILSTM的线损率预测,基于gru的线损率预测

目录 背影 摘要 LSTM的基本定义 LSTM实现的步骤 BILSTM神经网络 基于双向长短期神经网络BILSTM的线损率预测,基于gru的线损率预测 完整代码:基于双向长短期神经网络BILSTM的线损率预测,基于gru的线损率预测(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/d…...

智能售货机:引领便捷生活

智能售货机&#xff1a;引领便捷生活 在这个科技迅速进步的时代&#xff0c;便捷已成为生活的必需。智能售货机作为技术与便利完美结合的产物&#xff0c;正逐渐改变我们的购物方式&#xff0c;为都市生活增添新的活力。 智能售货机的主要优势是它的极致便利性。不论是在地铁…...

正向代理和反向代理

正向代理和反向代理是网络中常见的两种代理方式&#xff0c;它们在网络通信中扮演着不同的角色。 正向代理&#xff1a; 正向代理是代理服务器位于客户端和目标服务器之间的一种代理方式。 客户端向代理服务器发送请求&#xff0c;然后代理服务器将请求转发给目标服务器&…...

kimichat使用技巧:用语音对话聊天

kimichat之前是只能用文字聊天的&#xff0c;不过最近推出了语音新功能&#xff0c;也可以用语音畅快的对话聊天了。 这个功能目前支持手机app版本&#xff0c;所以首先要在手机上下载安装kimi智能助手。已经安装的&#xff0c;要点击检查更新&#xff0c;更新到最新的版本。 …...

机器学习-09-图像处理02-PIL+numpy+OpenCV实践

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中图像处理技术。 参考 【人工智能】PythonOpenCV图像处理&#xff08;一篇全&#xff09; 一文讲解方向梯度直方图&#xff08;hog&#xff09; 【杂谈】计算机视觉在人脸图像领域的十几个大的应用方向&…...

应急响应-战前反制主机HIDSElkeid蜜罐系统HFish

知识点 战前-反制-平台部署其他更多项目&#xff1a; https://github.com/birdhan/SecurityProduct HIDS&#xff1a;主机入侵检测系统&#xff0c;通常会有一个服务器承担服务端角色&#xff0c;其他主机就是客户端角色&#xff0c;客户端加入到服务端的检测范围里&#xff…...

C#:24小时制和12小时制之间的转换

任务描述 本关任务&#xff1a;编写一个程序&#xff0c;利用求余运算完成24小时制和12小时制之间的转换。 注意&#xff1a;要求输入的数字是0到24之间的整数。 测试说明 平台会对你编写的代码进行测试&#xff1a; 测试输入&#xff1a;4 预期输出&#xff1a; 现在是上午4…...

说说TCP为什么需要三次握手和四次挥手?

文章目录 一、三次握手为什么不是两次握手? 二、四次挥手四次挥手原因 三、总结参考文献 一、三次握手 三次握手&#xff08;Three-way Handshake&#xff09;其实就是指建立一个TCP连接时&#xff0c;需要客户端和服务器总共发送3个包 主要作用就是为了确认双方的接收能力和…...

STM32 串口接收定长,不定长数据

本文为大家介绍如何使用 串口 接收定长 和 不定长 的数据。 文章目录 前言一、串口接收定长数据1. 函数介绍2.代码实现 二、串口接收不定长数据1.函数介绍2. 代码实现 三&#xff0c;两者回调函数的区别比较四&#xff0c;空闲中断的介绍总结 前言 一、串口接收定长数据 1. 函…...

C++设计模式|0.前言

1.什么是设计模式&#xff1f; 简答来说&#xff0c;设计模式就是一套好用的代码经验总结&#xff0c;也就是怎么写好代码的方法论。使用设计模式是为了可重用代码、让代码更容易被他人理解、提高代码的可靠性。 2.设计模式的分类 设计模式可以分为三类&#xff1a;创建型、…...

[蓝桥杯] 岛屿个数(C语言)

提示&#xff1a; 橙色字体为需要注意部分&#xff0c;红色字体为难点部分&#xff0c;会在文章“重难点解答”部分精讲。 题目链接 蓝桥杯2023年第十四届省赛真题-岛屿个数 - C语言网 题目理解 这道题让我们求岛屿个数&#xff0c;那么我们就应该先弄懂&#xff0c;对于一…...

Apache Storm的详细配置

Apache Storm的详细配置主要涉及以下几个方面: Zookeeper配置:Apache Storm使用Zookeeper来进行协调和配置管理。你需要配置Zookeeper集群的连接信息,包括Zookeeper服务器的主机和端口。 Storm Nimbus配置:Nimbus是Storm的主节点,负责分配任务给各个工作节点。你需要配置N…...

kylin v10 php源码安装后配置nginx

银河麒麟V10 源码编译安装php7.4 下载地址 https://www.php.net/distributions/php-7.4.33.tar.xz 安装依赖包&#xff0c;准备编译 dnf install libxml2-devel sqlite-devel bzip2-devel libcurl-devel libjpeg-turbo-devel freetype-devel openldap-devel libtool-devel p…...

【01背包】滚动数组优化实现一维01背包DP(对比朴素写法)

01背包 代码 背包问题的滚动数组优化版本建议在完全弄懂了普通的二维01背包问题后再进行食用&#xff0c;不然会出现消化不良的症状… 我们可以将背包问题中DP数组的下标看作成两个集合 下面对比两种不同实现方法的区别&#xff1a; 朴素二维DP版本 使用dp[不超过i的物品集合]…...

深度学习500问——Chapter07:生成对抗网络(GAN)(2)

文章目录 7.2 GAN的生成能力评价 7.2.1 如何客观评价GAN的生成能力 7.2.2 Inception Score 7.2.3 Mode Score 7.2.5 Wasserstein distance 7.2.6 Frchet Inception Distance (FID) 7.2.7 1-Nearest Neighbor classifier 7.2.8 其他评价方法 7.3 其他常见的生成式模型有哪些 7.…...

A13 STM32_HAL库函数 之 HAL-ETH通用驱动 -- B -- 所有函数的介绍及使用

A13 STM32_HAL库函数 之 HAL-ETH通用驱动 -- B -- 所有函数的介绍及使用 1 通用定时器&#xff08;TIM&#xff09;预览1.11 HAL_ETH_TxCpltCallback1.12 HAL_ETH_RxCpltCallback1.13 HAL_ETH_ErrorCallback1.14 HAL_ETH_ReadPHYRegister1.15 HAL_ETH_WritePHYRegister1.16 HAL…...

Qotom Q720G5英特尔赛扬处理器N4000高性价比无风扇迷你电脑5网口软路由防火墙

在数字时代&#xff0c;迷你电脑已经成为高效、灵活的解决方案&#xff0c;无论是个人用户还是企业用户&#xff0c;都能从中受益。Qotom Q720G5 无风扇迷你电脑就是这样一款强大的选择&#xff0c;它不仅可以作为软路由、防火墙和路由器&#xff0c;还有着更多的潜力等待发掘。…...

如何将wordpress上传到站点/互联网营销师培训内容

2019独角兽企业重金招聘Python工程师标准>>> 工作中遇到的问题&#xff0c;计划任务执行了&#xff0c;但是不对&#xff0c;感觉是写错了&#xff0c;但是也没有报错&#xff0c;尝试了好久也不行&#xff0c;终于在网上找到了答案&#xff0c;原来在crontab里使用…...

长春公司网站建设/百度seo2022新算法更新

linux安装Navicat&#xff0c;界面出现乱码解决方法 &#xff08;转发&#xff09;参考文章&#xff1a; &#xff08;1&#xff09;linux安装Navicat&#xff0c;界面出现乱码解决方法 &#xff08;转发&#xff09; &#xff08;2&#xff09;https://www.cnblogs.com/miao…...

台州路桥网站建设/常用的seo工具

之前遇到过"/",在esclipse中报错&#xff0c;只认识“//”&#xff0c;“\”符号&#xff0c;需要将string字符串“/”&#xff0c;转换成“//”或者“\”怎么转呢&#xff1f; 获取字符串是 String path "/root/data/image"; StringBuilder sb new Stri…...

旅游论坛网站建设/南京今天重大新闻事件

开源「高逼格」简历例句&#xff0c;看你有没有中招&#xff1f; 星期天下午&#xff0c;在浏览 GitHub 的时候&#xff0c;发现一个非常有意思的开源项目&#xff0c;是由 ResumeJob 整理贡献的&#xff0c;那就是一份程序员简历上常常使用的介绍和描述技能的例句。感觉写的很…...

dz网站地图怎么做/广点通官网

目录 ThreadLocal InheritableThreadLocal TransmittableThreadLocal 本文主要介绍ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal三者之间区别、如何使用、什么场景使用以及对原理和源码的介绍。介绍原理的时候通过最直白、最易懂的语言争取让大家了解三者…...

做网站用什么技术/网游百度搜索风云榜

目录 5.1. 解析本库WAL日志 5.1.1. 创建扩展 5.1.2. 执行普通解析 5.1.3. 时间范围解析 5.1.4. LSN范围解析 5.1.5. 单表解析 5.1.6. 查看分析结果 5.1.7. 结束分析 5.2. 解析其他数据库的WAL日志 5.2.1. 从其他数据库导出数据字典 5.2.2. 导入其他数据库…...