matlab畸变校正代码_关于OpenCV中的去畸变

45c644776380ebf563be09c69a83a5a8.png

在opencv中,有关图像或像素点(角点)去畸变的函数有cv::undistort(),cv::getOptimalNewCameraMatrix(),cv::initUndistortRectifyMap(),remap(),cv::undistortPoints()。其中undistort可以直接对图像去畸变,getOptimalNewCameraMatrix、initUndistortRectifyMap和remap配合也可以对图像去畸变,他们之间有相同之处,又有各自特性,而undistortPoints是只针对像素点去畸变。下面就使用方法及细节进行梳理,并给出代码示例,以便加深印象。

1. 函数功能及参数介绍

1.1 cv::getOptimalNewCameraMatrix()

函数参数说明:

Mat cv::getOptimalNewCameraMatrix	
(	InputArray 	cameraMatrix,                  // 相机内参矩阵InputArray 	distCoeffs,                    // 相机畸变参数Size 	        imageSize,                     // 图像尺寸double 	        alpha,                         // 缩放比例Size 	        newImgSize = Size(),           // 校正后的图像尺寸Rect * 	        validPixROI = 0,               // 输出感兴趣区域设置bool 	        centerPrincipalPoint = false   // 可选标志
)	

这个函数的功能是,"Return the new camera matrix based on the free scaling parameter",即根据根据比例因子返回相应的新的相机内参矩阵。

这里的"比例因子"就是函数的第四个参数(alpha),这个参数的范围是(0, 1)。调节alpha的值能够控制得到的新矩阵中的fx和fy的大小。

当alpha=1的时候,原图像中的所有像素能够得到保留,因此这个时候得到的矫正后的图像是带黑框的,如后面图1所示。

当alpha=0时,得到的图像是不带黑色边框的,相对于原图像,此时的图像损失了部分像素,如后面图2所示。alpha的值控制着具体损失多少像素。

alphanewImageSize是两个互不干扰的参数,alpha只管是否对图像进行裁剪,而newImageSize只负责把图像进行缩放,这二者都会对返回的新的相机参数造成影响.

1.2 cv::initUndistortRectifyMap()

函数参数说明:

void cv::initUndistortRectifyMap	
(	InputArray 	cameraMatrix,     // 原相机内参矩阵InputArray 	distCoeffs,       // 原相机畸变参数InputArray 	R,                // 可选的修正变换矩阵 InputArray 	newCameraMatrix,  // 新相机内参矩阵Size 	        size,             // 去畸变后图像的尺寸int 	        m1type,           // 第一个输出的映射(map1)的类型,CV_32FC1 or CV_16SC2OutputArray 	map1,             // 第一个输出映射OutputArray 	map2              // 第二个输出映射
)	

这个函数用于计算原始图像和矫正图像之间的转换关系,将结果以映射的形式表达,映射关系存储在map1和map2中。

在单目相机例子中,newCameraMatrix可以用cv::getOptimalNewCameraMatrix来计算,或者直接与cameraMatrix相等。在双目相机例子中,newCameraMatrix一般是用cv::stereoRectify计算而来的(这里不做讨论)。

1.3 cv::remap()

void cv::remap
(       InputArray    src,                        // 原始图像OutputArray   dst,                        // 矫正图像           InputArray    map1,                       // 第一个映射          InputArray    map2,                       // 第二个映射      int           interpolation,              // 插值方式int           borderMode=BORDER_CONSTANT, // 边界模式           const Scalar& borderValue=Scalar()        // 边界颜色,默认Scalar()黑色   
)

函数功能:把原始图像中某位置的像素映射到矫正后的图像指定位置。

这里的map1和map2就是上面cv::initUndistortRectifyMap()计算出来的结果。

1.4 cv::undistort()

void cv::undistort	
(	InputArray 	src,                        // 原始图像OutputArray 	dst,                        // 矫正图像InputArray 	cameraMatrix,               // 原相机内参矩阵InputArray 	distCoeffs,                 // 相机畸变参数InputArray 	newCameraMatrix = noArray() // 新相机内参矩阵
)	

函数功能:直接对图像进行畸变矫正。

其内部调用了initUndistortRectifyMap和remap函数。

