- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章OpenCV-Python实现轮廓拟合由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
什么是轮廓?
轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同 的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用.
在计算轮廓时,可能并不需要实际的轮廓,而仅需要一个接近于轮廓的近似多边形。比如矩形其实都是差不多的轮廓,都是长宽不相等且平行的四边形,那么只要提供一个近似的轮廓,我们就可以区分形状.
在opencv中,它给我们提供了cv2.boundingrect()函数来绘制轮廓的矩形边界,其完整定义如下:
1
|
def
boundingrect(array):
|
array:前面已经介绍过,array是一个灰度图像,或者轮廓.
该函数返回3个值时,是矩形边界的左上角顶点的坐标值以及矩形边界的宽与高。返回4个值时,是矩形左上角顶点的x坐标,y坐标,以及宽高.
现在,我们还是使用前面的一张椭圆图形,如下图所示:
得到图形之后,我们使用上面的函数,计算该图像轮廓的4值,代码如下:
1
2
3
4
5
6
7
8
9
10
11
|
import
cv2
img
=
cv2.imread(
"26_1.jpg"
)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img1, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
x, y, w, h
=
cv2.boundingrect(contours[
0
])
print
(x, y, w, h)
|
运行之后,控制台输出如下内容:
这里我们得到了椭圆的矩形左上角坐标为(53,120),其宽高分别为272与84.
既然我们已经得到了其矩形边界的坐标以及宽高,那么我们可以开始绘制其矩形边界。前面提取轮廓绘制用的是cv2.drawcontours()函数,这里同样也是.
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
cv2
import
numpy as np
img
=
cv2.imread(
"26_1.jpg"
)
cv2.imshow(
"img1"
,img)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
x, y, w, h
=
cv2.boundingrect(contours[
0
])
rect
=
np.array([[[x,y],[x
+
w,y],[x
+
w,y
+
h],[x,y
+
h]]])
#1
cv2.drawcontours(img,[rect],
-
1
,(
255
,
255
,
255
),
2
)
#1
cv2.imshow(
"img2"
,img)
cv2.waitkey()
cv2.destroyallwindows()
|
运行之后,其椭圆的矩形边界就被我们标记出来了,效果如下:
当然,这里我们还可以使用另一个函数cv2.rectangle()来绘制矩形边界,值需要更换上面代码中注释1的两个代码,具体如下所示:
1
|
cv2.rectangle(img, (x, y), (x
+
w, y
+
h), (
255
,
255
,
255
),
2
)
|
在opencv中,它还提供了cv2.minarearect()来绘制最小包围矩形框,其完整定义如下:
1
|
def
minarearect(points):
|
其中points参数是轮廓,返回值为矩形特征信息,包括矩形的中心(x,y),宽高,以及旋转角度.
特别注意,minarearect函数的返回值并不能直接代入drawcontours()函数中。因此,我们必须将其转换为符合要求的结构才能接着操作。通过cv2.boxpoint()函数就可以转换为符合drawcontours()的结构参数.
还是上面那张图,不过我们用旋转后的椭圆原图,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import
cv2
import
numpy as np
img
=
cv2.imread(
"26_4.jpg"
)
cv2.imshow(
"img1"
,img)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
rect
=
cv2.minarearect(contours[
0
])
print
(rect)
points
=
cv2.boxpoints(rect)
print
(points)
points
=
np.int0(points)
print
(points)
cv2.drawcontours(img,[points],
0
,(
255
,
255
,
255
),
2
)
cv2.imshow(
"img2"
,img)
cv2.waitkey()
cv2.destroyallwindows()
|
运行之后,图像效果以及控制台的输出信息如下:
这里我们可以清楚的看到minarearect()函数返回值的转换过程。先通过boxpoints()函数转换为drawcontours()函数能接受的参数格式,然后通过取整转换为具体的像素坐标值.
既然有最小包围矩形框,那么一定就有最小包围圆形框。在opencv中,它给我们提供cv2.minenclosingcircle()函数来绘制最小包围圆形框.
函数的完整定义如下:
1
|
def
minenclosingcircle(points):
|
这里的参数与上面的points参数一致,但是其返回值并不相同,毕竟绘制圆形肯定与绘制矩形的参数肯定不一样.
它有两个返回值,一个是圆形的中心坐标(x,y),一个是圆形的半径r。下面,我们直接来绘制上面椭圆的最小包围圆形框。具体代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import
cv2
import
numpy as np
img
=
cv2.imread(
"26_4.jpg"
)
cv2.imshow(
"img1"
, img)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
(x, y), r
=
cv2.minenclosingcircle(contours[
0
])
center
=
(
int
(x),
int
(y))
r
=
int
(r)
cv2.circle(img, center, r, (
255
,
255
,
255
),
2
)
cv2.imshow(
"img2"
, img)
cv2.waitkey()
cv2.destroyallwindows()
|
运行之后,效果如下所示:
在opencv中,它给我们提供了cv2.fitellipse()函数绘制最优拟合椭圆。其完整的定义如下:
1
|
def
fitellipse(points):
|
其中points参数与前文一致,而它的返回值是rotatedrect类型,这是因为该函数返回的是拟合椭圆的外接矩形,包括矩形的质心,宽高,旋转角度等信息,这些信息正好与椭圆的中心点,轴长度,旋转角度一致.
下面,我们来使用该函数绘制最优拟合椭圆,这里我们选取如上图所示的一张矩形图。具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
cv2
img
=
cv2.imread(
"27.jpg"
)
cv2.imshow(
"img1"
, img)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
ellipse
=
cv2.fitellipse(contours[
0
])
cv2.ellipse(img, ellipse, (
0
,
0
,
255
),
3
)
cv2.imshow(
"img2"
, img)
cv2.waitkey()
cv2.destroyallwindows()
|
运行之后,效果如下所示:
在opencv中,它还提供了cv2.fitline()函数绘制最优拟合直线,其完整定义如下:
1
|
def
fitellipse(points):
|
points:与前文一样,是轮廓 。
disttype:距离类型。拟合直线时,要使输入点到拟合直线的距离之和最小。详细参数定义参考开发文档,这里不在赘述.
param:距离参数,与所选距离类型有关。当该参数为0时,自动选择最优值.
reps:用于表示拟合直线所需要的径向精度,通常该值被设定为0.01 。
aeps:用于表示拟合直线所需要的角度精度,通常该值被设定为0.01 。
对于二维直线,返回值line为4维,前两维代表拟合出的直线的方向,后两位代表直线上的一点.
下面,我们来直接使用代码绘制最优拟合直线.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
cv2
img
=
cv2.imread(
"27.jpg"
)
cv2.imshow(
"img1"
, img)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
ellipse
=
cv2.fitellipse(contours[
0
])
cv2.ellipse(img, ellipse, (
0
,
0
,
255
),
3
)
cv2.imshow(
"img2"
, img)
cv2.waitkey()
cv2.destroyallwindows()
|
运行之后,效果如下所示:
对于绘制直线来说,我们需要获取绘制直线的起点以及终点,这里lefty为起点,righty为终点.
在opencv,它还提供了cv2.minenclosingtriangle()函数来绘制最小外包三角形。其完整定义如下:
1
|
def
minenclosingtriangle(points, triangle
=
none):
|
其中points与前文类似,其返回值triangle为外包三角形的三个顶点集.
下面,我们直接构建最小外包三角形,具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
cv2
img
=
cv2.imread(
"27.jpg"
)
cv2.imshow(
"img1"
, img)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
area, trg1
=
cv2.minenclosingtriangle(contours[
0
])
print
(area)
print
(trg1)
for
i
in
range
(
0
,
3
):
cv2.line(img,
tuple
(trg1[i][
0
]),
tuple
(trg1[(i
+
1
)
%
3
][
0
]), (
0
,
255
,
0
),
2
)
cv2.imshow(
"img2"
, img)
cv2.waitkey()
cv2.destroyallwindows()
|
运行之后,效果如下:
需要注意的是,在cv2中没有直接绘制三角形的函数,所以我们通过绘制三条直线,绘制三角形,minenclosingtriangle()函数第一个返回值为三角形面积,第二返回值是三点坐标.
在opencv中,它还提供了cv2.approxpolydp()函数构建指定边数的逼近多边形。其完整定义如下:
1
|
def
approxpolydp(curve, epsilon, closed, approxcurve
=
none):
|
curve:轮廓 。
epsilon:精度,原始轮廓的边界点与逼近多边形边界之间的最大距离 。
closed:布尔类型。为true时,表示逼近多边形是封闭的。为false时,biao表示毕竟多边形是不封闭的.
approxcurve为该函数的返回值,是逼近多边形的点集。.
下面,我们来实现各类逼近多边形的绘制,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import
cv2
img
=
cv2.imread(
"24.jpg"
)
list
=
[
0.1
,
0.09
,
0.055
,
0.05
,
0.02
]
cv2.imshow(
"img"
, img)
# 转换为灰度图像
gray
=
cv2.cvtcolor(img, cv2.color_bgr2gray)
ret, binary
=
cv2.threshold(gray,
127
,
255
, cv2.thresh_binary)
contours, hierarchy
=
cv2.findcontours(binary, cv2.retr_list, cv2.chain_approx_simple)
for
i, val
in
enumerate
(
list
):
epsilon
=
val
*
cv2.arclength(contours[
0
], true)
approx
=
cv2.approxpolydp(contours[
0
], epsilon, true)
cv2.drawcontours(img, [approx],
0
, (
0
,
255
,
0
),
2
)
cv2.imshow(
"img"
+
str
(i), img)
cv2.waitkey()
cv2.destroyallwindows()
|
运行之后,效果如下:
cv2.approxpolydp()函数采用的是douglas-peucker算法,该算法的原理是首先从轮廓中找到距离最远的两个点,并将两个点相连。接下来,在轮廓上找到一个离当前直线最远的点,并将该点与原有直线连成一个封闭的多边形,此时得到一个三角形。以此类推四边形,五边形,六边形等。当前多边形的距离都小于函数cv2.approxpolydp()的参数epsilon的值时,就停止迭代.
到此这篇关于opencv-python实现轮廓拟合的文章就介绍到这了,更多相关opencv 轮廓拟合内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://liyuanjinglyj.blog.csdn.net/article/details/113921491 。
最后此篇关于OpenCV-Python实现轮廓拟合的文章就讲到这里了,如果你想了解更多关于OpenCV-Python实现轮廓拟合的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一个不规则形状的元素(比方说图标)。 我想要围绕它的某种轮廓,以符合特定颜色的形状。此轮廓的颜色必须均匀地围绕形状,即与形状各处的距离相同,并且没有颜色渐变。 我发现使用的是 css 选项 fil
这部分代码我总是出错 &contours = ((contours.h_next) -> h_next); contours.h_next = ((contours.h_next) -> h_next
我通过 css (:after) 创建了 3 个圆圈,使用一些背景颜色,边框看起来不规则。有什么解决办法吗? 在这里您可以看到问题:https://flowersliving.com/cpt_01/a
使用这个: background: -moz-linear-gradient(315deg, transparent 10px, black 10px); 如何在不使用 border 的情况下围绕它创
我想计算二元 NxM 矩阵中某个形状周围的凸包。凸包算法需要一个坐标列表,所以我采用 numpy.argwhere(im) 来获得所有形状点坐标。然而,这些点中的大多数对凸包没有贡献(它们位于形状的内
如何删除从下拉菜单中选择元素时显示的虚线边框/轮廓? 您可以看到显示了虚线边框/轮廓,我想删除它(在 Firefox 中截取的屏幕截图)。 尝试下面的解决方案并没有删除它: select:focus,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎是题外话,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或include a min
我正在使用 Qt4 GraphicsView 框架绘制一些多边形,并且允许用户放大和缩小绘图。我希望多边形随着用户在 View 中更改缩放级别(比例)而变得越来越小,但是有没有办法使轮廓厚度始终保持不
我在 C# 中有一个 Vector3 点列表,我需要计算这些点的凹轮廓。确实有很多引用资料,尤其是 -convex- 分辨率(我已经成功实现了,多亏了 graham 的算法), 但是,由于我现在需要有
注: r 中的解决方案, python , java ,或者如果需要,c++或 c#是需要的。 我正在尝试根据运输时间绘制轮廓。更清楚地说,我想将具有相似旅行时间(比如说 10 分钟间隔)的点聚集到特
假设我在图像上找到了轮廓。在图像 2 上找到此轮廓位置的最佳方法是什么? 我看到两个选项:要么我用白线绘制轮廓并匹配图像 2 上的图像,要么我以某种方式(这甚至可能吗?)直接匹配图像 2 上的轮廓。
我一直在研究细菌的图像,希望从图像中获取细菌的数量,还需要根据特定的形状和大小对细菌进行分类。 我正在使用opencv python。现在,我使用轮廓法。 contours,hierarchy
我无法区分以下两个轮廓。 cv2.contourArea两者的值相同。在Python中有什么功能可以区分它们吗? 最佳答案 要区分填充轮廓和未填充轮廓,可以在使用 cv2.findContours 查
是否可以根据 Activity 配置文件的某些表达式来注册bean前任。 @Profile(!prod) @Profile(name!="test") 我有一种情况,我需要根据许多不同的条件配
我有一个由多个 CAShapeLayer 组成的 3D 相似图形对象。必须抚摸所有形状(天花板和墙壁)。有些形状共享一条边 - 这似乎是问题的根源。 然而,轮廓似乎是围绕另一个形状的现有轮廓绘制的。所
有谁知道,是否可以在用户使用顺序导航(TAB 按钮)时在输入元素周围显示轮廓,并在用户用鼠标单击此输入元素时隐藏轮廓?有没有人实现过这种行为? 我在 CSS 文件中的 :focus 选择器上使用这个属
这是我在 StackOverflow 上的第一个问题,所以我会尝试以正确的方式格式化它。 基本上,我有一个带有边框和轮廓的 div。悬停时,div 也会有一个阴影,当然,它应该在轮廓之外。这适用于所有
我在 Opencv 2.9 (C++) 中使用 findContours。我得到的是一个 vector> contours,它描述了我的轮廓。假设我有一个矩形,其轮廓存储在 vector 中。接下来我
我有一个 div,它有附加的子 div,定位在父 div 之外。 我希望父 div 有一个轮廓 onclick,但轮廓延伸到子 div 周围。 有没有办法让轮廓完全围绕父 div。 我不能使用边框,因
我正在尝试在彩色图标周围设置实线边框。 应该足够直截了当,显然它适用于字形,但我无法让它适用于 我试过... // like this fiddle: http://jsfiddle.net/9s
我是一名优秀的程序员,十分优秀!