OpenCV安装教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

2023-05-16

目录

0.写作背景

1.安装visual studio

2.下载OpenCV相关的源码

下载OpenCV原始的源码

  下载OpenCV contrib的源码 

下载安装cmake

3.cmake编译OpenCV

初始编译

CmakeDownload的bug修复

OpenCV-crontrib编译:

Generate生成代码

VS生成代码:

报错修复

 4.Visual Studio配置变量

 5.Case测试:

初始测试

SIFT算子测试

SURF算子测试

6.总结

7.参考链接:

8.预告:关于修改源码


0.写作背景

        OpenCV可能是目前使用最广泛的开源图像处理工具了,尤其是在科研领域。

        在读研期间进行图像拼接相关的科研工作时候,我遇到了和OpenCV相关很棘手的两个问题:

        1.为什么的我的OpenCV安装不成功???

        2.为什么我的OpenCV不能修改源码?

        那个时候CSDN上的相关资料也不多,甚至现在关于OpenCV安装的很多问题,CSDN上说的也不算很清楚。与此同时那段时间也是自己比较艰难的一段时间,在OpenCV上花了很多时间和精力才终于解决了上述两个问题。我在此分享一下如何解决这两个问题。

        本篇主要详细记录一下如何在Windows 操作系统下,搭建Visual Studio+OpenCV+OpenCV contrib的运行环境。

1.安装visual studio

        关于安装visual studio,最保险的方法首先去官网下载安装器:

下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux

        暂时使用Community版本就好,尤其是对学生or个人用户而言。

         然后安装的时候,参考第一个"参考链接"(我自己安装的时候忘记截图了啦真的是很对不起了啦,谁要是质疑我就很机车了啦):

         然后只要选择"使用C++的桌面开发"就好。

         然后一路默认安装就好。

        本地随便建一个新项目运行:

         选择“控制台应用”:

         项目建立之后,点击"本地Windows调试器":

         然后就可以运行输出HelloWorld了:

2.下载OpenCV相关的源码

下载OpenCV原始的源码

        既然要下载源码了,我们还是去OpenCV的官网,下载最新的release版本:

Releases - OpenCV

                截止至2022年4月4号,最新的Release版本是OpenCV – 4.5.5。我们下载Sources(后面修改源码需要用到):

         下载之后解压到特定文件夹,当前case之中我解压到了E:\Downloads\opencv-4.5.5

  下载OpenCV contrib的源码 

        然后我们去下载OpenCV contrib,官网链接:

GitHub - opencv/opencv_contrib: Repository for OpenCV's extra modules

Q:为什么要下载OpenCV contrib呢?

A:因为自从OpenCV 3.0之后,很多经典的算法,比如sift和surf特征点检测算法,由于专利原因,已经不包含在OpenCV的源码当中了,需要下载OpenCV contrib包才能继续使用。

        OpenCV contrib的版本记得要和OpenCV版本符合哦(例如上图我们选择的是4.X版本)。还是要下载源码哦。

下载完解压,本文的路径为:E:\Downloads\opencv_contrib-4.x

下载安装cmake

之后我们还需要去下载cmake 用于编译OpenCV。

这里别下载错了下载成source了。在安装OpenCV的过程之中,我们只需要使用Cmake的gui程序图像化运行就好,不需要去管cmake的源码。

下载完解压,本文的解压地址为:E:\Downloads\cmake-3.23.0-windows-x86_64。在bin目录下运行cmake-gui.exe即可。

 

3.cmake编译OpenCV

前置工作结束就需要开始编译OpenCV了。

初始编译

1.第一步先按下图操作:

 2.弹窗出来的配置,按照自己的开发环境配置即可(本文的环境是VS 2022,平台是X64平台),然后点击"Finish"即可:

 3.cmake的窗口开始打印信息:

 打印出来的信息中如果出现python、matlab相关的报错,例如下图,直接pass。(Python……ptsd,想到python就ptsd……想起某人爱用python造轮子……) 

这一步需要等到cmake初始编译完成。

