OpenCV—轮廓操作一站式详解:查找/筛选/绘制/形状描述与重心标注(C++版)

2023-05-16

OpenCV—轮廓操作一站式详解:查找/筛选/绘制/形状描述与重心标注(C++版)

轮廓是定义或限定形状或对象的边或线,是机器视觉中的常用的概念,多用于目标检测、识别等任务。关于OpenCV轮廓操作,尤其是级别及如何使用轮廓级别进行筛选等问题,相关文章比较少,正好最近用到,因此将其总结成文。本文主要介绍OpenCV的查找轮廓函数findContours()绘制函数drawContours(),及其轮廓级别参数hierarchy,涉及到预处理、轮廓筛选等内容,并提供全部源代码,希望能帮助大家理解基本概念并能借鉴示例代码编写自己的算法。

本文代码:C++

本文包括如下内容:

  • 基本概念

1.查找和绘制轮廓函数findContous(),drawContours()

2.轮廓参数:轮廓级别、轮廓长度

3.轮廓的形状描述子:最小覆盖矩形、圆、多边形逼近、凸包

  • 编程实战

1.如何筛选轮廓:按轮廓级别和长度筛选

2.如何绘制轮廓的外接形状

3.如何获取轮廓的重心坐标并标注

本文的目标:

1.从原始图像中找到2架可回收火箭

2.标注目标的位置与重心坐标

阅读完成后,将能从原始图像中找到2架火箭,并标注其位置与坐标。如下图所示:

目录

OpenCV轮廓操作一站式详解:查找/筛选/绘制/形状描述与标注

1.查找、绘制轮廓函数

findContours()

drawContours()

2.预处理

3.查找轮廓

4.绘制轮廓

5.筛选轮廓

5.1 hierarchy轮廓级别详解

contours与hierarchy的关系

什么是层次结构hierarchy?

5.2 OpenCV中的层次结构表示

Next

Previous

First_Child

Parent

5.3 按hierarchy筛选轮廓

5.4 按长度筛选轮廓

6.联通域分析

7.标注轮廓重心


1.查找、绘制轮廓函数


findContours()

void cv::findContours     (
        InputOutputArray         image,
        OutputArrayOfArrays   contours,
        OutputArray                 hierarchy,
        int                                 mode,
        int                                 method,
        Point                             offset = Point()
    )   

函数参数:

image

输入:源图像,一个8位单通道图像,注意一定是CV_8UC1的单通道图像,否则报错。 非零像素被视为1。 零像素保持为0,因此图像被视为二进制。可以使用compare,inRange,threshold,adaptiveThreshold,Canny等来从灰度或彩色图像中创建二进制图像。如果mode为RETR_CCOMP或RETR_FLOODFILL,则输入也可以是标签的32位整数图像(CV_32SC1)。

contours

输出:检测到的轮廓。每个轮廓都存储为点向量(例如std :: vector <std :: vector <cv :: Point >>)。即由若干个cv::Point类型的点组成了单个轮廓std :: vector <cv :: Point >,再由若干个轮廓组成输入图像中的全部轮廓std::vector<std :: vector <cv :: Point >>

hierarchy

输出:轮廓级别信息。Hierarchy为可选输出变量,是std::vector<cv::Vec4i>类型的向量(每个元素都是一个4个int值构成的向量)。包含有关图像拓扑的信息。它具有与轮廓数量一样多的元素。例如,第i个轮廓, hierarchy[i][0],hierarchy[i][1],hierarchy[i][2]和hierarchy[i][3]依次为:第i个轮廓的[Next, Previous, First_Child, Parent],即轮廓i相同等级的下一轮廓、前一轮廓,第一个子轮廓和父轮廓(上一级轮廓)的索引号(即contours向量中的轮廓序号)。如果轮廓i没有下一个,前一个,父级或嵌套轮廓,则层次结构[i]的相应元素将为负数。这个参数我们将在下文中重点介绍。
mode输入:轮廓检索模式, 详见 RetrievalModes
method输入:轮廓近似法, 详见ContourApproximationModes
offset输入:每个轮廓点移动的偏移量,可选参数,cv::Point()类型。如果从整幅图像的某个ROI中提取轮廓,然后又在整个图像中分析轮廓(将ROI中的轮廓坐标恢复到整幅图像中的坐标),这个偏移量非常有用,可以免去我们自己写代码转换坐标系的麻烦。

