我试图将以下OpenCV C ++代码翻译成Emgu CV 3:
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> v4iHierarchy;
cv::findContours(imgThreshCopy, contours, v4iHierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
我可以找到一些使用null作为findContours的第3个参数的Emgu CV 3示例,例如,这样做就是Visual Basic翻译:
Dim contours As New VectorOfVectorOfPoint()
CvInvoke.FindContours(imgThreshCopy, contours, Nothing, RetrType.Tree, ChainApproxMethod.ChainApproxSimple)
如果不需要层次结构参数,那么哪个有效,但是如果是这样的话呢?我似乎无法想象C ++行的Emgu CV 3语法等价
std::vector<cv::Vec4i> v4iHierarchy;
还有其他人得到这个吗?任何帮助将不胜感激。
答案 0 :(得分:3)
传递默认构造的Mat
以获取层次结构。
var VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
var Mat hierarchy = new Mat();
CvInvoke.FindContours(
image,
contours,
hierarchy,
RetrType.Ccomp,
ChainApproxMethod.ChainApproxSimple
);
Console.WriteLine("contours.Size: " + contours.Size);
Console.WriteLine("hierarchy.Rows: " + hierarchy.Rows);
Console.WriteLine("hierarchy.Cols: " + hierarchy.Cols);
Console.WriteLine("hierarchy.Depth: " + hierarchy.Depth);
Console.WriteLine("hierarchy.NumberOfChannels: " + hierarchy.NumberOfChannels);
// Example Output:
// contours.Size: 4391
// hierarchy.Rows: 1
// hierarchy.Cols: 4391
// hierarchy.Depth: Cv32S
// hierarchy.NumberOfChannels: 4
您可以使用Mat DataPointer访问层次结构数据:
/// <summary>
/// Get a neighbor index in the heirarchy tree.
/// </summary>
/// <returns>
/// A neighbor index or -1 if the given neighbor does not exist.
/// </returns>
public int Get(HierarchyIndex component, int index)
{
if (Hierarchy.Depth != Emgu.CV.CvEnum.DepthType.Cv32S)
{
throw new ArgumentOutOfRangeException("ContourData must have Cv32S hierarchy element type.");
}
if (Hierarchy.Rows != 1)
{
throw new ArgumentOutOfRangeException("ContourData must have one hierarchy hierarchy row.");
}
if (Hierarchy.NumberOfChannels != 4)
{
throw new ArgumentOutOfRangeException("ContourData must have four hierarchy channels.");
}
if (Hierarchy.Dims != 2)
{
throw new ArgumentOutOfRangeException("ContourData must have two dimensional hierarchy.");
}
long elementStride = Hierarchy.ElementSize / sizeof(Int32);
var offset = (long)component + index * elementStride;
if (0 <= offset && offset < Hierarchy.Total.ToInt64() * elementStride)
{
unsafe
{
return *((Int32*)Hierarchy.DataPointer.ToPointer() + offset);
}
}
else
{
return -1;
}
}
https://gist.github.com/joshuanapoli/8c3f282cece8340a1dd43aa5e80d170b
答案 1 :(得分:1)
EmguCV开始使用VectorOfVectorPoint for FindContours,但没有真正更新他们的代码以正常使用它。请参阅下面的工作示例:
/// <summary>
/// Find contours using the specific memory storage
/// </summary>
/// <param name="method">The type of approximation method</param>
/// <param name="type">The retrieval type</param>
/// <param name="stor">The storage used by the sequences</param>
/// <returns>
/// Contour if there is any;
/// null if no contour is found
/// </returns>
public static VectorOfVectorOfPoint FindContours(this Image<Gray, byte> image, ChainApproxMethod method = ChainApproxMethod.ChainApproxSimple,
Emgu.CV.CvEnum.RetrType type = RetrType.List) {
//Check that all parameters are valid.
VectorOfVectorOfPoint result = new VectorOfVectorOfPoint();
if (method == Emgu.CV.CvEnum.ChainApproxMethod.ChainCode) {
throw new ColsaNotImplementedException("Chain Code not implemented, sorry try again later");
}
CvInvoke.FindContours(image, result, null, type, method);
return result;
}
这将返回一个VectorOfVectorPoint,它实现了IInputOutputArray,IOutputArray,IInputArrayOfArrays和IInputArray。我不确定你需要对轮廓做什么,但这里有一个如何获取每个边界框的例子。我们做了其他一些事情,所以让我知道你需要什么,我可以帮助你。
VectorOfVectorOfPoint contours = canvass2.FindContours(ChainApproxMethod.ChainApproxSimple, RetrType.Tree);
int contCount = contours.Size;
for (int i = 0; i < contCount; i++) {
using (VectorOfPoint contour = contours[i]) {
segmentRectangles.Add(CvInvoke.BoundingRectangle(contour));
if (debug) {
finalCopy.Draw(CvInvoke.BoundingRectangle(contour), new Rgb(255, 0, 0), 5);
}
}
}
答案 2 :(得分:0)
您只需创建一个
即可矩阵
然后将Mat对象数据复制到该Matrix中。见下面的例子:
Mat hierarchy = new Mat();
CvInvoke.FindContours(imgThreshCopy, contours, hierarchy , RetrType.Tree,ChainApproxMethod.ChainApproxSimple);
Matrix<int> matrix = new Matrix<int>(hierarchy.Rows, hierarchy.Cols,hierarchy.NumberOfChannels);
hierarchy.CopyTo(matrix);
可以在
中访问数据