Qt -使用OpenCV得到SDF

article/2025/6/18 5:11:08

博客主页:【夜泉_ly】
本文专栏:【暂无】
欢迎点赞👍收藏⭐关注❤️

在这里插入图片描述

目录

  • cv::Mat
  • distanceTransform
  • 获得SDF

本文的目标,
是简单学习并使用OpenCV的相关函数,
并获得QImage的SDF(Signed Distance Field 有向距离场)
至于我要用QImage的SDF来做什么,嗯,以后再说。

cv::Mat

这个可以理解为OpenCV的QImage,嗯。
简单看看就行。

首先,Mat是可以存QImage并显示的。
其次,Mat是可以手搓的。
我们先手搓一个白底的黑色正方形,看看效果:

void Widget::on_pushButton_clicked()
{cv::Mat testMat(201, 201, CV_8UC1);for(int i = 0; i <= 200; i++){for(int j = 0; j <= 200; j++){// testMat[i][j] = 0; 这不行呢if((90 < i && i < 110) && (90 < j && j < 110)) {testMat.at<uchar>(i, j) = 0;   // 0   - 黑} else {testMat.at<uchar>(i, j) = 255; // 255 - 白}}}cv::imshow("testMat", testMat);
}

在这里插入图片描述
CV_8UC1 ,表示 8 位单通道,即灰度图,这个之后会用。

先试试把QImage转为灰度图:

cv::Mat image_to_CV_8UC1(const QImage& image){int w = image.width(),h = image.height();cv::Mat mat(w, h, CV_8UC1);for(int i = 0; i < w; i++){for(int j = 0; j < h; j++){ // 注: 只能设为全0,或全1mat.at<uchar>(i, j) = (image.pixelColor(i, j).alpha() == 0) ? 0 : 255;}}if(mat.empty()) return mat;cv::imshow("image", mat);return mat;
}

跑一下,发现图像被逆时针转了九十度。
cv::Mat 的这个构造,传的分别是 ( 行, 列, 类型)
QImage 的 width 是宽, height 是高,刚好反了:
在这里插入图片描述
改了顺序过后就对了:

cv::Mat image_to_CV_8UC1(const QImage& image){int r = image.height(), c = image.width();cv::Mat mat(r, c, CV_8UC1);for(int i = 0; i < r; i++){for(int j = 0; j < c; j++){ // 注意下面 image 是 (j, i)mat.at<uchar>(i, j) = (image.pixelColor(j, i).alpha() == 0) ? 0 : 255;}}if(mat.empty()) return mat;cv::imshow("image", mat);return mat;
}

在这里插入图片描述
再来试试翻转,我们需要把0变非0,把非0变0,
这个用条件判断加赋值有点慢,
不过,OpenCV 有现成的函数 bitwise_not :

void Widget::on_pushButton_2_clicked(bool checked)
{cv::Mat mat_front = image_to_CV_8UC1(_image);cv::Mat mat_back;cv::bitwise_not(mat_front, mat_back);if(checked) cv::imshow("image", mat_front);else cv::imshow("image", mat_back);
}

在这里插入图片描述在这里插入图片描述

distanceTransform

这个可以用来计算每个非零像素点到最近的零像素点的距离。
嗯,有点抽象,不过刚刚我们学会了手绘 Mat,
那我们可以先做个实验,看看这个距离到底是什么:

void Widget::on_pushButton_3_clicked()
{cv::Mat src(21, 21, CV_8UC1);for(int r = 0; r <= 20; r++){for(int c = 0; c <= 20; c++){if((5 < r && r < 15) && (5 < c && c < 15)) {src.at<uchar>(r, c) = 0;   // 0   - 黑} else {src.at<uchar>(r, c) = 255; // 255 - 白}}}cv::Mat dst;cv::distanceTransform(src, dst, cv::DIST_L2, 3);QString ret;for(int r = 0; r <= 20; r++){for(int c = 0; c <= 20; c++){float f = dst.at<float>(r, c);ret += QString::number(f).rightJustified(9, ' ');}   ret += "\n";}cv::imshow("dst", dst);std::cout << ret.toStdString();
}

哦,关于参数,
第一个是传入的 Mat,类型好像只能是 CV_8UC1,值只能是0或255。
第二个是得到的 Mat,只能用 at<float> 去取到它的值,这个值就是非0到最近0的距离。
第三个是距离的类型,这里用的 cv::DIST_L2,即欧几里得距离。
第四个是掩码,嗯,意义不明,取三就行。

打印结果如下:
在这里插入图片描述

  8.21576  7.80147  7.38718  6.97289  6.55859   6.1443  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001   6.1443  6.55859  6.97289  7.38718  7.80147  8.215767.80147  6.84647  6.43217  6.01788  5.60359   5.1893  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501   5.1893  5.60359  6.01788  6.43217  6.84647  7.801477.38718  6.43217  5.47717  5.06288  4.64859   4.2343  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001   4.2343  4.64859  5.06288  5.47717  6.43217  7.387186.97289  6.01788  5.06288  4.10788  3.69359   3.2793  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501   3.2793  3.69359  4.10788  5.06288  6.01788  6.972896.55859  5.60359  4.64859  3.69359  2.73859   2.3243     1.91     1.91     1.91     1.91     1.91     1.91     1.91     1.91     1.91   2.3243  2.73859  3.69359  4.64859  5.60359  6.558596.1443   5.1893   4.2343   3.2793   2.3243  1.36929 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002  1.36929   2.3243   3.2793   4.2343   5.1893   6.14435.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730015.73001  4.77501  3.82001  2.86501     1.91 0.955002        0        0        0        0        0        0        0        0        0 0.955002     1.91  2.86501  3.82001  4.77501  5.730016.1443   5.1893   4.2343   3.2793   2.3243  1.36929 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002 0.955002  1.36929   2.3243   3.2793   4.2343   5.1893   6.14436.55859  5.60359  4.64859  3.69359  2.73859   2.3243     1.91     1.91     1.91     1.91     1.91     1.91     1.91     1.91     1.91   2.3243  2.73859  3.69359  4.64859  5.60359  6.558596.97289  6.01788  5.06288  4.10788  3.69359   3.2793  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501  2.86501   3.2793  3.69359  4.10788  5.06288  6.01788  6.972897.38718  6.43217  5.47717  5.06288  4.64859   4.2343  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001  3.82001   4.2343  4.64859  5.06288  5.47717  6.43217  7.387187.80147  6.84647  6.43217  6.01788  5.60359   5.1893  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501  4.77501   5.1893  5.60359  6.01788  6.43217  6.84647  7.801478.21576  7.80147  7.38718  6.97289  6.55859   6.1443  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001  5.73001   6.1443  6.55859  6.97289  7.38718  7.80147  8.21576

额,似乎有偏差?感觉明明该是整数的点却是小数。
不过偏差不大,能用就行。

试试把掩码改为5,听说这个精确一些:
在这里插入图片描述

      8.4   7.7969   7.1938   6.5907   6.3938   6.1969        6        6        6        6        6        6        6        6        6   6.1969   6.3938   6.5907   7.1938   7.7969      8.47.7969        7   6.3969   5.7938   5.3938   5.1969        5        5        5        5        5        5        5        5        5   5.1969   5.3938   5.7938   6.3969        7   7.79697.1938   6.3969      5.6   4.9969   4.3938   4.1969        4        4        4        4        4        4        4        4        4   4.1969   4.3938   4.9969      5.6   6.3969   7.19386.5907   5.7938   4.9969      4.2   3.5969   3.1969        3        3        3        3        3        3        3        3        3   3.1969   3.5969      4.2   4.9969   5.7938   6.59076.3938   5.3938   4.3938   3.5969      2.8   2.1969        2        2        2        2        2        2        2        2        2   2.1969      2.8   3.5969   4.3938   5.3938   6.39386.1969   5.1969   4.1969   3.1969   2.1969      1.4        1        1        1        1        1        1        1        1        1      1.4   2.1969   3.1969   4.1969   5.1969   6.19696        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66        5        4        3        2        1        0        0        0        0        0        0        0        0        0        1        2        3        4        5        66.1969   5.1969   4.1969   3.1969   2.1969      1.4        1        1        1        1        1        1        1        1        1      1.4   2.1969   3.1969   4.1969   5.1969   6.19696.3938   5.3938   4.3938   3.5969      2.8   2.1969        2        2        2        2        2        2        2        2        2   2.1969      2.8   3.5969   4.3938   5.3938   6.39386.5907   5.7938   4.9969      4.2   3.5969   3.1969        3        3        3        3        3        3        3        3        3   3.1969   3.5969      4.2   4.9969   5.7938   6.59077.1938   6.3969      5.6   4.9969   4.3938   4.1969        4        4        4        4        4        4        4        4        4   4.1969   4.3938   4.9969      5.6   6.3969   7.19387.7969        7   6.3969   5.7938   5.3938   5.1969        5        5        5        5        5        5        5        5        5   5.1969   5.3938   5.7938   6.3969        7   7.79698.4   7.7969   7.1938   6.5907   6.3938   6.1969        6        6        6        6        6        6        6        6        6   6.1969   6.3938   6.5907   7.1938   7.7969      8.4

不过精确当然也有代价,比如运算速度肯定不如 3。
我们把数据改大,测测效率:

#include <QElapsedTimer>
void mask_3_VS_5(const cv::Mat& src, int mask)
{QElapsedTimer timer;timer.start();for (int i = 0; i < 10; i++) {cv::Mat dst;cv::distanceTransform(src, dst, cv::DIST_L2, mask);}qint64 elapsed = timer.nsecsElapsed();qDebug() << "mask = " << mask << ", Elapsed time:" << elapsed / 1000000.0 << "ms";
}void Widget::on_pushButton_4_clicked()
{cv::Mat src(10000, 10000, CV_8UC1);for(int r = 0; r < 10000; r++) for(int c = 0; c < 10000; c++)if((rand() % 100) < 50) src.at<uchar>(r, c) = 0;else src.at<uchar>(r, c) = 255;mask_3_VS_5(src, 5);mask_3_VS_5(src, 3);
}

10000 x 10000 的图,跑 10 次, 打印结果如下:
嗯,截图为证:
在这里插入图片描述
精度高的运行速度还更快!竟然还有这种好事😋。

获得SDF

我们已经得到了非0点到最近0点距离。
但SDF要求有正有负,即把图分为2份,一个外,一个内:
在这里插入图片描述
我们拿到一个QImage,把它转为 Mat。
其中,alpha,即透明度为 0,即纯黑的我们称为 内,其他的称为 外。
额,算了,换个说法,黑色就是障碍物,其他就是背景。
障碍物内的值为 负,外的值为 正。
那么我们拿着两个一减就得到了SDF:

// image 中, alpha为 0 的表示背景
bool image_to_SDF(const QImage& image, cv::Mat* SDF)
{int r = image.height(), c = image.width();cv::Mat mat_background(r, c, CV_8UC1);for(int i = 0; i < r; i++){for(int j = 0; j < c; j++){mat_background.at<uchar>(i, j) = (image.pixelColor(j, i).alpha() == 0) ? 0 : 255;}}if(mat_background.empty()){qDebug() << "传了个空的image计算SDF";return false;} else {qDebug() << "准备计算sdf, 地图大小: rows = " << r << ", cols = " << c;}cv::Mat mat_background_dst; // 这里面为 0 的是障碍物, 为正的是背景cv::distanceTransform(mat_background, mat_background_dst, cv::DIST_L2, 5);cv::Mat mat_front(r, c, CV_8UC1); // 这里面为 0 的是障碍物cv::Mat mat_front_dst; // 这里面为 0 的是背景, 为正的是障碍物cv::bitwise_not(mat_background, mat_front);cv::distanceTransform(mat_front, mat_front_dst, cv::DIST_L2, 5);*SDF = mat_background_dst - mat_front_dst;return true;
}

再简单测试一下:

void Widget::on_pushButton_5_clicked()
{QImage image(21, 21, QImage::Format_ARGB32);for(int i = 0; i <= 20; i++){for(int j = 0; j <= 20; j++){if((5 < i && i < 15) && (5 < j && j < 15)) {image.setPixelColor(i, j, QColor(0, 0, 0, 0)); // 透明} else {image.setPixelColor(i, j, QColor(0, 0, 0, 255));}}}cv::Mat sdf;image_to_SDF(image, &sdf);QString ret;for(int r = 0; r < sdf.rows; r++){for(int c = 0; c < sdf.cols; c++){float f = sdf.at<float>(r, c);ret += QString::number(f).rightJustified(9, ' ');}   ret += "\n";}cv::imshow("sdf", sdf);std::cout << ret.toStdString();
}

输出结果:
在这里插入图片描述
不错,和预期的一致。

然后我们再测测性能,用 10000 x 10000 的 image 跑它10次:

void Widget::on_pushButton_6_clicked()
{QImage image(10000, 10000, QImage::Format_ARGB32);for(int i = 0; i < 10000; i++){for(int j = 0; j < 10000; j++){int cur = rand() % 500 + 1;image.setPixelColor(i, j, QColor(0, 0, 0, cur < 255 ? cur : 0));}}QElapsedTimer timer;timer.start();qDebug() << "begin:" << timer.nsecsElapsed() / 1000000.0 << "ms";for (int i = 0; i < 10; i++) {cv::Mat sdf;image_to_SDF(image, &sdf);qDebug() << "第" << i << "次计算完成, time : " << timer.nsecsElapsed() / 1000000.0 << "ms";}qDebug() << "end:" << timer.nsecsElapsed() / 1000000.0 << "ms";
}

在这里插入图片描述
有点慢,但看了下,主要慢在我们每次都构造了个 cv::Mat sdf,
这里得判断 10000 x 10000次 image 是不是透明的。
那么优化方案就很明显了,我们别每次重新构造 cv::Mat 了,
我们在创建、修改 QImage时,顺便带一个 cv::Mat,
算 SDF 时,直接使用这个 cv::Mat 就行。

bool get_SDF(const cv::Mat& background, cv::Mat* SDF)
{if(background.empty()){qDebug() << "传了个空的background计算SDF";return false;} else {qDebug() << "准备计算sdf, 地图大小: rows = " << background.rows << ", cols = " << background.cols;}cv::Mat background_dst; // 这里面为 0 的是障碍物, 为正的是背景cv::distanceTransform(background, background_dst, cv::DIST_L2, 5);cv::Mat front(background.rows, background.cols, CV_8UC1); // 这里面为 0 的是障碍物cv::Mat front_dst; // 这里面为 0 的是背景, 为正的是障碍物cv::bitwise_not(background, front);cv::distanceTransform(front, front_dst, cv::DIST_L2, 5);*SDF = background_dst - front_dst;return true;
}void Widget::on_pushButton_7_clicked()
{QImage background_image(10000, 10000, QImage::Format_ARGB32);cv::Mat background_mat(10000, 10000, CV_8UC1);for(int r = 0; r < 10000; r++){for(int c = 0; c < 10000; c++){int alpha = (rand() % 2 == 0) ? 0 : (rand() % 255 + 1); // 差不多 50% 是 0background_image.setPixelColor(c, r, QColor(0, 0, 0, alpha));background_mat.at<uchar>(r, c) = (alpha == 0) ? 0 : 255;}}QElapsedTimer timer;timer.start();qDebug() << "begin:" << timer.nsecsElapsed() / 1000000.0 << "ms";for (int i = 0; i < 10; i++) {cv::Mat sdf;get_SDF(background_mat, &sdf);qDebug() << "第" << i << "次计算完成, time : " << timer.nsecsElapsed() / 1000000.0 << "ms";}qDebug() << "end:" << timer.nsecsElapsed() / 1000000.0 << "ms";
}

在这里插入图片描述
嘿嘿,非常不错,效率高多了。
至于加载,那不是我们关心的,毕竟每个游戏登录时都会让你等半天。

嗯,不过我们可以看看创建一个 10000 x 10000 的 image要多久,以及带上一个 cv::Mat又要多久:

void Widget::on_pushButton_8_clicked()
{QElapsedTimer timer;timer.start();qDebug() << "begin:" << timer.nsecsElapsed() / 1000000.0 << "ms";for(int i = 0; i < 1; i++){QImage background_image(10000, 10000, QImage::Format_ARGB32);for(int r = 0; r < 10000; r++){for(int c = 0; c < 10000; c++){int alpha = (rand() % 2 == 0) ? 0 : (rand() % 255 + 1); // 差不多 50% 是 0background_image.setPixelColor(c, r, QColor(0, 0, 0, alpha));}}}qDebug() << "end:" << timer.nsecsElapsed() / 1000000.0 << "ms";timer.restart();qDebug() << "begin:" << timer.nsecsElapsed() / 1000000.0 << "ms";for(int i = 0; i < 1; i++){QImage background_image(10000, 10000, QImage::Format_ARGB32);cv::Mat background_mat(10000, 10000, CV_8UC1);for(int r = 0; r < 10000; r++){for(int c = 0; c < 10000; c++){int alpha = (rand() % 2 == 0) ? 0 : (rand() % 255 + 1); // 差不多 50% 是 0background_image.setPixelColor(c, r, QColor(0, 0, 0, alpha));background_mat.at<uchar>(r, c) = (alpha == 0) ? 0 : 255;}}}qDebug() << "end:" << timer.nsecsElapsed() / 1000000.0 << "ms";
}

在这里插入图片描述
可以看到差不了多久,说明 cv::Mat 的创建还是很快的。

在这里插入图片描述


希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!


http://www.hkcw.cn/article/longklZAwx.shtml

相关文章

【小米拥抱AI】小米开源 MiMo-7B-RL-0530

更新日志 [2025.05.30] 在强化学习训练过程中&#xff0c;通过持续扩大训练窗口尺寸&#xff08;从32K提升至48K&#xff09;&#xff0c;MiMo-7B-RL-0530模型在AIME24基准测试上的表现持续提升&#xff0c;最终超越DeepSeek R1模型的性能水平。 BenchmarkMiMo-7B-RLMiMo-7B-…

俄布良斯克州桥梁坍塌致列车脱轨事故造成3死28伤

△图片来源:莫斯科交通检察院总台记者当地时间6月1日获悉,据俄罗斯紧急情况部初步统计,布良斯克州桥梁坍塌致火车脱轨事故共造成31人伤亡,其中3人不幸遇难,28人已送往医疗机构救治。此前据俄罗斯BAZA网站报道,事件造成4人死亡,至少44人受伤。俄紧急情况部称,救援人员正…

JDK17 与JDK8 共同存在一个电脑上

官网下载JDK17 官网链接 &#xff1a;https://www.oracle.com/java/technologies/downloads/#java17-windows 下载这个 安装 环境变量设置 因为之前设置过JDK 8这里为了使 两者共存&#xff0c;采用设置变量方式来实现具体操作如下 1、进入高级系统环境设置 1.1先建一个关…

打开NRODIC SDK编译不过怎么处理,keil与segger studio

打开NRODIC SDK编译不过怎么处理,以下是keil处理. 1,如图,不要安装安装也不会过 2. 不要安装点击否 3.点击确定后进来这个样子 4.这里选择这个勾,OK后就不会再有后面的pack_license 5.去掉勾后这里要选择自己SDK对应的pack版本,我的是8.27.0 6.OK后弹出个界面也要反复选择…

每日八股文5.31

每日八股-5.31 Go1.切片是值传递还是引用传递&#xff1f;2.切片的深拷贝与浅拷贝3.切片的底层实现4.切片的扩容机制5.Map是线程安全的吗&#xff1f;6.哪些类型可以作为map的key&#xff1f;7.Map删除一个key内存是否会释放&#xff1f;8.Map为什么是无序的&#xff1f;9.如何…

智能重塑连接:AI原生互联网的范式革命与未来十年

引言:互联网的下一幕——智能涌现与体验重塑 2024年初,OpenAI发布的文生视频模型Sora,以其惊人的逼真度和对物理世界的理解能力,再次将人工智能的魔力推向了全球聚光灯下。这不仅仅是一个技术演示,更像是一个强烈的信号:我们正加速驶向一个由AI深度重塑的未来。回望互联…

【深度学习相关安装及配环境】Anaconda搭建虚拟环境并安装CUDA、cuDVV和对应版本的Pytorch,并在jupyter notebook上部署

目录 1. 查看自己电脑的cuda版本2.安装cuda关于环境变量的配置测试一下&#xff0c;安装完成 3.安装cuDVV环境变量的配置测试一下&#xff0c;安装完成 4.创建虚拟环境先安装镜像源下载3.11版本py 5.在虚拟环境下&#xff0c;下载pytorch6.验证是否安装成功7.在jupyter noteboo…

2. 手写数字预测 gui版

2. 手写数字预测 gui版 背景1.界面绘制2.处理图片3. 加载模型4. 预测5.结果6.一点小问题 背景 做了手写数字预测的模型&#xff0c;但是老是跑模型太无聊了&#xff0c;就配合pyqt做了一个可视化界面出来玩一下 源代码可以去这里https://github.com/Leezed525/pytorch_toy拿 …

用JS实现植物大战僵尸(前端作业)

1. 先搭架子 整体效果&#xff1a; 点击开始后进入主场景 左侧是植物卡片 右上角是游戏的开始和暂停键 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevic…

巴黎球迷打出TIFO悼念恩里克女儿 感人至深的纪念

北京时间6月1日,巴黎圣日耳曼在欧冠决赛中以5-0战胜国际米兰,夺得本赛季欧冠冠军。赛后,安联球场展示了一个感人至深的TIFO,主角是巴黎圣日耳曼主教练恩里克和他的已故女儿Xana。十年前,恩里克带领巴塞罗那夺得欧冠冠军时,曾与女儿Xana一起将巴萨的旗帜插进球场。然而,X…

六一儿童节 实践我先行活动举行

5月30日,在“六一”国际儿童节来临之际,“实践我先行——2025年在宋庆龄奶奶生活过的地方过六一”活动在北京宋庆龄故居举行,逾百名中外少年儿童和教师代表参加。活动现场,北京市西城区金融街惠泽幼儿园的小朋友们表演了群鼓节目《华夏少年》。中国宋庆龄基金会党组书记、副…

阿什拉夫弑旧主 破门后拒绝庆祝 情深义重

在欧冠决赛中,巴黎圣日耳曼迎战国际米兰。上半场,阿什拉夫攻破了老东家的大门,帮助巴黎取得领先。这位现年26岁的摩洛哥后卫曾在2020年至2021年效力于国际米兰,并为蓝黑军团出场45次。比赛进行到第12分钟时,阿什拉夫推射空门得手,将比分改写为1-0。进球后,他举起双手,拒…

端午安康(Python)

端午节总算是回家了&#xff0c;感觉时间过得真快&#xff0c;马上就毕业了&#xff0c;用Python弄了一个端午节元素的界面&#xff0c;虽然有点不像&#xff0c;祝大家端午安康。端午节粽子&#xff08;python&#xff09;_python画粽子-CSDN博客https://blog.csdn.net/weixin…

10.安卓逆向2-frida hook技术-frida基本使用-frida指令(用于hook)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码&#xff1…

# CppCon 2014 学习: Quick game development with C++11/C++14

这是一个关于游戏开发与现代 C&#xff08;尤其是 C11/C14&#xff09;结合的技术分享或讲座的概要&#xff0c;结构清晰、内容分为几个部分&#xff1a; About This Talk — 内容结构 1. 导言部分&#xff08;Introductory part&#xff09; 介绍为什么选择游戏开发作为主题…

vscode不满足先决条件问题的解决——vscode的老版本安装与禁止更新(附安装包)

目录 起因 vscode更新设置的关闭 安装包 结语 起因 由于主包用的系统是centos的&#xff0c;且版本有点老了&#xff0c;再加上vscode现在不支持老版本的&#xff0c;这对主包来说更是雪上加霜啊 但是主包看了网上很多教程&#xff0c;眼花缭乱&#xff0c;好多配置要改&…

如何手搓扫雷(待扩展)

文章目录 一、扫雷游戏分析与设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 文件结构设计 二、扫雷游戏的代码实现三、扫雷游戏的扩展总结 一、扫雷游戏分析与设计 扫雷游戏网页版 1.1 扫雷游戏的功能说明 使用控制台&#xff08;黑框框的程序&a…

Python打卡训练营学习记录Day41

DAY 41 简单CNN 知识回顾 数据增强卷积神经网络定义的写法batch归一化&#xff1a;调整一个批次的分布&#xff0c;常用与图像数据特征图&#xff1a;只有卷积操作输出的才叫特征图调度器&#xff1a;直接修改基础学习率 卷积操作常见流程如下&#xff1a; 1. 输入 → 卷积层 →…

我们来学mysql -- mysql8.4主从

mysql8.4主从 8.4安装主从原理主my.cnf启动创建复制用户 从my.cnf启动锁库&迁移数据连接主&开启复制检查复制 8.4安装 参考保姆级安装教程传送门 主从原理 从库准备 使用 CHANGE MASTER TO 配置主库信息并写入 master.info 文件。执行 START SLAVE 启动从库&#xff…

kafka学习笔记(三、消费者Consumer使用教程——消费性能多线程提升思考)

1.简介 KafkaConsumer是非线程安全的&#xff0c;它定义了一个acquire()方法来检测当前是否只有一个线程在操作&#xff0c;如不是则会抛出ConcurrentModifcationException异常。 acquire()可以看做是一个轻量级锁&#xff0c;它仅通过线程操作计数标记的方式来检测线程是否发…