1.5 cv::undistortPoints()

void cv::undistortPoints	
(	InputArray 	src,            // 原始像素点矩阵  1xN or Nx1 (CV_32FC2 or CV_64FC2).OutputArray 	dst,            // 矫正像素点矩阵InputArray 	cameraMatrix,   // 原相机内参矩阵InputArray 	distCoeffs,     // 相机畸变参数InputArray 	R = noArray(),  // 可选的修正变换矩阵InputArray 	P = noArray()   // 新的相机矩阵
)

函数功能:只对图像中的某些点做畸变矫正。

2. 示例代码

2.1 使用 getOptimalNewCameraMatrix + initUndistortRectifyMap + remap 矫正图像

//
// Created by jiang on 2020/4/29.
//
#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;int main()
{const cv::Mat K = ( cv::Mat_<double> ( 3,3 ) << 931.73, 0.0, 480.0, 0.0, 933.16, 302.0, 0.0, 0.0, 1.0 );const cv::Mat D = ( cv::Mat_<double> ( 5,1 ) << -1.7165e-1, 1.968259e-1, 0.0, 0.0, -3.639514e-1 );const string str = "/home/jiang/4_learn/WeChatCode/ImageUndistort/data/";const int nImage = 5;const int ImgWidth = 960;const int ImgHeight = 640;cv::Mat map1, map2;cv::Size imageSize(ImgWidth, ImgHeight);const double alpha = 1;cv::Mat NewCameraMatrix = getOptimalNewCameraMatrix(K, D, imageSize, alpha, imageSize, 0);initUndistortRectifyMap(K, D, cv::Mat(), NewCameraMatrix, imageSize, CV_16SC2, map1, map2);for(int i=0; i<nImage; i++){string InputPath = str + to_string(i) + ".png";cv::Mat RawImage = cv::imread(InputPath);cv::imshow("RawImage", RawImage);cv::Mat UndistortImage;remap(RawImage, UndistortImage, map1, map2, cv::INTER_LINEAR);cv::imshow("UndistortImage", UndistortImage);string OutputPath = str + to_string(i) + "_un" + ".png";cv::imwrite(OutputPath, UndistortImage);cv::waitKey(0);}return 0;
}

当alpha=1时,所有像素均保留,但存在黑色边框,矫正后的图像如图1所示。

当alpha=0时,损失最多的像素,没有黑色边框,矫正后的图像如图2所示。

843b0e9b94432380b9766e0e988d6097.png
图1 alpha=1,所有像素均保留,带黑框。

35c2316efa8212d45a2d38f865fdf066.png
图2 alpha=0,损失最多的像素,无黑框。

2.2 使用 undistort 矫正图像

