如何确定OpenCV轮廓中的曲线点 [英] How to determine curve points in OpenCV contours
问题描述
大家好,
对于我的图像处理项目,我需要在轮廓中找到曲线点。
在下面显示的示例图像中,检测到的轮廓以红色显示。现在我需要在水平和/或垂直轴上找到曲线点/坐标(用蓝色箭头表示)。
http://imageshack.com/a/img540/7162/3NEzhC.jpg [ ^ ]
曲线未必完美省略号。
任何人都可以告诉我这样做的好方法。
一些参考代码块会非常感激,但会有一个解释单独也会有所帮助。
Hello everyone,
For my image processing project i need to find curve points in a contour.
In the example image shown below, detected contour is shown in Red. Now i need to find the curve points/coordinates (indicated with blue arrows) on horizontal and/or vertical axis.
http://imageshack.com/a/img540/7162/3NEzhC.jpg[^]
The curves may not necessarily be perfect ellipses.
Can anyone please let me know a good approach to do so.
Some reference code block would be much appreciated but an explanation alone would also be helpful.
推荐答案
Hello Everyone
Hello Everyone
我研究了一下,发现取轮廓的一阶导数(分别用于x和y)可以解决这个问题。
I studied a bit and found that taking the first order derivative of the contour (for x and for y separately) can solve this problem.
一阶导数用于找到局部最大值和最小值。在曲线点上,一阶导数的值从正变为负(对于峰值)和从负变为正(对于谷)。
The first order derivative is used to find Local Maxima and Minima. On the curve points the value of the first order derivative changes from positive to negative (for a peak) and from negative to positive (for a valley).
基本定义一维函数f(x)的一阶导数是差值
A basic definition of the first-order derivative of a one-dimensional function f(x) is the difference
df / dx = f(x + 1) - f(x)
要确定波谷和峰值(水平轴上的曲线点),只需要轮廓点的Y值。类似于确定垂直轴上的曲线点,只需要轮廓点的X值。
To determine valley and peaks (curve points on horizontal axis), only Y value of the contour points is required. Similarly to determine curve points on vertical axis, only X value of the contour points is required.
我在这里放了一小部分用于确定山谷的代码(Minima)在轮廓中。
I am putting here a small part of code used to determine only valleys (Minima) in a contour.
非常欢迎任何改进方法或代码的建议。
Any suggestion to improve the approach or the code is very much welcome.
int posCntr = 0;
int negCntr = 0;
var diffY = new List<List<int>>();
var diff2Y = new List<List<int>>();
var diffSeq = new List<List<int>>();
// Process each detected contour
for (int n = 0; n < validContours.Count; n++)
{
posCntr = 0;
negCntr = 0;
diffY.Add(new List<int>());
diffSeq.Add(new List<int>());
for (int i = 0; i < validContours[n].Total - 1; i++)
{
// Taking first derivative of contour
// df/dy = f(y+1) - f(y);
diffY[n].Add(validContours[n][i + 1].Y - validContours[n][i].Y);
// count continuous positive and negative values and add them to a list
// list will have consecutive positives, negatives, positives, negatives, ...
if (diffY[n][i] >= 0)
{
posCntr++;
if (negCntr != 0)
{
diffSeq[n].Add(negCntr);
negCntr = 0;
}
}
else //if (diffY[n][i] < 0)
{
negCntr++;
if (posCntr != 0)
{
diffSeq[n].Add(posCntr);
posCntr = 0;
}
}
}
if (negCntr != 0)
{
diffSeq[n].Add(negCntr);
negCntr = 0;
}
else if (posCntr != 0)
{
diffSeq[n].Add(posCntr);
posCntr = 0;
}
}
int cntr;
for (int n = 0; n < validContours.Count; n++)
{
cntr = 0;
for (int i = 0; i < diffSeq[n].Count - 1; i = i + 2)
{
// Check if the consequtive pos, neg seq counts are above a threshold level
// if they are, means we have found a Minima
if (diffSeq[n][i] >= Constants.CURVE_SZ &&
diffSeq[n][i + 1] >= Constants.CURVE_SZ)
Console.WriteLine(validContours[n][cntr + diffSeq[n][i]].ToString());
cntr += diffSeq[n][i] + diffSeq[n][i+1];
}
}
这篇关于如何确定OpenCV轮廓中的曲线点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!