mode参数:

RETR_EXTERNAL 

Python: cv.RETR_EXTERNAL

仅检索极端外轮廓。 它为所有轮廓设置hierarchy [i][2] = hierarchy [i][3] = - 1。

RETR_LIST 

Python: cv.RETR_LIST

检索所有轮廓而不建立任何层次关系。

RETR_CCOMP 

Python: cv.RETR_CCOMP

检索所有轮廓并将它们组织成两级层次结构。在顶层轮廓是外部轮廓。在第二层轮廓是“洞”的轮廓。如果连接组件的洞内有另一个轮廓,它的级别仍然认定为顶层。

RETR_TREE 

Python: cv.RETR_TREE

检索所有轮廓并重建嵌套轮廓的完整层次结构。

RETR_FLOODFILL 

Python: cv.RETR_FLOODFILL

 

drawContours()

绘制轮廓轮廓或填充轮廓。

void cv::drawContours     (
        InputOutputArray       image,
        InputArrayOfArrays    contours,
        int                               contourIdx,
        const Scalar &            color,
        int                               thickness = 1,
        int                               lineType = LINE_8,
        InputArray                  hierarchy = noArray(),
        int                               maxLevel = INT_MAX,
        Point                           offset = Point()
    )       

函数参数:

image

输入:源图像。单通道或3通道图像。

contours

输入:待绘制的轮廓。std :: vector <std :: vector <cv :: Point >>类型。
contourIdx输入:待绘制的轮廓序号。例如:0为绘制第1个轮廓contours[0];1为绘制第2个轮廓contours[1],依次类推;-1为绘制所有轮廓。
color输入:轮廓颜色。cv::Scalar变量,例如:cv::Scalar(0,0,255)为红色轮廓,cv::Scalar::all(0)为黑色轮廓
thickness输入:轮廓粗细。int型变量,默认为1,值越大越粗
lineType输入:绘制轮廓的线型。默认LINE_8,8联通线型(下一个点连接上一个点的边或角)

hierarchy

输入:待绘制的轮廓级别。std::vector<cv::Vec4i>类型的向量(每个元素都是一个4个int值构成的向量)。下一轮廓、前一轮廓,第一个子轮廓和父轮廓(上一级轮廓)的索引号。
maxLevel输入:待绘制的轮廓最大级别。
method输入:轮廓近似法, 详见ContourApproximationModes
offset输入:每个轮廓点移动的偏移量,可选参数。

2.预处理


预处理目的是为轮廓查找提供高质量的输入源图像。

预处理的主要步骤包括:

  • 灰度化:使用cv::cvtColor()
  • 图像去噪:使用高斯滤波cv::Gaussian()
  • 二值化:使用cv::Threshold()
  • 形态学处理:cv::morphologyEx()

其中灰度化可以将3通道图像转化为单通道图像,以便进行二值化门限分割;去噪可以有效剔除图像中的异常独立噪点;二值化是为轮廓查找函数提供单通道图像;形态学的某些处理通常可以剔除细小轮廓,联通断裂的轮廓。

读取图像代码如下:

// 1.载入图像
	cv::Mat image = cv::imread("spaceX2.jpg",1);
	cv::imshow("original", image);
	cv::waitKey();
// 2.预处理
	cv::Mat gray, binary, element; // 临时变量
	cv::cvtColor(image, gray, CV_BGR2GRAY);
	cv::imshow("gray", gray);

	GaussianBlur(gray, gray, Size(3, 3), 1);
	cv::threshold(gray, binary, 80, 255, CV_THRESH_BINARY_INV);
	cv::imshow("binary", binary);
	
	element = getStructuringElement(MORPH_RECT, Size(3, 3));//3*3全1结构元素
	cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, element);
	cv::imshow("morphology", binary);
	cv::waitKey();

 


使用findContours函数查找轮廓

// 3.查找轮廓
	std::vector<std::vector<cv::Point>> contours;
	std::vector<cv::Vec4i> hierarchy;
	cv::findContours(
		binary,               // 输入二值图
		contours,             // 存储轮廓的向量
		hierarchy,            // 轮廓层次信息
		RETR_TREE,            // 检索所有轮廓并重建嵌套轮廓的完整层次结构
		CHAIN_APPROX_NONE);   // 每个轮廓的全部像素
	printf("find %d contours", contours.size());

