Intelx86x64汇编指令集
英特尔®64和IA-32架构软件开发⼈员⼿册包括五个卷:基本体系结构,订单号253665;产品⽬录。指令集参考号AM,订单号253666;指令集参考书NZ,订单号253667;系统编程指南,第1部分,订单号253668;系统编程指南,第2部分,订货号
253669。在评估设计需求时,请参考所有五个卷。
⽂件:(访问密码:551685)
以下内容⽆关:
-------------------------------------------分割线---------------------------------------------
⼆值图像分析最常见的⼀个主要⽅式就是轮廓发现与轮廓分析,其中轮廓发现的⽬的是为轮廓分析做准备,经过轮廓分析我们可以得到轮廓各种有⽤的属性信息。
这⾥顺带提下边缘检测,和轮廓提取的区别:
边缘检测主要是通过⼀些⼿段检测数字图像中明暗变化剧烈(即梯度变化⽐较⼤)像素点,偏向于图像中像素点的变化。如canny边缘检测,结果通常保存在和源图⽚⼀样尺⼨和类型的边缘图中。
轮廓检测指检测图像中的对象边界,更偏向于关注上层语义对象。如OpenCV中的findContours()函数, 它会得到每⼀个轮廓并以点向量⽅式存储,除此也得到⼀个图像的拓扑信息,即⼀个轮廓的后⼀个轮廓、前⼀个轮廓、⽗轮廓和内嵌轮廓的索引编号。
⼀,轮廓的发现与绘制
在OpenCV⾥⾯利⽤findContours()函数和drawContours()函数实现这⼀功能。
findContours()函数
void findContours(
InputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
参数⼀: image,输⼊图像、⼋位单通道的,背景为⿊⾊的⼆值图像。(⼀般是经过Canny、拉普拉斯等边缘检测算⼦处理过的⼆值图像)
参数⼆:contours,输出轮廓图像。是⼀个向量,向量的每个元素都是⼀个轮廓。因此,这个向量的每个元素仍是⼀个向量。即:
vector<vector<Point> > contours;
参数三:hierarchy,输出各个轮廓的继承关系。hierarchy也是⼀个向量,长度和contours相等,每个元素和contours的元素对应。hierarchy的每个元素是⼀个包含四个整型数的向量。即:
vector<Vec4i> hierarchy;
参数四:mode,检测轮廓的⽅法。有四种⽅法:
RETR_EXTERNAL:只检测外轮廓。忽略轮廓内部的洞。
RETR_LIST:检测所有轮廓,但不建⽴继承(包含)关系。
RETR_TREE:检测所有轮廓,并且建⽴所有的继承(包含)关系。
RETR_CCOMP:检测所有轮廓,但是仅仅建⽴两层包含关系。
参数五:method,每个轮廓的编码信息。也有四种(常⽤前两种)
CHAIN_APPROX_NONE:把轮廓上所有的点存储。
CHAIN_APPROX_SIMPLE:只存储轮廓上的拐点。
CHAIN_APPROX_TC89_L1,CHAIN_APPROX_TC89_KCOS使⽤teh-Chinl chain 近似算法
参数六: Point,偏移量。默认为0
注意:该函数将⽩⾊区域当作前景物体。所以findContours()函数是⿊⾊背景下⽩⾊轮廓。(重要)
drawContours()函数
drawContours(
InputOutputArray binImg, // 输出图像
OutputArrayOfArrays contours,// 全部发现的轮廓对象
Int contourIdx// 轮廓索引号,-1表⽰绘制所有轮廓
const Scalar & color,// 绘制时候颜⾊
int thickness,// 绘制线宽,-1表⽰填充轮廓内部
int lineType,// 线的类型LINE_8
InputArray hierarchy,// 拓扑结构图
int maxlevel,// 最⼤层数, 0只绘制当前的,1表⽰绘制绘制当前及其内嵌的轮廓
Point offset = Point()// 轮廓位移,可选
)
⼆,轮廓分析(⼆值图像分析)
在得到图像的轮廓以后,我们就可以进⾏轮廓分析。经过轮廓分析我们可以得到轮廓各种有⽤的属性信息、常见的如下:
计算轮廓⾯积 :
contourArea(contour, oriented = False) //计算轮廓的⾯积
参数说明:contour为输⼊的单个轮廓值;oriented:轮廓⽅向,默认值false。
汇编指令有多少个如果为true,该函数返回⼀个带符号的⾯积,其正负取决于轮廓的⽅向(顺时针还是逆时针)。
如果是默认值false,则⾯积以绝对值的形式返回.
根据这个特性可以根据⾯积的符号来确定轮廓的位置。
计算轮廓周长:
arcLength(contour, closed) // 计算轮廓的周长
参数说明:contour为输⼊的单个轮廓值,closed表⽰轮廓是否封闭(true为封闭,false为不封闭)
计算⼏何矩与中⼼距: moments()
Moments m = moments(contours[t]); //获取轮廓的距
//计算轮廓质⼼
double cx = m.m10 / m.m00;
double cy = m.m01 / m.m00;
轮廓的外接矩形:
轮廓的外接矩形有两种,如下图,绿⾊的叫外接矩形boundingRect(),表⽰不考虑旋转并且能包含整个轮廓的矩形。蓝⾊的叫最⼩外接矩形minAreaRect(),考虑了旋转
1 外接矩形Rect boundingRect(InputArray points)
输⼊参数points可以⼀系列点的集合,对轮廓来说就是该轮廓的点集 返回结果是⼀个正矩形,包含以下信息:
矩形左上⾓的坐标(rect.x,rect.y)
矩形的宽和⾼(rect.width,rect.height)
Rect rect = boundingRect(Mat(contours[i]));//获取轮廓外接正矩形
rectangle(src, rect, (0, 0, 255), 2, 8, 0);
2 最⼩外接矩形minAreaRect()
输⼊参数points可以⼀系列点的集合,对轮廓来说就是该轮廓的点集 返回结果是⼀个旋转矩形,包含下⾯的信息:
旋转矩形的中⼼坐标()
旋转矩形的宽和⾼(rect.size.width,rect.size.height)
旋转矩形的⾓度(rect.angle)
RotatedRect rect = minAreaRect(contours[i]);//获取轮廓最⼩外接矩形
Point2f P[4];
rect.points§;//获取四顶点坐标
for (int j = 0; j <= 3; j++)
{
line(src, P[j], P[(j + 1) % 4], Scalar(0,0,255), 1);//依次连线
}
最⼩外接圆/拟合圆:minEnclosingCircle()
void minEnclosingCircle(InputArray points, Point2f& center, float& radius);
points,输⼊的⼆维点集,可以是 vector 或 Mat 类型。
center,圆的输出圆⼼。
radius,圆的输出半径。
例如:
findContours(bin_img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
//寻包裹轮廓的最⼩圆
vectorcenters(contours.size());//圆⼼个数
vectorradius(contours.size());//半径个数
for (int i = 0; i < contours.size(); i++)
{
//寻并绘制最⼩圆
minEnclosingCircle(contours[i], centers[i], radius[i]);
circle(src, centers[i], radius[i], scalar(0,0,255), 2);
}
拟合椭圆:fitEllipse()
RotatedRect fitEllipse(InputArray points);
//唯⼀⼀个参数是输⼊的⼆维点集,可以是 vector 或 Mat 类型。
例如:
// 轮廓发现与绘制
vector<vector> contours;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());
for (size_t t = 0; t < contours.size(); t++)
{
// 拟合椭圆
RotatedRect rrt = fitEllipse(contours[t]);
ellipse(src, rrt, Scalar(0, 0, 255), 2, 8);
}
imshow(“contours”, src);
拟合直线:fitLine()
OpenCV中直线拟合正是基于最⼩⼆乘法实现的。其函数将计算出的直线信息存放在 line 中,(为Vec4f 类型)。line[0]、line[1] 存放的是直线的⽅向向量,float cosθ = oneline[0]; float sinθ = oneline[1]。line[2]、line[3] 存放的是直线上⼀个点的坐标。
实现直线拟合的API如下:
void fitLine(
InputArray points, //输⼊待拟合的⼆维点的数组或vector
OutputArray line, //输出直线,Vec4f (2d)或Vec6f (3d)的vector
int distType, //距离类型
double param, //距离参数(⼀般设为0)
double reps, //径向的精度参数(⼀般设为0.01)
double aeps //⾓度精度参数(⼀般设为0.01)
)
distType(距离类型)有六种参数:(DIST_L2就是最⼩⼆乘法)
opencv实现:
Mat src = imread(“D:/opencv练习图⽚/直线拟合.png”);
imshow(“原图⽚”, src);
// 去噪声与⼆值化
Mat dst, gray, binary;
Canny(src, binary, 80, 160, 3, false);
imshow(“canny⼆值化”, binary);
Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
dilate(binary, binary, k);
/
/ 轮廓发现与绘制
vector<vector> contours;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());
for (size_t t = 0; t < contours.size(); t++) {
// 最⼤外接轮廓
Rect rect = boundingRect(contours[t]);
int m = max(rect.width, rect.height);
if (m < 30) continue;
// 直线拟合
Vec4f oneline;
fitLine(contours[t], oneline, DIST_L1, 0, 0.01, 0.01);
float cosθ = oneline[0];
float sinθ = oneline[1];
float x0 = oneline[2];
float y0 = oneline[3];
// 直线参数斜率k与截矩b
float k = sinθ / cosθ; //求tanθ,也就是斜率
float b = y0 - k * x0;
float x = 0;
float y = k * x + b;
line(src, Point(x0, y0), Point(x, y), Scalar(0, 0, 255), 2, 8, 0);
}
imshow("结果", src);
轮廓的凸包:convexHull()
凸包(Convex Hull)是⼀个计算⼏何(图形学)中常见的概念。简单来说,给定⼆维平⾯上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它是能包含点集中所有点的。
理解物体形状或轮廓的⼀种⽐较有⽤的⽅法便是计算⼀个物体的凸包,然后计算其凸缺陷(convexity defects)。
convexHull ( InputArray points, /输⼊的⼆维点集,Mat类型数据即可
OutputArray hull, //输出参数,⽤于输出到的凸包
bool clockwise = false, //操作⽅向,为True时,输出的凸包为顺时针⽅向,否则为逆时针⽅向
bool returnPoints = true //凸包的返回形式,默认值为true,此时返回点坐标的形式,否则返回对应点的索引值
)
凸包检测原理:
opencv实现:
Mat src = imread("D:/opencv练习图⽚/凸包检测.jpg");
imshow("原图⽚", src);
// ⼆值化
Mat dst, gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
// 形态学去除⼲扰
Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(binary, binary, MORPH_OPEN, k);
imshow("binary", binary);
// 轮廓发现与绘制
vector<vector<Point>> contours;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());
for (size_t t = 0; t < contours.size(); t++) {
vector<Point> hull;
convexHull(contours[t], hull);//凸包检测
bool isHull = isContourConvex(contours[t]);//判断轮廓是否为凸包
printf("test convex of the contours %s", isHull ? "Y" : "N");
int len = hull.size();
//绘制凸包
for (int i = 0; i < hull.size(); i++) {
circle(src, hull[i], 4, Scalar(255, 0, 0), 2, 8, 0);//点
line(src, hull[i%len], hull[(i + 1) % len], Scalar(0, 0, 255), 2, 8, 0);//线
}
}
imshow("凸包检测", src);
多边形逼近-逼近真实形状:approxPolyDP()
轮廓的多边形逼近指的是:使⽤多边形来近似表⽰⼀个轮廓。 多边形逼近的⽬的是为了减少轮廓的顶点数⽬。 多边形逼近的结果依然是⼀个轮廓,只是这个轮廓相对要粗旷⼀些。
void approxPolyDP( InputArray curve, //输⼊曲线,⼀般是由图像的轮廓点组成的点集
OutputArray approxCurve, //表⽰输出的逼近后多边形的点集(类型与输⼊曲线的类型相同)
double epsilon, //轮廓逼近的顶点距离真实轮廓曲线的最⼤距离,该值越⼩表⽰越逼近真实轮廓
bool closed //表⽰输出的多边形是否封闭
)
opencv实现:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论