将for循环转换为并行循环

Pay*_*yam 3 c# parallel-processing for-loop

我编写了一个计算图像焦点值的代码.但这需要5秒多的时间才能完成.

 public double GetFValue(Image image)
        {
            Bitmap source = new Bitmap(image);
            int count = 0;
            double total = 0;
            double totalVariance = 0;
            double FM = 0;
             Bitmap bm = new Bitmap(source.Width, source.Height);
             Rectangle rect = new Rectangle(0,0,source.Width,source.Height);
              Bitmap targetRect = new Bitmap(rect.Width, rect.Height);

            // converting to grayscale
            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < source.Width; x++)
                {
                    count++;
                    Color c = source.GetPixel(x, y);
                    int luma = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
                    source.SetPixel(x, y, Color.FromArgb(luma, luma, luma)); // the image is now gray scaled 
                    var pixelval = source.GetPixel(x, y);
                  //  targetRect.Save(@"C:\Users\payam\Desktop\frame-42-rectangle.png", System.Drawing.Imaging.ImageFormat.Png);
                    int pixelValue = pixelval.G;
                    total += pixelValue;
                    double avg = total / count;
                    totalVariance += Math.Pow(pixelValue - avg, 2);
                    double stDV = Math.Sqrt(totalVariance / count); // the standard deviation, which is also the focus value
                    FM = Math.Round(stDV, 2);
                }
            }
            return FM;
        }
Run Code Online (Sandbox Code Playgroud)

我试图将此代码转换为并行计算.我最终得到了一些我无法理解他们的错误.有什么建议吗?

  public double CalculateFvalue (Image image)
    {
        Bitmap myimage = new Bitmap(image);
        int count = 0;
        int total = 0;
        double totalVariance = 0;
        double FM = 0;
        Parallel.For(0, image.Height, y =>
            {

            for (int x = 0; x < myimage.Width; x++)
                   {
                           count++;
                           Color c = myimage.GetPixel(x, y);
                           int luma = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
                           myimage.SetPixel(x, y, Color.FromArgb(luma, luma, luma)); // the image is now gray scaled 
                           var pixelval = myimage.GetPixel(x, y);
                           int pixelValue = pixelval.G;
                           total += pixelValue;
                           double avg = total / count;
                           totalVariance += Math.Pow(pixelValue - avg, 2);
                           double stDV = Math.Sqrt(totalVariance / count); // the standard deviation, which is also the focus value
                           FM = Math.Round(stDV, 2);
                   }


    });

        return Math.Round(FM,2);
    }
Run Code Online (Sandbox Code Playgroud)

Mir*_*Mir 7

这是因为您在范围之外声明的变量Parallel.For.由于它们的访问(和写入)是非确定性的,因此可能会使用错误的数据(例如FM)覆盖值.

我建议你让每次迭代产生关于其结果的信息,然后使用收集的数据以线程安全的方式操纵你的变量.您也可以通过使用一些lock语句来逃避它,但我个人会避免这种情况.