4.绘制轮廓


为了方便查看轮廓查找结果,使用drawContours()来绘制轮廓并显示。编写函数drawMyContours()函数用于在白色背景中或者原图上查看轮廓。

函数参数:

  • 窗口名字;
  • 原始图像以及轮廓变量
  • 白色背景上还是在原图上绘制轮廓的标志位
// 4. 绘制轮廓函数
void drawMyContours(string winName, Mat &image, std::vector<std::vector<cv::Point>> contours, bool draw_on_blank)
{
	cv::Mat temp;
	if (draw_on_blank) // 在白底上绘制轮廓
	{
		temp = cv::Mat(image.size(), CV_8U, cv::Scalar(255));
		cv::drawContours(
			temp,
			contours,
			-1,//画全部轮廓
			0, //用黑色画
			2);//宽度为2
	}		
	else // 在原图上绘制轮廓
	{
		temp = image.clone();
		cv::drawContours(
			temp,
			contours,
			-1,//画全部轮廓
			cv::Scalar(0,0,255), //用red画
			1);//宽度为2
	}
	cv::imshow(winName, temp);
	cv::waitKey();
}

main函数中调用drawMyContours()如下:

// 4.绘制原始轮廓
	drawMyContours("contours", image, contours, true);

首次查找的轮廓变量contours中有16个向量,即找到16个轮廓。

展开contours变量,可以看到每个元素都是一个由一系列轮廓上的点组成的向量,其size就是每个轮廓的长度。

通过绘制轮廓,可以看到这16个轮廓,除了两个目标之外,还有云、地面背景以其中的“洞”轮廓。

5.筛选轮廓


查找到大轮廓显然有许多不符合要求,因此可以通过某些准则进行轮廓筛选。通过观察,发现上图中有许多轮廓包含“洞”,即子轮廓,而这些子轮廓显然也有父级轮廓,因此我们可以使用findContours的hierarchy轮廓级别参数删除那些有子轮廓也有父轮廓的轮廓

5.1 hierarchy轮廓级别详解

contourshierarchy的关系

使用findContours()函数将返回contours轮廓向量以及对应的hierarchy轮廓级别向量(可选项)。两者有相同的长度即contours.size() = hierarchy.size(),并且向量的序号表示找到的轮廓索引,且一一对应。

什么是层次结构hierarchy

通常我们使用findContours()函数来检测图像中的对象。有时对象位于不同的位置。但在某些情况下,某些形状在其他形状内(类似嵌套)。在这种情况下,我们将外部轮廓称为父级轮廓,将内部轮廓称为子轮廓。这样,图像中的轮廓彼此之间存在某种关系。并且我们可以指定一个轮廓如何相互连接,例如,它是某个其他轮廓的子项,还是父项等。此关系的表示就称为层次结构hierarchy。

考虑下面的示例图片:

在上图中,有一些形状,我们从0-5编号这5个形状。图中2和2a表示最外侧矩形的外部和内部轮廓。

轮廓0,1,2是最外部轮廓,三者为同一级别。我们可以说,它们在层次结构0中,或者只是它们处于相同的层次结构级别。

接下来是轮廓-2a可以被认为是轮廓-2的子轮廓(或者相反,轮廓-2是轮廓-2a的父级轮廓)所以让它在层次结构-1中。 类似地,轮廓-3是轮廓-2a的子轮廓,它进入下一层次。 最后,轮廓4,5是轮廓-3a的子轮廓,它们位于最后的层次结构级别。 从编号框的方式,可以说轮廓-4是轮廓-3a的第一个子轮廓,当然轮廓-5也是轮廓-3a的子轮廓。

如果上面的描述看着头晕,不要紧,一开始都这样。

5.2 OpenCV中的层次结构表示

OpenCV中每个轮廓都有自己的信息,关于它是什么层次结构,谁是它的子轮廓,谁是它的父轮廓等.OpenCV将它表示为四个int值的数组,类型为cv::Vec4i(4个int值):

[Next,Previous,First_Child,Parent]

Next

Next表示同一级别的下一个轮廓索引。例如,在我们的图片中取出轮廓-0。同一水平的下一个轮廓是轮廓-1。 所以简单地说Next = 1。类似地,对于轮廓-1,next是轮廓-2。 所以Next = 2。

