【问题标题】:vector<double> areas(contour.size()) in c#? mass of center, area. Particle Analyzec# 中的向量<double> 区域(contour.size())?质心,面积。粒子分析
【发布时间】:2020-01-03 11:02:37
【问题描述】:

您好,我想用 EmguCV 分析粒子。我使用它显然是因为我使用 C#。我发现一些代码似乎对我来说是完美的,但它是用 C++ 编写的,所以我试图让它在 C# 中运行。现在我被卡住了,因为我找不到与在 c# 中工作的代码类似的东西

另外我想告诉你我是一个菜鸟程序员,c#对我来说也是新的

这是 C++ 中的代码

Mat frame = imread("particles.png", CV_LOAD_IMAGE_GRAYSCALE);

threshold(frame, frame, 127, 255, THRESH_BINARY);

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours(frame, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

vector<double> areas(contours.size());

for (int i = 0; i < contours.size(); i++)
    areas[i] = contourArea(contours[i]);

vector<Point2d> mass_centres(contours.size());

for (int i = 0; i < contours.size(); i++)
{
    const Moments mu = moments(contours[i], false);
    mass_centres[i] = Point2d(mu.m10 / mu.m00, mu.m01 / mu.m00);
}

cout << "Num particles: " << contours.size() << endl;

for (int i = 0; i < contours.size(); i++)
    cout << "area " << (i + 1) << ": " << areas[i] << endl;

for (int i = 0; i < contours.size(); i++)
    cout << "centre " << (i + 1) << ": " << mass_centres[i].x << " " << mass_centres[i].y << endl;

return 0;

}

这就是我迄今为止用 C# 编写的内容

        Mat frame = CvInvoke.Imread(file2, ImreadModes.Grayscale);

        CvInvoke.Threshold(frame, frame, 127, 255, ThresholdType.Binary);

        Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint();

        Mat hierarchy = new Mat();

        CvInvoke.FindContours(frame, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);

现在我被困在这里,我现在不替代此代码:

vector<double> areas(contours.size());

for (int i = 0; i < contours.size(); i++)
    areas[i] = contourArea(contours[i]);

vector<Point2d> mass_centres(contours.size());

for (int i = 0; i < contours.size(); i++)
{
    const Moments mu = moments(contours[i], false);
    mass_centres[i] = Point2d(mu.m10 / mu.m00, mu.m01 / mu.m00);
}

【问题讨论】:

    标签: c# opencv emgucv opencvsharp


    【解决方案1】:

    您要查找的函数是CvInvoke.ContourAreaCvInvoke.Moments

    代码可以写成如下:

    List<double> areas = new List<double>();
    foreach(Emgu.CV.Util.VectorOfPoint contour in contours)
    {
        areas.Add(Emgu.CV.CvInvoke.ContourArea(contour));
    } 
    
    VectorOfPoint mass_centers = new VectorOfPoint();
    foreach(Emgu.CV.Util.VectorOfPoint contour in contours)
    {
        Emgu.CV.Structure.MCVMoments mu = Emgu.CV.CvInvoke.Moments(contour); 
        mass_centers.Push(Emgu.CV.Point2D<double>(mu.M10 / mu.M00, mu.M01 / mu.M00));
    } 
    

    希望这会有所帮助。

    【讨论】:

    • 非常感谢。我使用的是 EmguCV 版本 4,所以如果我复制/粘贴您的代码,编译器会发现错误。第一个在这里: ...contour in contours... //foreach 不能用于“VectorofVectorofPoints” 第二个是它无法识别 Emgu.CV.Point2D
    【解决方案2】:

    我用下面的代码解决了我的问题。

            double[] area = new double[contours.Size];
    
            for (int i = 0; i < contours.Size; i++)
            {
                area[i] = CvInvoke.ContourArea(contours[i]);
            }
    
    
            double[] mass_centerX = new double[contours.Size];
            double[] mass_centerY = new double[contours.Size];
    
    
            for (int i = 0; i < contours.Size; i++)
            {
                Moments mu = CvInvoke.Moments(contours[i], false);
    
                mass_centerX[i] = mu.M10 / mu.M00;
                mass_centerY[i] = mu.M01 / mu.M00;
    
                mass_centerX[i] = Math.Round(mass_centerX[i], 2);
                mass_centerY[i] = Math.Round(mass_centerY[i], 2);
    
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      相关资源
      最近更新 更多