CmakeDownload的bug修复

这一步很多博客都没有写清楚如何排查,导致很多新手在之后VisualStudio阶段导包的时候出错。

上一步完成之后,大部分情况下会报错。

不出意外会看到如下的报错信息。

 仔细阅读之后,我们应该查看一下CMakeDownloadLog.txt。

使用Notepad++或者其他软件打开CMakeDownloadLog.txt,

        有时间的同学自己阅读和翻译。我直接说一下问题:Cmake去下载相关的包没有下载下来。

        所以根据红框处的信息我们需要自行下载,方法:将链接输入到浏览器,然后就会自动下载。一些链接输入到浏览器之后,显示的是文本,那么就将文本拷贝到本地并重命名,如下图的cmake文件。

        这种情况,就ctrl+s保存,注意命名。

        此处我不把包上传到CSDN上,因为版本更新之后还是有可能遇到同样问题,希望后续OpenCV版本更新之后,大家能自行解决问题。

        另外此处的链接可能会被屏蔽,大家自行找办法下载。        

        下载之后将这些包拷贝到.cache文件夹下,并且需要更改包的名字(cmake下载包之后将校验的hash码重命名到了包中),下图以ippcv包为例:

下载的包原名为:

ippicv_2020_win_intel64_20191018_general.zip         

复制到CmakeDownloadLog.txt中的.cache文件夹下,并改名为:

879741a7946b814455eee6c6ffde2984-ippicv_2020_win_intel64_20191018_general.zip

 其他的包同上。不赘述。

这些拷贝结束之后,我们重新configure:

然后我们在看CmakeDownLoadLog.txt,已经不报错了:

cmake也不标红和报错了:

OpenCV-crontrib编译:

在cmake的OPENCV_EXTRA_MODULES_PATH之中输入之前下载的OpenCV-contrib的路径(精确到modules:

 

 再次configure,然后又看到一大堆报错:

 查看CmakeDownLoadLog.txt,是的,又来了:

再次下载吧。(有一说一,多了好多微信二维码的内容,不愧是你,腾讯!不愧是你,化腾!) 

        下载完成,再次configure,并查看CmakeDownLoadLog.txt,好的不报错了。PS:如果过程中发现CmakeDownLoadLog.txt还是有报错,继续下载,继续复制。

        另外在多次configure过程中,每次都会尝试从.cache文件中获取原始文件,再拷贝到build之后的文件夹下面,复制的过程也会打日志的。建议多点几次configure。

        最后我们查看CmakeDownLoadLog.txt,我们会看到如下信息: 

终于都是match了,开心! 

注:史前大坑:OPENCV_ENABLE_NONFREE一定要勾选上啊!否则Nonfree没法用。

Generate生成代码

上述工作检查无误,到了这一步才可以点击Generate哦。

VS生成代码:

找到build之后的OpenCV.sln文件,用VS打开。

 右键项目,并点击“重新生成解决方案”:

另外这里只是生成了debug版本,后面记得把Release版本也生成一下,Debug和Relea版本都生成之后,后续的代码才能在debug和release两个环境下运行。

 这一步会等很久,等待时间从2小时到12个小时不等。

(注:这里有点错误,参考了其他一些链接,实际上只需要对CMakeTargets文件夹下的Install进行重新生成即可,如下图,但是全部重新生成应该也不影响)。

报错修复

之前安装OpenCV 3.X版本没有遇到过这个错误,这次遇到了,就尝试修复一下吧。参考链接4。 

vs2022重新编译opencv-python cuda加速时报错_Harry Xu的博客-CSDN博客

解决方法的核心就是找到出错的文件,然后保存为Unicode格式的文件即可。

 个人猜测这个问题不修复也不会怎么影响OpenCV大部分功能的使用。

 然后重新生成,可以看到没有报错了(无论是debug还是release版本)。

注:如果只重新生成INSTALL的话,之前的报错应该是不会出现的。

只重新生成INSTALL之后,可以看到170个项目都成功了。

 4.Visual Studio配置变量

        我们首先创建一个空的"控制台应用"项目,就叫OpenCVtest。

        然后先配置系统环境变量,Windows控制台搜索即可查询到。

 把之前install产出的bin的包的路径填进去。

然后重启电脑才会生效。

 

        

 这里还是使用Release版本 x64的编译环境,debug的类似。

然后右键项目,更改属性:

然后编辑VC++目录下的包含目录(其实就是英文版本的include path):

然后把install之后的include文件夹路径添加上去(注意,是install之后的include路径,不要填错成了其他的include路径) 

 然后我们编辑库目录(其实就是英文版的lib path)

把install之后的lin目录输入进去(再次强调是install之后的lib目录

 

 链接器->附加依赖项->编辑,输入所有的xxxxx/install\x64\vc16\lib中 所有xxxd.lib文件名字:

 这里建议使用windows命令行操作获取所有的XXX455.lib文件名(455是opencv版本名字,不同版本的opencv安装后,敲命令行使用不同的版本号哦)。

操作命令如下:

dir *.*  /B  | findstr 455.lib

复制进去:

然后我们开始测试。

 5.Case测试:

        为了验证我们安装OpenCV的效果,我们需要使用测试Case进行测试。

        这里先测试OpenCV的基本功能,再使用SIFT算子和SURF算子进行测试。 由于SIFT算子和SURF算子都是OpenCV contrib里面才有的图像库,这两个算子能测试通过,说明OpenCV contrib安装完成(更正:opencv4.4之后sift又回到opencv普通库了……崩溃)。

初始测试

在项目中输入下述代码:

// OpenCVTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat src = cv::imread("E:\\images\\00000.jpg");//图片路径
    if (src.empty())
    {
        std::cout << "pic is empty!\n";
        return -1;
    }
    cv::imshow("show", src);
    cv::waitKey(0);
    std::cout << "Hello World!\n";
}

运行结果:

好了,说明能展示了。 

SIFT算子测试

参考上述文章:

代码如下:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp> //OpenCV 4.2.0 及之后版本

int main()
{
	cv::Mat imageL = cv::imread("E:\\images\\3.jpg");
	cv::Mat imageR = cv::imread("E:\\images\\4.jpg");


	//提取特征点方法
	//SIFT
	//cv::Ptr<cv::xfeatures2d::SIFT> sift = cv::xfeatures2d::SIFT::create();
	cv::Ptr<cv::SIFT> sift = cv::SIFT::create(); //OpenCV 4.4.0 及之后版本
	//ORB
	//cv::Ptr<cv::ORB> orb = cv::ORB::create();
	//SURF
	//cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create();

	//特征点
	std::vector<cv::KeyPoint> keyPointL, keyPointR;
	//单独提取特征点
	sift->detect(imageL, keyPointL);
	sift->detect(imageR, keyPointR);

	//画特征点
	cv::Mat keyPointImageL;
	cv::Mat keyPointImageR;
	drawKeypoints(imageL, keyPointL, keyPointImageL, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); 
	drawKeypoints(imageR, keyPointR, keyPointImageR, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

	//显示窗口
	cv::namedWindow("KeyPoints of imageL");
	cv::namedWindow("KeyPoints of imageR");

	//显示特征点
	cv::imshow("KeyPoints of imageL", keyPointImageL);
	cv::imshow("KeyPoints of imageR", keyPointImageR);

	//特征点匹配
	cv::Mat despL, despR;
	//提取特征点并计算特征描述子
	sift->detectAndCompute(imageL, cv::Mat(), keyPointL, despL);
	sift->detectAndCompute(imageR, cv::Mat(), keyPointR, despR);

	//Struct for DMatch: query descriptor index, train descriptor index, train image index and distance between descriptors.
	//int queryIdx –>是测试图像的特征点描述符(descriptor)的下标,同时也是描述符对应特征点(keypoint)的下标。
	//int trainIdx –> 是样本图像的特征点描述符的下标,同样也是相应的特征点的下标。
	//int imgIdx –>当样本是多张图像的话有用。
	//float distance –>代表这一对匹配的特征点描述符(本质是向量)的欧氏距离,数值越小也就说明两个特征点越相像。
	std::vector<cv::DMatch> matches;

	//如果采用flannBased方法 那么 desp通过orb的到的类型不同需要先转换类型
	if (despL.type() != CV_32F || despR.type() != CV_32F)
	{
		despL.convertTo(despL, CV_32F);
		despR.convertTo(despR, CV_32F);
	}

	cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased");
	matcher->match(despL, despR, matches);

	//计算特征点距离的最大值 
	double maxDist = 0;
	for (int i = 0; i < despL.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist > maxDist)
			maxDist = dist;
	}

	//挑选好的匹配点
	std::vector< cv::DMatch > good_matches;
	for (int i = 0; i < despL.rows; i++)
	{
		if (matches[i].distance < 0.5 * maxDist)
		{
			good_matches.push_back(matches[i]);
		}
	}



	cv::Mat imageOutput;
	cv::drawMatches(imageL, keyPointL, imageR, keyPointR, good_matches, imageOutput);

	cv::namedWindow("picture of matching");
	cv::imshow("picture of matching", imageOutput);
	cv::waitKey(0);
	return 0;
}

原始图像如下: 

 运行结果:

SURF算子测试

代码如下,参考了:

【OpenCV】OpenCV 4 下 SIFT、SURF的使用_魏Gordon的博客-CSDN博客_opencv4 surf

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/imgproc.hpp"
#include <opencv2/imgproc/types_c.h>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int main()
{
	//【0】改变console字体颜色
	system("color 1F");


	//【1】载入原始图片
	Mat srcImage1 = imread("E:/images/3.jpg", 1);
	Mat srcImage2 = imread("E:/images/4.jpg", 1);
	Mat copysrcImage1 = srcImage1.clone();
	Mat copysrcImage2 = srcImage2.clone();

	if (!srcImage1.data || !srcImage2.data)
	{
		printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false;
	}

	//【2】使用SURF算子检测关键点
	int minHessian = 100;//SURF算法中的hessian阈值

	Ptr<SURF> detector = SURF::create(minHessian);//定义一个SurfFeatureDetector(SURF) 特征检测类对象  
	// Ptr<SURF> detector = cv::xfeatures2d::SURF::create(400);

	vector<KeyPoint> keypoints_object, keypoints_scene;//vector模板类,存放任意类型的动态数组

	//【3】调用detect函数检测出SURF特征关键点,保存在vector容器中
	detector->detect(srcImage1, keypoints_object);
	detector->detect(srcImage2, keypoints_scene);

	//【4】计算描述符(特征向量)
	Ptr<SURF> extractor = SURF::create();

	Mat descriptors_object, descriptors_scene;
	extractor->compute(srcImage1, keypoints_object, descriptors_object);
	extractor->compute(srcImage2, keypoints_scene, descriptors_scene);

	//【5】使用FLANN匹配算子进行匹配
	FlannBasedMatcher matcher;
	vector< DMatch > matches;
	matcher.match(descriptors_object, descriptors_scene, matches);
	double max_dist = 0; double min_dist = 100;//最小距离和最大距离

	//【6】计算出关键点之间距离的最大值和最小值
	for (int i = 0; i < descriptors_object.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist < min_dist) min_dist = dist;
		if (dist > max_dist) max_dist = dist;
	}

	printf(">Max dist 最大距离 : %f \n", max_dist);
	printf(">Min dist 最小距离 : %f \n", min_dist);

	//【7】存下匹配距离小于3*min_dist的点对
	std::vector< DMatch > good_matches;
	for (int i = 0; i < descriptors_object.rows; i++)
	{
		if (matches[i].distance < 3 * min_dist)
		{
			good_matches.push_back(matches[i]);
		}
	}

	//绘制出匹配到的关键点
	Mat img_matches;
	drawMatches(srcImage1, keypoints_object, srcImage2, keypoints_scene,
		good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
		vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

	//定义两个局部变量
	vector<Point2f> obj;
	vector<Point2f> scene;

	//从匹配成功的匹配对中获取关键点
	for (unsigned int i = 0; i < good_matches.size(); i++)
	{
		obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
		scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
	}
	vector<unsigned char> listpoints;

	//Mat H = findHomography( obj, scene, CV_RANSAC );//计算透视变换 
	Mat H = findHomography(obj, scene, RANSAC, 3, listpoints);//计算透视变换 


	std::vector< DMatch > goodgood_matches;
	for (int i = 0; i < listpoints.size(); i++)
	{
		if ((int)listpoints[i])
		{

			goodgood_matches.push_back(good_matches[i]);


			cout << (int)listpoints[i] << endl;
		}

	}
	cout << "listpoints大小:" << listpoints.size() << endl;
	cout << "goodgood_matches大小:" << goodgood_matches.size() << endl;
	cout << "good_matches大小:" << good_matches.size() << endl;
	Mat Homgimg_matches;
	drawMatches(copysrcImage1, keypoints_object, copysrcImage2, keypoints_scene,
		goodgood_matches, Homgimg_matches, Scalar::all(-1), Scalar::all(-1),
		vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

	imshow("去除误匹配点后;", Homgimg_matches);


	//从待测图片中获取角点
	vector<Point2f> obj_corners(4);
	obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(srcImage1.cols, 0);
	obj_corners[2] = cvPoint(srcImage1.cols, srcImage1.rows); obj_corners[3] = cvPoint(0, srcImage1.rows);
	vector<Point2f> scene_corners(4);

	//进行透视变换
	perspectiveTransform(obj_corners, scene_corners, H);

	//绘制出角点之间的直线
	line(img_matches, scene_corners[0] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[1] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
	line(img_matches, scene_corners[1] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[2] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
	line(img_matches, scene_corners[2] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[3] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
	line(img_matches, scene_corners[3] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[0] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);

	//显示最终结果
	imshow("效果图", img_matches);

	waitKey(0);
	return 0;
}

        测试结果如下。

 在OpenCV4.X版本中,SURF依然是OpenCV contrib中的代码。SURF代码测试成功,说明我们的安装已经成功了。

看到这里的都不容易,大家休息一下吧,下一步就可以考虑修改源码啦。

6.总结

        OpenCV的安装的确是一个非常复杂和麻烦的过程,即使我之前已经有了成功安装的经验,这一次安装(加写教程)还是花了我大约一天的时间。

        在安装过程中,主要注意以下几点:

1.cmake阶段注意查看Cmake的报错信息,及时检查CMakeDownLog.txt文件;

2.根据日志文件自行下载相应的依赖;

3.最后的测试case能够跑通才算完成整个安装流程。

7.参考链接:

VS2019+OpenCV4.1.0安装及整合详细步骤 - 简书

OpenCV3.3+contrib+VS2017+CMake+Win10_码代马的博客-CSDN博客

OpenCV+opencv_contrib+VS2015+CMake+Win10编译过程_TechGreat的博客-CSDN博客_cmake opencv_contrib

vs2022重新编译opencv-python cuda加速时报错_Harry Xu的博客-CSDN博客win10 +visual studio 2019 +opencv4.5.0+opencv_contrib4.5.0源码编译安装_语符律的博客-CSDN博客_win10安装opencv4.5

OpenCV3.4.0+Visual Studio2017配置 - 上中下,高平宽 - 博客园

opencv::sift特征提取 - osbreak - 博客园

【VS2017】【OpenCV4.0.0】调用SIFT出错_啊吼!的博客-CSDN博客

8.预告:关于修改源码

        安装OpenCV已经这么费劲了,不如继续改改源码?

        关于如何修改OpenCV的源码(以修改SURF算子为例),请参考下一篇文章:

OpenCV 修改源码:基于hpp文件,修改SURF算子(支持打断点、调试、debug)_树叶的叶and开心的开的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV安装教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib 的相关文章

  • EXCEL利用VBA自由控制图表绘图区大小

    用好VBA的话确实可以给你再办公室的工作效率带来质的提升 如果有人跟你说你可以用Python什么的语言处理Excel balabala的 xff0c 你可以无视他了 当然python可以处理很多事情 xff0c 但是EXCEL自带的作图工具
  • 提升CUDA程序运行效率的几个关键点

    目录 1 明确计算机中GPU卡片的计算资源 xff0c 决定变量的性质 xff08 constant xff0c share还是global xff09 以及Grid xff0c Block的维度 xff0c 充分并合理利用GPU显卡的资源
  • CUDA程序编写具体参数设置

    介绍了GPU的结构以及资源的控制要素 xff08 GPU硬件结构和程序具体参数设置 yu132563的专栏 CSDN博客 xff09 以及编程过程中的一些需要注意的问题 xff08 CUDA程序性能调优 yu132563的专栏 CSDN博客
  • CUDA Stream流并发性

    目录 1 CUDA 中的异步命令 2 默认流 3 Multistream多流示例 异构计算是指高效地使用系统中的所有处理器 xff0c 包括 CPU 和 GPU 为此 xff0c 应用程序必须在多个处理器上并发执行函数 CUDA 应用程序通
  • Madagascar环境下编程

    引用 原创 Madagascar环境下编程 2013 07 17 04 50 34 转载 标签 xff1a 教育 分类 xff1a madagascar 本文转载自seismig 原创 Madagascar环境下编程 Madagascar是
  • mySQL(关系型数据库管理系统)编辑

    收藏 2906 1034 mySQL xff08 关系型数据库管理系统 xff09 编辑 MySQL 1 是一个 关系型数据库管理系统 xff0c 由瑞典 MySQL AB公司开发 xff0c 目前属于 Oracle公司 MySQL是最流行
  • CPU的核心数、线程数的关系和区别

    我们在选购电脑的时候 xff0c CPU是一个需要考虑到核心因素 xff0c 因为它决定了电脑的性能等级 CPU从早期的单核 xff0c 发展到现在的双核 xff0c 多核 CPU除了核心数之外 xff0c 还有线程数之说 xff0c 下面
  • STM32单片机,下载器下载完程序能正常跑起来,断电再上电程序不运行

    晶振坏了 转载于 https www cnblogs com god of death p 7050281 html
  • CUDA性能优化----warp深度解析

    CUDA性能优化 warp深度解析 2017 01 12 16 41 07 分类 xff1a HPC amp CUDA优化 标签 xff1a gpu cuda hpc 举报 字号 订阅 下载LOFTER 我的照片书 1 引言 CUDA性能优
  • 螺旋桨转矩

    xfeff xfeff 在螺旋桨气动力分析时 xff0c 首先应用翼型理论进行螺旋桨叶素分析 利用翼型升阻特性数据 xff0c 回避了有限机翼的展弦比问题 xff0c 诱导流动由涡流模型确定 xff0c 取决于桨叶数目 间距以及作用于每片桨
  • 给初学者们讲解人工神经网络(ANN)

    1 介绍 这份教学包是针对那些对人工神经网络 xff08 ANN xff09 没有接触过 基本上完全不懂的一批人做的一个简短入门级的介绍 我们首先简要的引入网络模型 xff0c 然后才开始讲解ANN的相关术语 作为一个应用的案例 xff0c
  • OpenMP基本概念

    OpenMP是一种用于共享内存并行系统的多线程程序设计方案 xff0c 支持的编程语言包括C C 43 43 和Fortran OpenMP提供了对并行算法的高层抽象描述 xff0c 特别适合在多核CPU机器上的并行程序设计 编译器根据程序
  • 散度和旋度的物理意义是什么?

    高等数学学的时间有点久远了 xff0c 最近需要推倒一些公式 xff0c 以前高数学的时候这公式那定理的都没说什么物理意义 xff0c 现在接触的问题都是具有一定物理意义的 xff0c 感觉对不上 xff0c 回来找找资料好好理解一下 xf
  • 格林公式、高斯公式及斯托克斯公式的理解及相互关系

    最近要推倒波动方程积分解 xff0c 要对散度 旋度以及他们之间的相互关系有一个理解 看了两天 xff0c 自己认为理解的差不多了 xff0c 现在写在这个地方 xff0c 作为笔记 xff0c 以后忘记了拿过来看一下 xff0c 加深一下
  • Radon变换理论介绍

    本人最近在研究Radon变换 xff0c 在查阅了各种资料之后在此写下个人的理解 xff0c 希望与各位牛牛进行交流共同进步 xff0c 也使得理解更加深刻些 Radon变换的本质是将原来的函数做了一个空间转换 xff0c 即 xff0c
  • test

    lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 utf 8 34 gt lt meta http equiv 61 34 X U
  • BIT内存顺序

    机器的最小寻址单位是字节 xff0c bit无法寻址 xff0c 也就没有高低地址和起始地址的概念 xff0c 我们需要定义一下bit的 地址 以一个字节为例 xff0c 我们把从左到右的8个bit的位置 position 命名按顺序命名如
  • 无人驾驶感知篇之融合(五)

    今天早上看到上海新增一万七千左右 xff0c 看的真的很揪心 xff01 希望白衣战士能早点战胜这场疫情 xff0c 期待明天能有好消息 xff01 今天具体讲讲多贝叶斯估计算法的原理 xff0c 多贝叶斯估计法的主要思想是将传感器信息依据
  • MAC地址的介绍(单播、广播、组播、数据收发)

    MAC地址组成 网络设备的MAC地址是全球唯一的 MAC地址长度为48比特 xff0c 通常用十六进制表示 MAC地址包含两部分 xff1a 前24比特是组织唯一标识符 xff08 OUI xff0c OrganizationallyUni
  • stm32通用定时器输出PWM控制舵机

    stm32的通用定时器有TIM2 TIM3 TIM4 TIM5 xff0c 每个定时器都有独立的四个通道可以作为 xff1a 输入捕获 输出比较 PWM输出 单脉冲模式输出等 stm32除了基本定时器 xff0c 其他定时器都能输出PWM

随机推荐

  • Linux内核Socket CAN中文文档

    自己在年假中空闲之余翻译的内核中Socket CAN的文档 xff0c 原文地址在 xff1a http lxr linux no linux 43 v2 6 34 Documentation networking can txt 但是这篇
  • c/c++自定义通讯协议(TCP/UDP)

    前言 xff1a TCP与UDP是大家耳熟能详的两种传输层通信协议 xff0c 本质区别在于传输控制策略不相同 xff1a 使用TCP协议 xff0c 可以保证传输层数据包能够有序地被接受方接收到 xff0c 依赖其内部一系列复杂的机制 x
  • ubuntu 使用虚拟can 与 socketCAN使用

    原文链接 xff1a https blog csdn net xiandang8023 article details 127990159 创建虚拟CAN接口 在Linux上能使用虚拟CAN接口之前 xff0c 需要在终端执行以下三个步骤
  • cmake引入第三方库

    cmake引入第三方库 第三方库包含 lib文件和 h hpp文件动态库还包含 dll文件 小例程 3rdparty bin test dll include test hpp lib Debug test lib Release test
  • AHB-APB总线协议

    AHB APB总线协议 文章目录 AHB APB总线协议一 AHB APB总线介绍二 AHB总线设备1 AHB主设备 xff08 master xff09 2 AHB从设备 xff08 slave xff09 3 AHB仲裁器 xff08
  • Modelsim缺失库快速添加

    Modelsim缺失库快速添加 文章目录 Modelsim缺失库快速添加前言一 ini文件二 器件库配置1 将器件库放在modelsim文件夹下2 ini配置文件修改 前言 在单独使用modelsim时 xff0c 假如要编译复杂的工程文件
  • AHB-APB_Lite总线协议及Verilog实现

    AHB APB Lite总线协议及Verilog实现 文章目录 AHB APB Lite总线协议及Verilog实现一 AHB Lite协议介绍二 系统框架介绍三 代码设计四 仿真测试 一 AHB Lite协议介绍 AHB xff08 Ad
  • 通信协议详解(二):IIC总线协议(传输时序+数据格式+设计实现)

    文章目录 一 IIC xff08 Inter Integrated Circuit xff09 介绍二 传输协议1 时序传输时序写操作时序数据有效性开始 amp 结束信号从机应答信号 2 数据格式 三 设计实现1 时钟2 传输过程3 三态门
  • Qt error ------ 'XXX' has not been declared

    1 头文件没加 2 调用函数者的头文件在XXX头文件的下方 转载于 https www cnblogs com god of death p 8572306 html
  • Command Expert安装

    一 安装准备 需先下载两个安装包 1 Commmand Expert安装包 https www keysight com cn zh lib software detail computer software command expert
  • Vitis开发(一):Vivado启动vitis

    Vitis是Xilinx SDK的继承开发工具 xff0c 从Vivado 2019 2版本开始启用 在Vivado 2019 1及更早版本中 xff0c 导出的硬件描述文件为 hdf文件 xff0c 给xilinx sdk使用 在Viva
  • 数字IC刷题(一)

    一 选择 1 To achieve better leakage cells are placed A HVT B LVT C RVT 解 LVT Low V threshold xff1a 低阈值 这种库的漏电流较大 xff0c 但是延迟
  • CPU设计-分支预测

    目录 CPU分支指令类型分类 1 xff09 无条件跳转 xff0f 分支 xff08 Unconditional Jump Branch xff09 指令 无条件直接跳转 xff0f 分支 xff1a 无条件间接跳转 xff0f 分支 x
  • 数字世界的积木-从MOS管搭反相器,与非门,锁存器,触发器

    文章目录 一 MOS管MOS管搭建反相器MOS管搭建传输门MOS管搭建与非门 二 与非门R S锁存器三 电平触发器电平触发RS锁存器带异步复位 xff0c 异步置位的电平触发RS锁存器电平触发D触发器 四 边沿触发器 一 MOS管 NMOS
  • 内存对齐规则

    每个特定平台上的编译器都有自己的默认 对齐系数 也叫对齐模数 程序员可以通过预编译命令 pragma pack n xff0c n 61 1 2 4 8 16来改变这一系数 xff0c 其中的n就是你要指定的 对齐系数 规则 xff1a 1
  • EGO-Planner: An ESDF-free Gradient-based Local Planner for Quadrotors(论文笔记)

    EGO Planner An ESDF free Gradient based Local Planner for Quadrotors xff08 论文笔记 xff09 ESDF欧式符号距离场避碰力估算基于梯度的轨迹优化平滑惩罚障碍惩罚可
  • 计算机组成原理系列(三):计算机存储器结构体系详解

    x1f525 Hi xff0c 我是小余 本文已收录到 GitHub Androider Planet 中 这里有 Android 进阶成长知识体系 xff0c 关注公众号 小余的自习室 xff0c 在成功的路上不迷路 xff01 前言 生
  • linux下怎么使用C语言编写接收和发送udp组播数据?

    一 xff0c 发送端 代码如下 xff1a 先调用initUdpMultiCastSender初始化 xff0c int initUdpMultiCastSender uint32 t localip uint16 t localport
  • MQTT 及其 测试工具

    协议说明书 xff1a https mcxiaoke gitbooks io mqtt cn content mqtt 04 OperationalBehavior html 官网提供了很多的broker模拟器 xff0c 地址 xff1a
  • OpenCV安装教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

    目录 0 写作背景 1 安装visual studio 2 下载OpenCV相关的源码 下载OpenCV原始的源码 下载OpenCV contrib的源码 下载安装cmake 3 cmake编译OpenCV 初始编译 CmakeDownlo