轮廓-2的同一级别没有下一个轮廓,所以轮廓-2的Next = -1。轮廓-4呢?它与轮廓-5处于同一水平。所以它的下一个轮廓是轮廓-5,所以轮廓-4的Next = 5。

Previous

Previous表示同一级别的上一个轮廓索引。例如,轮廓-1的上一个轮廓在同一级别中为轮廓-0。 类似地,对于轮廓-2,它的上一个轮廓是轮廓-1。而对于轮廓-0,没有先前的,所以把它的Previous = -1。

First_Child

First_Child表示当前轮廓的第一个子轮廓索引。例如,对于轮廓-2,子轮廓是轮廓-2a。因此轮廓-2的First_Child为轮廓-2a的相应索引值。轮廓-3a呢?它有两个子轮廓。但hierarchy参数只记录第一个子轮廓,因此它是轮廓-4的索引值。因此,对于轮廓-3a,First_Child = 4。

Parent

Parent表示当前轮廓的父轮廓索引。对于轮廓-4和轮廓-5,它们的父轮廓都是轮廓-3a。对于轮廓-3a,它的父轮廓是轮廓-3,依此类推。

注意:

  • Previous表示同一层级的前一个轮廓的索引;
  • Parent表示其父轮廓的索引;
  • 如果某个轮廓没有子轮廓项或父轮廓,则对应的字段=-1.

5.3hierarchy筛选轮廓

有了上述对轮廓层级的理解,下面就可以根据需要筛选轮廓了。例如本文任务是找到两个火箭,而首次查找轮廓有许多中间有空洞的轮廓不符合要求,下面就通过遍历每一个轮廓的hierarchy级别参数的第3第4个参数来找到那些有子轮廓或者有父轮廓的轮廓,并删除之。注意向量迭代器的使用,删除后会返回下一个向量的指针;此外,contours与hierarchy元素需要同步删除和并递增迭代器,以保持编号对应关系,否则会删错。

// 5.筛选轮廓
	// 初始化迭代器
	std::vector<std::vector<cv::Point>>::iterator itc = contours.begin();
	std::vector<cv::Vec4i>::iterator itc_hierarchy = hierarchy.begin();
	
	// 5.1使用层级结构筛选轮廓
	int i = 0;
	while(itc_hierarchy != hierarchy.end())
	{
		//验证轮廓大小
		if (hierarchy[i][2] > 0 || hierarchy[i][3] > 0) // 存在子轮廓/父轮廓
		{
			itc = contours.erase(itc);
			itc_hierarchy = hierarchy.erase(itc_hierarchy);
		}
		else
		{
			++i;
			++itc;
			++itc_hierarchy;
		}
	}
	printf("%d contours remaining after hierarchy filtering", contours.size());
	// 绘制级别筛选后的轮廓
	drawMyContours("contours after hierarchy filtering", image, contours, true);

筛选过后的轮廓如下图所示,左上角和右下角的云层与地面的带有空洞的轮廓都被删除了。

5.4 按长度筛选轮廓

尽管上一个步骤已经剔除了天空与地面背景轮廓,但仍然残留这一些细小的轮廓。下一步可以使用轮廓长度contours[i].size()来滤除过小或过大的轮廓:

// 5.2使用轮廓长度滤波
	int min_size = 20;
	int max_size = 500;

	// 针对所有轮廓
	itc = contours.begin();
	itc_hierarchy = hierarchy.begin();
	while (itc != contours.end()) 
	{
		//验证轮廓大小
		if (itc->size() < min_size || itc->size() > max_size)
		{
			itc = contours.erase(itc);
			itc_hierarchy = hierarchy.erase(itc_hierarchy);
		}			
		else
		{
			++itc;
			++itc_hierarchy;
		}			
	}
	printf("%d contours remaining after length filtering", contours.size());
	// 绘制长度筛选后的轮廓
	drawMyContours("contours after length filtering", image, contours, true);

感觉越来越接近真理了!

6.联通域分析


连通区域通常代表了场景中的某个物体。为了识别该物体,或将它与其他图像元素比较,需要对此区域进行测量,以提取部分特征。本节介绍opencv的形状描述子,用于描述连通区域的形状。OpenCV中用于形状描述的函数有很多。我们把其中几个用到上节提取到的区域。