//
// Created by jiang on 2020/4/29.
//
#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;int main()
{const cv::Mat K = ( cv::Mat_<double> ( 3,3 ) << 931.73, 0.0, 480.0, 0.0, 933.16, 302.0, 0.0, 0.0, 1.0 );const cv::Mat D = ( cv::Mat_<double> ( 5,1 ) << -1.7165e-1, 1.968259e-1, 0.0, 0.0, -3.639514e-1 );const string str = "/home/jiang/4_learn/WeChatCode/ImageUndistort/data/";const int nImage = 5;const int ImgWidth = 960;const int ImgHeight = 640;cv::Mat map1, map2;cv::Size imageSize(ImgWidth, ImgHeight);const double alpha = 1;cv::Mat NewCameraMatrix = getOptimalNewCameraMatrix(K, D, imageSize, alpha, imageSize, 0);for(int i=0; i<nImage; i++){string InputPath = str + to_string(i) + ".png";cv::Mat RawImage = cv::imread(InputPath);cv::imshow("RawImage", RawImage);cv::Mat UndistortImage;cv::undistort(RawImage, UndistortImage, K, D, K);
//        cv::undistort(RawImage, UndistortImage, K, D, NewCameraMatrix);cv::imshow("UndistortImage", UndistortImage);string OutputPath = str + to_string(i) + "_un2" + ".png";cv::imwrite(OutputPath, UndistortImage);cv::waitKey(0);}return 0;
}

如果undistort函数的最后一个参数使用原相机内参,那么得到的结果就是上面图2的结果,相当于alpha=0的情况。

如果undistort函数的最后一个参数使用getOptimalNewCameraMatrix计算出来的新矩阵,那么得到损失像素后的图像,当alpha=1时,就得到上面图1的结果。

如果像我示例程序一样,有多个图片需要矫正,那么推荐使用2.1的方法,因为initUndistortRectifyMap函数只需要计算一次就行,不需要每次循环都计算,可以像我程序中一样,将initUndistortRectifyMap放在循环外面。而使用2.2的方法,因为undistort函数内部调用了initUndistortRectifyMap和remap,所以相当于你n张图像计算了n次initUndistortRectifyMap,这会大大降低效率,增加程序耗时。

2.3 使用 undistortPoints 矫正角点

方法一:

//
// Created by jiang on 2020/4/29.
//
#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;const cv::Mat K = ( cv::Mat_<double> ( 3,3 ) << 931.73, 0.0, 480.0, 0.0, 933.16, 302.0, 0.0, 0.0, 1.0 );
const cv::Mat D = ( cv::Mat_<double> ( 5,1 ) << -1.7165e-1, 1.968259e-1, 0.0, 0.0, -3.639514e-1 );void UndistortKeyPoints(vector<cv::Point2f> &points);int main()
{const string str = "/home/jiang/4_learn/WeChatCode/ImageUndistort/data/";const int nImage = 5;const int MAX_CNT = 150;const int MIN_DIST = 30;for(int i=0; i<nImage; i++){string InputPath = str + to_string(i) + ".png";cv::Mat RawImage = cv::imread(InputPath);vector<cv::Point2f> pts;cv::Mat RawImage_Gray;cv::cvtColor(RawImage, RawImage_Gray, CV_RGB2GRAY);cv::goodFeaturesToTrack(RawImage_Gray, pts, MAX_CNT, 0.01, MIN_DIST);for(auto& pt:pts)circle(RawImage, pt, 2, cv::Scalar(255, 0, 0), 2);cv::imshow("pts", RawImage);UndistortKeyPoints(pts);cv::Mat UndistortImage;cv::undistort(RawImage, UndistortImage, K, D, K);for(auto& pt:pts)circle(UndistortImage, pt, 2, cv::Scalar(0, 0, 255), 2);cv::imshow("pts_un", UndistortImage);string OutputPath = str + to_string(i) + "_pts_un" + ".png";cv::imwrite(OutputPath, UndistortImage);cv::waitKey(0);}return 0;
}void UndistortKeyPoints(vector<cv::Point2f> &points)
{if(D.at<float>(0)==0.0)    // 图像矫正过return;// N为提取的特征点数量,将N个特征点保存在N*2的mat中uint N = points.size();cv::Mat mat(N,2,CV_32F);for(int i=0; i<N; i++){mat.at<float>(i,0)=points[i].x;mat.at<float>(i,1)=points[i].y;}// 调整mat的通道为2,矩阵的行列形状不变mat=mat.reshape(2);cv::undistortPoints(mat, mat, K, D, cv::Mat(), K);mat=mat.reshape(1);// 存储校正后的特征点for(int i=0; i<N; i++){cv::Point2f kp = points[i];kp.x=mat.at<float>(i,0);kp.y=mat.at<float>(i,1);points[i] = kp;}
}

方法二:

//
// Created by jiang on 2020/4/29.
//
#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;const cv::Mat K = ( cv::Mat_<double> ( 3,3 ) << 931.73, 0.0, 480.0, 0.0, 933.16, 302.0, 0.0, 0.0, 1.0 );
const cv::Mat D = ( cv::Mat_<double> ( 5,1 ) << -1.7165e-1, 1.968259e-1, 0.0, 0.0, -3.639514e-1 );void UndistortKeyPoints(vector<cv::Point2f> &points, cv::Mat &newCamMatrix);int main()
{const string str = "/home/jiang/4_learn/WeChatCode/ImageUndistort/data/";const int nImage = 5;const int ImgWidth = 960;const int ImgHeight = 640;const int MAX_CNT = 150;const int MIN_DIST = 30;cv::Mat map1, map2;cv::Size imageSize(ImgWidth, ImgHeight);const double alpha = 1;cv::Mat NewCameraMatrix = getOptimalNewCameraMatrix(K, D, imageSize, alpha, imageSize, 0);initUndistortRectifyMap(K, D, cv::Mat(), NewCameraMatrix, imageSize, CV_16SC2, map1, map2);for(int i=0; i<nImage; i++){string InputPath = str + to_string(i) + ".png";cv::Mat RawImage = cv::imread(InputPath);cv::Mat UndistortImage;cv::remap(RawImage, UndistortImage, map1, map2, cv::INTER_LINEAR);vector<cv::Point2f> pts;cv::Mat RawImage_Gray;cv::cvtColor(RawImage, RawImage_Gray, CV_RGB2GRAY);cv::goodFeaturesToTrack(RawImage_Gray, pts, MAX_CNT, 0.01, MIN_DIST);for(auto& pt:pts)circle(RawImage, pt, 2, cv::Scalar(255, 0, 0), 2);cv::imshow("pts", RawImage);UndistortKeyPoints(pts, NewCameraMatrix);for(auto& pt:pts)circle(UndistortImage, pt, 2, cv::Scalar(0, 0, 255), 2);cv::imshow("pts_un", UndistortImage);string OutputPath = str + to_string(i) + "_pts_un" + ".png";cv::imwrite(OutputPath, UndistortImage);cv::waitKey(0);}return 0;
}void UndistortKeyPoints(vector<cv::Point2f> &points, cv::Mat &newCamMatrix)
{if(D.at<float>(0)==0.0)    // 图像矫正过return;// N为提取的特征点数量,将N个特征点保存在N*2的mat中uint N = points.size();cv::Mat mat(N,2,CV_32F);for(int i=0; i<N; i++){mat.at<float>(i,0)=points[i].x;mat.at<float>(i,1)=points[i].y;}// 调整mat的通道为2,矩阵的行列形状不变mat=mat.reshape(2);cv::undistortPoints(mat, mat, K, D, cv::Mat(), newCamMatrix);mat=mat.reshape(1);// 存储校正后的特征点for(int i=0; i<N; i++){cv::Point2f kp = points[i];kp.x=mat.at<float>(i,0);kp.y=mat.at<float>(i,1);points[i] = kp;}
}

先使用cv::goodFeaturesToTrack函数在图像中提取一些FAST角点,如图3所示。

44fefda5f3aaac69d36adde3b37aabab.png
图3 FAST角点提取

然后对这些角点去畸变,注意,我们矫正后的点是不能直接打印在原图像上的,所以我们需要先对图像去畸变(这里的两种方法就是为了应对两种不同的图像矫正),然后将矫正后的点打印在矫正后的图像上。矫正结果如图3所示。

58e3f556144dc0dc11ab68a77931651d.png
图4 FAST角点去畸变

注意,undistortPoints和undistort函数都有newCameraMatrix参数,这两个函数要使用相同的newCameraMatrix参数,这样才能将去畸变的点和去畸变的图像对应起来,这里的newCameraMatrix使用原相机内参。

2.4 undistortPoints 矫正BoundingBox

//
// Created by jiang on 2020/4/29.
//
#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;const cv::Mat K = ( cv::Mat_<double> ( 3,3 ) << 931.73, 0.0, 480.0, 0.0, 933.16, 302.0, 0.0, 0.0, 1.0 );
const cv::Mat D = ( cv::Mat_<double> ( 5,1 ) << -1.7165e-1, 1.968259e-1, 0.0, 0.0, -3.639514e-1 );void UndistortBbox(cv::Rect &rect, cv::Mat &newCamMatrix);int main()
{const string str = "/home/jiang/4_learn/WeChatCode/ImageUndistort/data/";const int nImage = 5;const int ImgWidth = 960;const int ImgHeight = 640;cv::Mat map1, map2;cv::Size imageSize(ImgWidth, ImgHeight);const double alpha = 1;cv::Mat NewCameraMatrix = getOptimalNewCameraMatrix(K, D, imageSize, alpha, imageSize, 0);initUndistortRectifyMap(K, D, cv::Mat(), NewCameraMatrix, imageSize, CV_16SC2, map1, map2);cv::Rect Bbox{338, 141, 23, 57};for(int i=0; i<nImage; i++){string InputPath = str + to_string(i) + ".png";cv::Mat RawImage = cv::imread(InputPath);cv::Mat UndistortImage;cv::remap(RawImage, UndistortImage, map1, map2, cv::INTER_LINEAR);
//        cv::undistort(RawImage, UndistortImage, K, D, K);cv::rectangle(RawImage, Bbox, cv::Scalar(255, 0, 0), 2, 1);cv::imshow("RawImage", RawImage);string OutputPath1 = str + to_string(i) + "_Bbox" + ".png";cv::imwrite(OutputPath1, RawImage);UndistortBbox(Bbox, NewCameraMatrix);cv::rectangle(UndistortImage, Bbox, cv::Scalar(0, 0, 255), 2, 1);cv::imshow("UndistortImage", UndistortImage);string OutputPath2 = str + to_string(i) + "_Bbox_un" + ".png";cv::imwrite(OutputPath2, UndistortImage);cv::waitKey(0);}return 0;
}void UndistortBbox(cv::Rect &rect, cv::Mat &newCamMatrix)
{cv::Mat mat(4, 2,  CV_32F);mat.at<float>(0, 0) = rect.x;mat.at<float>(0, 1) = rect.y;mat.at<float>(1, 0) = rect.x + rect.width;mat.at<float>(1, 1) = rect.y;mat.at<float>(2, 0) = rect.x;mat.at<float>(2, 1) = rect.y + rect.height;mat.at<float>(3, 0) = rect.x + rect.width;mat.at<float>(3, 1) = rect.y + rect.height;mat = mat.reshape(2);  // 2通道,行列不变cv::undistortPoints(mat, mat, K, D, cv::Mat(), newCamMatrix);mat = mat.reshape(1);  // 单通道,行列不变double MaxX, MaxY;rect.x = min(mat.at<float>(0, 0), mat.at<float>(2, 0));MaxX   = max(mat.at<float>(1, 0), mat.at<float>(3, 0));rect.y = min(mat.at<float>(0, 1), mat.at<float>(1, 1));MaxY   = max(mat.at<float>(2, 1), mat.at<float>(3, 1));rect.width = MaxX - rect.x;rect.height = MaxY - rect.y;
}

这里我们手动画了一个Bbox{338,141,23,57}。然后用remap的方式矫正了图像。

在矫正BoundingBox也就是矫正BoundingBox的四个点。只是这里有一个细节要考虑,就是Bbox的四个角点在矫正后的大小不确定,因此要判断一下。矫正前的图像如图5所示,矫正后的图像如图6所示。

f4edc3ea128bdf499b79f3a37113b17a.png
图5 Bbox矫正前

fbe6323c52c92df4c7cb1e3dc0491ae4.png
图6 Bbox矫正后

3. 总结与补充

关于图像、角点和Bbox的去畸变就介绍到这里,后续有更深入的研究在加以补充。本人才疏学浅,如文章中有错误,还请读者不吝赐教,吾当感激不尽。

文中用的opencv版本是3.3.0,CMakeLists如下:

cmake_minimum_required(VERSION 3.14)
project(ImageUndistort)set(CMAKE_CXX_STANDARD 11)set(OpenCV_DIR "/home/jiang/6_lib/install/opencv3.3.0/share/OpenCV")find_package(OpenCV REQUIRED)add_executable(undistort2_1 undistort2_1.cpp)
target_link_libraries(undistort2_1${OpenCV_LIBS}
)add_executable(undistort2_2 undistort2_2.cpp)
target_link_libraries(undistort2_2${OpenCV_LIBS})add_executable(undistort2_3_1 undistort2_3_1.cpp)
target_link_libraries(undistort2_3_1${OpenCV_LIBS})add_executable(undistort2_3_2 undistort2_3_2.cpp)
target_link_libraries(undistort2_3_2${OpenCV_LIBS})add_executable(undistort2_4 undistort2_4.cpp)
target_link_libraries(undistort2_4${OpenCV_LIBS})

完整的代码在这里:

https://github.com/JiangZhengok/WeChatCode/tree/master/ImageUndistort​github.com

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis数据库简介、redis下载及安装(win64位)、node操作redis、redis实现短信校验注册接口

redis简介&#xff1a; 1:内存数据库,同时也能够保存数据到磁盘&#xff1b; 2:比其他的内存数据库有着更多的数据类型&#xff1a; 列表,集合,排序集合,哈希表等; 3:主从结构&#xff1a;数据可以备份到从服务器&#xff1b; 4: Redis数据操作速度快; 5:所有的操作都是原…

go func()和 go_Go的泛型真的要来了—如何使用以及它们是怎么工作的

点击上方蓝色“Go语言中文网”关注我们&#xff0c;领全套Go资料&#xff0c;每天学习 Go 语言你没看错&#xff0c;这里讲的就是 Go 中的泛型。只不过还没有正式发布&#xff0c;是基于草案设计的&#xff0c;已经是实现了可运行的版本。所以&#xff0c;泛型到来真的不远了&a…

bios设置_bios怎么设置显存 bios设置显存教程【图文】

有些用户可能会发现打开电脑系统信息窗口显示的内存容量与实际容量不同&#xff0c;例如系统内存显示4G&#xff0c;可用3.73G。那么不可用的那部分内存到哪里去了呢?其实是被集成显卡占用当做显存使用了。下面我们就通过 bios设置显存 来调整占用内存容量的大小&#xff0c;我…

4变形物体_Houdini基础(二)曲线变形物体

设想&#xff1a;先从二维上来看直角坐标系。物体是由x&#xff0c;y两个轴向的数据组成的。少了其中一组数据物体就只能是分布在单一轴向上的点。单独保留物体x、y情况下的点分布情况现在将x、y加起来&#xff0c;可见在三维空间中形成了一个平面。仅有x、y坐标的物体从目前的…

mybatis 映射成多个list_SSM:Mybatis架构与原理

MyBatis功能架构设计功能架构讲解&#xff1a;我们把Mybatis的功能架构分为三层&#xff1a;API接口层&#xff1a;提供给外部使用的接口API&#xff0c;开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。数据处理层&…

10无法勾选隐藏的项目_Excel超好用的隐藏操作,不可多得

日常工作中&#xff0c;表格数据的展示与隐藏也是有大学问的&#xff0c;为了表格更加简洁明了、美观大气&#xff0c;实用的隐藏技巧就派上用场了。且听小翼慢慢分享~1、隐藏行列方法1&#xff1a;选中目标区域&#xff0c;右击鼠标选择“隐藏”即可。如图&#xff1a;方法2&a…

HTML5简略介绍

今天要说下 HTML5特有的一个元素 canvas &#xff0c;旨在让web页面上作矢量图不需要在依靠flash或是其他插件&#xff0c;在网页上使用canvas元素时&#xff0c;它会创建一块矩形区域&#xff0c;默认300*150&#xff0c;当然也是可以自定义的。Canvas中的坐标是从左上角开始的…

我的世界java和基岩版哪个好玩_我的世界:Java版本好玩还是基岩版好玩?老玩家看完后沉默了...

MC刚开始是在国外风靡了起来&#xff0c;传到中国的时候MC已经火了很久了&#xff0c;这时候外国已经出现了很多玩MC十分厉害的大神和主播&#xff0c;而在国外也有超多的服务器&#xff0c;其中有号称最强的原版生存服务器Scicraft&#xff0c;而在版本方面MC其实算下来大概有…

SQL Server简介

SQL Server是微软的一款关系型数据库。某些平台吹得天花烂坠&#xff0c;今天第一次在自己的项目中使用了下&#xff0c;感觉不是那么好&#xff0c;特别是SQL语句的支持度还是很欠缺&#xff0c;如limit等都不支持&#xff0c;还有特别单双引号都是需要特别注意的,下面是SQL S…

Windows下断言的类型及实现

一、内容综述 本文主要介绍Windows下断言assert的实现&#xff0c;并总结断言的不同应用准则。最后给出一个windows自定义断言的方法。 本文行文参考《Debugging Windows Programs》第三章相关内容&#xff0c;如果有兴趣的话建议读者可以深入阅读下。 二、断言的类型 1. ANSI…

linux右上角不显示网络连接_来体验下Linux吧

在前面的几期中我们从树莓派开始了解Linux&#xff0c;大家可能已经想来试一下手了。趁热打铁&#xff0c;本期我将介绍两种方便体验学习Linux的方法&#xff0c;在线体验或者安装虚拟机。1 在线体验Linux如果想快速的体验下Linux系统&#xff0c;我们可以选择云计算服务商提供…

python md5解密_python 生成文件MD5码

pymd5.py的代码如下&#xff1a; #-*-coding:utf-8-*-Created on 2012-5-25 author: kanpiaoxueimport hashlib import os import sys def printUsage(): print (Usage: [python] pymd5.py ) def createMD5(filePath): if not os.path.isfile(filePath): printUsage() else: tm…

Java数据结构、list集合、ArrayList集合、LinkedList集合、Vector集合

数据结构&#xff1a; 数据存储的常用结构有&#xff1a;栈、队列、数组、链表、红黑树。 栈&#xff1a;stack,又称堆栈&#xff0c;它是运算受限的线性表&#xff0c;其限制是仅允许在标的一端进行插入和删除操作&#xff0c;不允许在其他任何位置进行添加、查找、删除等操…

第11章 GUI Page436 使用缓冲DC, wxBufferedPaintDC

所谓“缓冲DC”&#xff0c;是指将所有图元都先划到一个人眼看不到的“设备上下文”之上&#xff0c;最后再一次性复制到真正的屏幕DC之上&#xff0c;这样我们就看不到中间画的过程了&#xff0c;也就不会感到闪烁了。 注意&#xff0c;这时不能解除ScrolledWindow1的背景擦除…

Tomcat+JSP经典配置实例

经常看到jsp的初学者问tomcat下如何配置jsp、servlet和bean的问题&#xff0c;于是总结了一下如何tomcat下配置jsp、servlet和ben&#xff0c;希望对那些初学者有所帮助。    一、开发环境配置    第一步&#xff1a;下载j2sdk和tomcat&#xff1a;到sun官方站&#xf…

python海龟编辑器画小汽车_【海龟编辑器下载】海龟编辑器(Python编辑器) v1.3.4 官方免费版-趣致软件园...

海龟编辑器是一款专为广大少儿打造的Python编辑器&#xff0c;该软件功能强大且使用便利&#xff0c;可以帮助孩子们以搭积木的方式来学习Python&#xff0c;并且支持Python代码和图形化积木的双向互相转译&#xff0c;不但可以有效提升孩子的学习兴趣&#xff0c;而且还能够降…

微信小程序中组件的使用

微信小程序中组件的使用&#xff1a; 微信小程序中组件定义在项目根目录下components文件夹下&#xff0c;在页面使用的时候需要在页面的json文件中声明&#xff0c;如 父组件向子组件传值及子组件向父组件传值&#xff1a; 父组件wxml中&#xff1a;通过属性绑定值的方式向…

如何保证交叉表编译器和目标系统版本一致_嵌入式系统词汇表

欢迎FPGA工程师加入官方微信技术群点击蓝字关注我们FPGA之家-中国最好最大的FPGA纯工程师社群AASIC(专用集成电路) Application-Specific Integrated Circuit. A piece of custom-designed hardware in a chip. 专用集成电路。一个在一个芯片上定制设计的硬件。address bus (地…

动态定义数组

首先&#xff1a;为什么需要动态定义数组呢&#xff1f; 这是因为&#xff0c;很多情况下&#xff0c;在预编译过程阶段&#xff0c;数组的长度是不能预先知道的&#xff0c;必须在程序运行时动态的给出 但是问题是&#xff0c;c要求定义数组时&#xff0c;必须明确给定数组的…

sql随机抽取数据50条_厉害!苏宁通过citus打造分布式数据库抗住DB高负载

2018-07-16 23:59内容来源&#xff1a;2017 年 10 月 20 日&#xff0c;苏宁云商IT总部资深技术经理陈华军在“PostgreSQL 2017中国技术大会”进行《苏宁citus分布式数据库应用实践》演讲分享。IT 大咖说&#xff08;微信id&#xff1a;itdakashuo&#xff09;作为独家视频合作…