等高线的 arcLength 结果是什么?
What is the result of arcLength for a contour?
我在 Google 中搜索了 arcLength
,好吧,也许我能理解它,但是它如何在 EmguCV 或 OpenCV 中对图像中的轮廓起作用?我尝试使用 MATLAB 制作一个小图像。图像是 9 x 9
,我在图像中画了一条线,那条线是 1 个像素。我在 EmguCV 中使用这段代码来检测轮廓:
VectorOfVectorOfPoint cons = new VectorOfVectorOfPoint();
CvInvoke.FindContours(img_gray, cons, null, RetrType.List, ChainApproxMethod.ChainApproxNone);
for(int i=0; i<cons.Size;i++)
{
VectorOfPoint points = cons[i];
for(int x =0; x<points.Size;x++)
{
temp[points[x]] = new Gray(255);
}
double c= CvInvoke.ArcLength(cons[i], true);
textBox1.Text = c.ToString();
}
imageBox2.Image = temp;
arcLength
是:
- 当线条为 1 个像素时 ->
arcLength
为 0。
- 当线条为 2 像素时 ->
arcLength
为 2.
- 当线条为 3 像素时 ->
arcLength
为 4。
这是我在线条为 3 像素时的图像。
谁能给我解释一下结果吗?
arcLength
确实如其所言:
Calculates a contour perimeter or a curve length.
在您的示例中,您被 findContours
(!) 的特定问题所愚弄,即应用于 1 像素宽的线条时! (实施问题、算法问题、"border following" 的一般问题,...!?)
让我们看看下面的例子(很抱歉在这里使用Python API,但是概念应该清楚了)。
示例 1: 3 x 1
黑色图像上的白线
import cv2
import numpy as np
# Generate 5 x 5 black image
img = np.zeros((5, 5), np.uint8)
# Draw 3 x 1 white line
img = cv2.rectangle(img, (1, 1), (3, 1), 255, cv2.FILLED)
# Find contours
cnts = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# Outputs
print(img, '\n') # Image
print(np.squeeze(cnts[0]), '\n') # Contour
print('Contour points:', cnts[0].shape[0], '\n')
print('arcLength:', cv2.arcLength(cnts[0], True))
输出:
[[ 0 0 0 0 0]
[ 0 255 255 255 0]
[ 0 0 0 0 0]
[ 0 0 0 0 0]
[ 0 0 0 0 0]]
[[1 1]
[2 1]
[3 1]
[2 1]]
Contour points: 4
arcLength: 4.0
请注意,[2 1]
在轮廓中出现了两次,所以我们总共有四个轮廓点,两个相邻轮廓点之间的每个"distance"都是1,因此轮廓周长(=弧长)也是 4.
示例 2: 3 x 2
黑色图像上的白色矩形
import cv2
import numpy as np
# Generate 5 x 5 black image
img = np.zeros((5, 5), np.uint8)
# Draw 3 x 2 white rectangle
img = cv2.rectangle(img, (1, 1), (3, 2), 255, cv2.FILLED)
# Find contours
cnts = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# Outputs
print(img, '\n') # Image
print(np.squeeze(cnts[0]), '\n') # Contour
print('Contour points:', cnts[0].shape[0], '\n')
print('arcLength:', cv2.arcLength(cnts[0], True))
输出:
[[ 0 0 0 0 0]
[ 0 255 255 255 0]
[ 0 255 255 255 0]
[ 0 0 0 0 0]
[ 0 0 0 0 0]]
[[1 1]
[1 2]
[2 2]
[3 2]
[3 1]
[2 1]]
Contour points: 6
arcLength: 6.0
我们得到六个轮廓点,并且两个相邻轮廓点之间的每个 "distance" 都是 1,因此轮廓周长(= 弧长)也是 6 – 这似乎(更)合理。
示例 3: 黑色图像上半径为 2
的白色圆圈
import cv2
import numpy as np
# Generate 5 x 5 black image
img = np.zeros((5, 5), np.uint8)
# Draw white circle with radius 2
img = cv2.circle(img, (2, 2), 2, 255, cv2.FILLED)
# Find contours
cnts = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# Outputs
print(img, '\n') # Image
print(np.squeeze(cnts[0]), '\n') # Contour
print('Contour points:', cnts[0].shape[0], '\n')
print('arcLength:', cv2.arcLength(cnts[0], True))
输出:
[[ 0 0 255 0 0]
[ 0 255 255 255 0]
[255 255 255 255 255]
[ 0 255 255 255 0]
[ 0 0 255 0 0]]
[[2 0]
[1 1]
[0 2]
[1 3]
[2 4]
[3 3]
[4 2]
[3 1]]
Contour points: 8
arcLength: 11.313708305358887
从 [2 0]
到 [1 1]
的 "distance" 是 1.414...(2 的平方根)。每两个相邻的轮廓点都有那个距离(见图),所以我们的轮廓周长(=弧长)为 8 * 1.414... = 11.313...
希望对理解有所帮助!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.2.0
----------------------------------------
我在 Google 中搜索了 arcLength
,好吧,也许我能理解它,但是它如何在 EmguCV 或 OpenCV 中对图像中的轮廓起作用?我尝试使用 MATLAB 制作一个小图像。图像是 9 x 9
,我在图像中画了一条线,那条线是 1 个像素。我在 EmguCV 中使用这段代码来检测轮廓:
VectorOfVectorOfPoint cons = new VectorOfVectorOfPoint();
CvInvoke.FindContours(img_gray, cons, null, RetrType.List, ChainApproxMethod.ChainApproxNone);
for(int i=0; i<cons.Size;i++)
{
VectorOfPoint points = cons[i];
for(int x =0; x<points.Size;x++)
{
temp[points[x]] = new Gray(255);
}
double c= CvInvoke.ArcLength(cons[i], true);
textBox1.Text = c.ToString();
}
imageBox2.Image = temp;
arcLength
是:
- 当线条为 1 个像素时 ->
arcLength
为 0。 - 当线条为 2 像素时 ->
arcLength
为 2. - 当线条为 3 像素时 ->
arcLength
为 4。
这是我在线条为 3 像素时的图像。
谁能给我解释一下结果吗?
arcLength
确实如其所言:
Calculates a contour perimeter or a curve length.
在您的示例中,您被 findContours
(!) 的特定问题所愚弄,即应用于 1 像素宽的线条时! (实施问题、算法问题、"border following" 的一般问题,...!?)
让我们看看下面的例子(很抱歉在这里使用Python API,但是概念应该清楚了)。
示例 1: 3 x 1
黑色图像上的白线
import cv2
import numpy as np
# Generate 5 x 5 black image
img = np.zeros((5, 5), np.uint8)
# Draw 3 x 1 white line
img = cv2.rectangle(img, (1, 1), (3, 1), 255, cv2.FILLED)
# Find contours
cnts = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# Outputs
print(img, '\n') # Image
print(np.squeeze(cnts[0]), '\n') # Contour
print('Contour points:', cnts[0].shape[0], '\n')
print('arcLength:', cv2.arcLength(cnts[0], True))
输出:
[[ 0 0 0 0 0]
[ 0 255 255 255 0]
[ 0 0 0 0 0]
[ 0 0 0 0 0]
[ 0 0 0 0 0]]
[[1 1]
[2 1]
[3 1]
[2 1]]
Contour points: 4
arcLength: 4.0
请注意,[2 1]
在轮廓中出现了两次,所以我们总共有四个轮廓点,两个相邻轮廓点之间的每个"distance"都是1,因此轮廓周长(=弧长)也是 4.
示例 2: 3 x 2
黑色图像上的白色矩形
import cv2
import numpy as np
# Generate 5 x 5 black image
img = np.zeros((5, 5), np.uint8)
# Draw 3 x 2 white rectangle
img = cv2.rectangle(img, (1, 1), (3, 2), 255, cv2.FILLED)
# Find contours
cnts = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# Outputs
print(img, '\n') # Image
print(np.squeeze(cnts[0]), '\n') # Contour
print('Contour points:', cnts[0].shape[0], '\n')
print('arcLength:', cv2.arcLength(cnts[0], True))
输出:
[[ 0 0 0 0 0]
[ 0 255 255 255 0]
[ 0 255 255 255 0]
[ 0 0 0 0 0]
[ 0 0 0 0 0]]
[[1 1]
[1 2]
[2 2]
[3 2]
[3 1]
[2 1]]
Contour points: 6
arcLength: 6.0
我们得到六个轮廓点,并且两个相邻轮廓点之间的每个 "distance" 都是 1,因此轮廓周长(= 弧长)也是 6 – 这似乎(更)合理。
示例 3: 黑色图像上半径为 2
的白色圆圈
import cv2
import numpy as np
# Generate 5 x 5 black image
img = np.zeros((5, 5), np.uint8)
# Draw white circle with radius 2
img = cv2.circle(img, (2, 2), 2, 255, cv2.FILLED)
# Find contours
cnts = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# Outputs
print(img, '\n') # Image
print(np.squeeze(cnts[0]), '\n') # Contour
print('Contour points:', cnts[0].shape[0], '\n')
print('arcLength:', cv2.arcLength(cnts[0], True))
输出:
[[ 0 0 255 0 0]
[ 0 255 255 255 0]
[255 255 255 255 255]
[ 0 255 255 255 0]
[ 0 0 255 0 0]]
[[2 0]
[1 1]
[0 2]
[1 3]
[2 4]
[3 3]
[4 2]
[3 1]]
Contour points: 8
arcLength: 11.313708305358887
从 [2 0]
到 [1 1]
的 "distance" 是 1.414...(2 的平方根)。每两个相邻的轮廓点都有那个距离(见图),所以我们的轮廓周长(=弧长)为 8 * 1.414... = 11.313...
希望对理解有所帮助!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.2.0
----------------------------------------