(1)矩形框cv::Rect r0 = cv::boundingRect()

在表示和定位图像中的区域方法中,边界框可能是最简洁的。它的定义是:能完整包含该形状的最小垂直矩形。比较边界框的高度和宽度,可以获得物体在垂直和水平方向上的范围。

(2)最小覆盖圆cv::minEnclosingCircle()

最小覆盖圆通常用在只需要区域尺寸和位置的近似值的情况。

(3)多边形逼近cv::approxPolyDP()

如果要更紧凑地表示区域的形状,可以采用多边形逼近。在创建时需要设置精度参数,表示形状与对应的简化多边形之间能接受的最大距离。它是cv::approxPolyDP(contours[1],poly,5,true)函数的第四个参数。返回结果是cv::Point类型的向量,表示多边形顶点个数。在画这个多边形时,要迭代遍历整个向量,并在顶点之间画直线,把它们逐个连接起来。

(4)凸包cv::convexHull()

凸包是包含该形状的最小凸多边形。可以把它看作一条绕在区域周围的橡皮筋。在形状轮廓中凹进去的位置,凸包轮廓会与原始轮廓发生偏离。

下面使用上述分析方法中的凸包与最小覆盖矩形两种方法分别对2架火箭的提取轮廓进行分析。

// 6.形状描述子
	// 最小覆盖矩形
	cv::Mat result =image.clone();
	cv::Rect rect = cv::boundingRect(contours[0]);//轮廓1			
	cv::rectangle(result, rect, cv::Scalar(0,255,255), 1);//画矩形
	// 凸包
	std::vector<cv::Point> hull;
	cv::convexHull(contours[1], hull);//轮廓2
	cv::polylines(result, hull, true, cv::Scalar(0, 255, 0), 1);//画多边形
	cv::imshow("bounding", result);
	cv::waitKey();

得到的结果如下图所示:轮廓1为最小覆盖矩形(黄色线条),轮廓2为凸包(绿色线条)

7.标注轮廓重心

终于到最后一步了。下面先求2个轮廓的重心,然后使用cv::Circle()与cv::putText()函数将重心位置与坐标标注到画面上。

// 7.计算轮廓矩,画重心
	itc = contours.begin();
	while (itc != contours.end()) {
		// 计算全部轮廓矩
		cv::Moments mom = cv::moments(cv::Mat(*itc++));
		// 画重心
		cv::Point pt = cv::Point(mom.m10 / mom.m00, mom.m01 / mom.m00);	//使用前三个矩m00, m01和m10计算重心	
		cv::circle(result, pt, 2, cv::Scalar(0, 0, 255), 2);//画红点
                // 标注重心坐标值
		string text_x = std::to_string(pt.x);
		string text_y = std::to_string(pt.y);
		string text = "(" + text_x + ", " + text_y + ")";
		cv::putText(result, text, cv::Point(pt.x+10,pt.y+10), cv::FONT_HERSHEY_PLAIN, 1.5, cv::Scalar::all(255), 1, 8, 0);
	}
	cv::imshow("center", result);
	cv::waitKey();

最终结果如下图所示。

参考链接:

https://docs.opencv.org/3.1.0/d9/d8b/tutorial_py_contours_hierarchy.html

https://docs.opencv.org/3.4.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a

本文更新链接:https://blog.csdn.net/iracer/article/details/90260670

转载请注明出处。


新书终于面市啦,《机器学习原理与编程实战》连接原理与实战:

https://blog.csdn.net/iracer/article/details/116051674?spm=1001.2014.3001.5501

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

OpenCV—轮廓操作一站式详解:查找/筛选/绘制/形状描述与重心标注(C++版) 的相关文章

  • C++学习推荐书目

    语言入门 有丰富C经验 缺乏C 43 43 经验的 C 43 43 Primer 3RD 有其他语言的丰富经验的 The C 43 43 Programming Language 简称TCPL 对不住纯C的fans了 如果选择薄一点的书 x
  • 2011年个人总结

    2011 年个人总结 花絮 xff1a 我们习惯总结过去的一年 xff0c 但每年都是一样的 xff0c 我们拼命的工作 xff0c 为了生活 xff0c 一成不变 xff0c 却又常常迷茫 而写写总结 xff0c 是为了以后更好的生活 x
  • VNC连接失败:The connection was refused by the host computer

    解决方法 xff1a 1 用Xshell登陆自己的服务器 2 在命令行中输入vncserver 命令行中出现 xff1a Warning optimal6 2 is taken because of tmp X2 lock Remove t
  • 业务层 、服务层、数据层、表现层

    一般说来 xff0c 业务逻辑层中的模块包含了系统所需要的所有功能上的算法和计算过程 xff0c 并与数据访问层和表现层交互 抽象的说 xff0c 业务逻辑层就是处理与业务相关的部分 xff0c 一般来说 xff0c 业务层包含一系列的执行
  • 计算机视觉:传统图像处理方法

    1 图像分割 经典的数字图像分割算法一般是基于灰度值的两个基本特征之一 xff1a 不连续性和相似性 xff08 1 xff09 基于阈值 xff1a 基于图像的灰度特征来计算一个或多个灰度阈值 xff0c 并将图像中每个像素的灰度值与阈值
  • 基于UGUI实现类似Excel表格功能

    曾经有一个类似这种需求 xff0c 想在Unity中实现类似Excel表中的一个功能 xff0c 能在Scene窗口中 新增行 可视化配置 所见所得 单元格合并 等功能 经过我对UGUI的一些深层次了解以及结合Editor编辑器窗口开发 x
  • 电子货架标签应用浅析(ESL)

    关注与分享 xff0c 是对原创最大的鼓励 年底了 xff0c 会断续介绍几个主要的BLE的应用及市场情况 xff0c 这篇文章介绍的是电子货架标签 xff0c ESL Electronic Shelf Label 文章将从应用简介 xff
  • 最详细UWB技术及特点介绍

    关注与分享 xff0c 是对原创最大的鼓励 这篇文章偏技术 xff0c 信息偏深 xff0c 建议大家可以先跳到感兴趣的章节阅读 xff1b 01 UWB简介 UWB是Ultra Wide Band缩写 xff0c 来源于很久之前的脉冲通信
  • 浅聊Matter协议 (原CHIP协议)

    聚焦 xff1a 芯产品 xff0c 芯市场 xff0c 芯资讯 因为Matter协议目前还没有发布 xff0c 标准只针对部分协会成员开放 xff1b 很多朋友可能听过这个名字 xff0c 然后知道是一个 上层 协议 xff0c 更多内容
  • 2021 MCU WiFi竞争新格局,国产MCU WiFi芯片盘点,附录2020/2021 MCU WiFi排行

    关注智联网事 iotthings xff1a 芯产品 xff0c 芯市场 xff0c 芯资讯 缺货 xff0c 是半导体产业2021年最主要的基调 xff0c 有公司拿不到产能 xff0c 有公司新芯片流片周期大幅拉长 xff1b 新冠病情
  • 芯科(Silabs) Matter 全栈解决方案,附录高质量Matter培训资

    关注智联网事 xff1a 芯产品 xff0c 芯市场 xff0c 芯资讯 对芯科的最初印象 xff0c 最早应该是2014 5年左右 xff0c 当时SI44xx系列渗透了很多市场的客户 xff0c 记得一个是低功耗的特性 xff0c 一个
  • WAF技术选型介绍

    WAF目前是企业必不可少的安全设备 xff0c 目前常见的开源技术选型包括 xff1a jxwafopenstarngx lua wafApache APISIXmodsecurity 介绍参考 xff1a https zhuanlan z
  • int 占多少字节

    char 1 int 4 long 8 float 4 double 8 xff08 1 xff09 使用VC xff0c int类型占4个字节 xff08 2 xff09 使用Turbo C xff0c int类型占2个字节 16位编译器
  • 海外LPWAN的王者是我,一文看懂Wi-Sun协议

    聚焦 xff1a 芯产品 xff0c 芯市场 xff0c 芯技术 注 xff1a 欢迎加入文章底部的 lt 物联坊间 gt 微信 刚刚毕业的我 xff0c 有参与城市照明系统的建设 xff0c 包括城市公交系统 xff0c 那个时候困扰我的
  • 22家国产汽车MCU公司及型号盘点

    专注芯片 xff0c 应用系统 xff0c 行销技能的公众号 如果有一家芯片MCU或模拟公司和你说 xff0c 他不做汽车方向芯片 xff0c 你可以内心欣喜的 xff0c 严肃的问一句 xff0c 为什么 xff1b 做汽车芯片 xff0
  • 2022 MCU公司交卷,总营收84.8亿人民币,排名第一和最后的分别是

    2022财报季结束 xff0c 我们看下上市MCU公司的最新排名 xff0c 毛利 xff0c 库存及库存周转率情况 xff1b 根据 Omdia 的数据 xff0c 2022 年中国 MCU 市场规模约为 82 亿美元 xff0c 小二统
  • 深度:旋转变压器原理,芯片,算法,选型

    之前介绍的新能源汽车电机控制器 MCU 和电动助力转向 EPS 文章中 xff0c 有提到电机的角度反馈可选择转旋转变压器方案 xff0c 今天做个分享 xff0c 欢迎留言交流 本文目录 xff1a 旋转变压器应用及参数概览 旋转变压器原
  • 实时微控制器的关键技术及国产玩家,国产DSP盘点

    小二用芯在写 xff0c 如果您觉得有帮助 xff0c 帮忙朋友圈推荐下 34 xff0c 感谢 xff01 在介绍OBC xff0c DCDC时候 xff0c 觉得有必要对主控芯片做个介绍 xff0c 比如为什么说数字电源的控制一般集成H
  • 天猫精灵的开发者生态

    文章转自 智联网事 欢迎关注 xff0c 每周一篇原创 xff0c 直至 No End https mp weixin qq com s biz 61 MzI3NDE2NDMwNQ 61 61 amp mid 61 2649905740 a
  • 蓝牙Mesh网络性能及网络特点总结(一)

    原文链接 xff1a 欢迎关注公众号 智联网事 xff0c 一周一篇原创文章 xff0c 一起探讨智联网 https mp weixin qq com s biz 61 MzI3NDE2NDMwNQ 61 61 amp mid 61 264

随机推荐

  • 华为物联网(IOT)开发者平台

    智联网事 关注与分享 xff0c 是对原创最大的鼓励 原文链接 https mp weixin qq com s biz 61 MzI3NDE2NDMwNQ 61 61 amp mid 61 2649905835 amp idx 61 1
  • Kubernetes v1.21.14二进制搭建单节点集群

    1 集群环境准备 1 1 主机规划 IP主机名主机角色操作系统安装组件192 168 11 71k8s master1master workerCentos7 9api server controller manager scheduler
  • shell脚本第一行:#!/bin/bash的含义

    相信有接触过shell脚本的同学们都应该知道 xff0c shell脚本的第一行一般会写有以下字样 xff1a bin bash或者 bin sh或者 bin awk 比较常见的说法是 xff1a 第一行的内容指定了shell脚本解释器的路
  • LPMS-IMU姿态解算

    参考文章 xff1a AHRS姿态解算说明 加速度 43 陀螺仪 43 磁力计原理及原始数据分析 AHRS俗称航姿参考系统 xff0c AHRS由加速度计 xff0c 磁场计 xff0c 陀螺仪构成 xff0c AHRS的真正参考来自于地球
  • 如何在我的VsCode中集成Git

    在VsCode中配置Git后 xff0c 我们就可以简单快速管理我们的代码仓库 一 下载安装Git 如果没有Git xff0c 这里可以参考我之前的文章安装 配置Git 精讲Git xff08 从安装到熟练使用一文全解 xff0c 看完轻松
  • 虚拟机:xshell连接虚拟机Ubuntu失败解决方法

    当我们买不起服务器但却想模拟服务器环境进行学习时 xff0c 再好不过的就是直接装Linux虚拟机了 xff0c 非常简单快捷 xff01 首先我们可以通过ifconfig a来查看Ubuntu Server的IP地址 xff08 前提是你
  • SVM原理:超平面方程

    xff08 1 xff09 超平面方程 3维空间中平面方程的一般形式 xff1a 1 我们都知道为平面到原点的距离 这里简单证明超平面的法向量为 d维空间平面方程的一般形式 xff1a 2 平面的法向量为 xff0c xff08 分号表示列
  • windows11编译OpenCV4.5.0 with CUDA(附注意事项)

    windows11编译OpenCV4 5 0 with CUDA 从OpenCV4 2 0 版本开始允许使用 Nvidia GPU 来加速推理 本文介绍最近使用windows11系统编译带CUDA的OpenCV4 5 0的过程 文中使用 特
  • Windows11安装Detectron2(附详细操作指南)

    Windows11安装Detectron2 0 简介 Detectron2 是 Facebook AI Research 的下一代目标检测库 xff0c 可提供最先进的检测和分割算法 它是 Detectron 和 maskrcnn benc
  • 四轴飞行器F450+Futaba 14SG+好盈电调油门行程校准

    F450 43 Futaba 14SG油门行程校准 装机前忘了进行油门校准 xff0c 装好后进行校准一开始老出现电机接收不到油门信号的提示音 因为Futaba 14SG也是新入手的控 xff0c 有些模式和操作不熟悉 xff0c 为此花了
  • NTKO控件安装:“不能装载文档控件,请在检查浏览器的选项中检查浏览器的安全设置”问题

    上礼拜手欠把OFFICE文档控件 NTKO给卸载了 xff0c 结果这周通知基金结题网上填写报告 本以为就装个控件 xff0c 没想到各种问题 xff0c 几经尝试终于解决 xff0c 总结如下 xff1a 1 问题 xff1a 不能装载文
  • Arduino - 串口操作函数与示例代码大全

    Arduino 串口操作函数与示例代码大全 本文总结了Arduino常用串口操作函数 xff0c 函数说明部分来源于Arduino 官网串口使用指南 xff0c 示例与实验部分为自编 本文是对Arduino串口操作函数的较全面总结 xff0
  • vs2010 出错:error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    LNK1123 转换到 COFF期间失败 文件无效或损坏 的解决方法 一 错误描述 之前写的程序隔段时间使用VS2010再次运行时出现如下错误 xff1a LINK fatal error LNK1123 转换到 COFF 期间失败 文件无
  • OpenCV—基本矩阵操作与示例

    OpenCV的基本矩阵操作与示例 OpenCV中的矩阵操作非常重要 xff0c 本文总结了矩阵的创建 初始化以及基本矩阵操作 xff0c 给出了示例代码 xff0c 主要内容包括 xff1a 创建与初始化 矩阵加减法 矩阵乘法 矩阵转置 矩
  • ubuntu16.04下利用ROS启动LPMS-CURS、CURS2等型号IMU;用imu控制turtlesim--教程

    文章目录 IMU型号及协议第一步 下载安装 LPsensor library第二步 设置ROS和carkin工作空间第三步 下载编译LPMS IMU的ROS驱动第四步 启动IMU xff08 可能也会遇到问题 xff09 遇到的问题1 ub
  • PixHawk飞控和Mission Planner地面站安装调试

    PixHawk飞控和Mission Planner地面站安装调试 PixHawk是著名飞控厂商3DR推出的新一代独立 开源 高效的飞行控制器 xff0c 前身为APM飞控 xff0c 不仅提供了丰富的外设模块和可靠的飞行体验 xff0c 有
  • 飞越650四轴无人机安装全程详解(多图)

    飞越650四轴无人机安装全程详解 xff08 多图 xff09 本文根据自己的安装实际过程 xff0c 总结了开箱后一个比较合理的650四轴无人机安装顺序 xff0c 以及各个步骤的注意事项 xff0c 主要内容包括 xff1a 系统基本配
  • DIY一个基于树莓派和Python的无人机视觉跟踪系统

    DIY 一个基于树莓派和Python的无人机视觉跟踪系统 无人机通过图传将航拍到的图像存储并实时传送回地面站几乎已经是标配 如果想来点高级的 在无人机上直接处理拍摄的图像并实现自动控制要怎么实现呢 xff1f 其实视觉跟踪已经在一些高端的消
  • windows环境下的Anaconda安装与OpenCV机器视觉环境搭建

    windows环境下的Anaconda安装与OpenCV机器视觉环境搭建 本文介绍win7和win10系统下通过Anaconda配置基于python语言的机器视觉编程环境 xff08 博主测试了两个系统下的安装基本相同 xff09 xff0
  • OpenCV—轮廓操作一站式详解:查找/筛选/绘制/形状描述与重心标注(C++版)

    OpenCV 轮廓操作一站式详解 xff1a 查找 筛选 绘制 形状描述与重心标注 C 43 43 版 轮廓 是定义或限定形状或对象的边或线 xff0c 是机器视觉中的常用的概念 xff0c 多用于目标检测 识别 等任务 关于OpenCV轮