简体   繁体   中英

How to use Parallel.For for image processing in C#?

I'm processing some images in a for loop based on the number of ROI's present in an image. But if I have 4 ROI's the for loop processes the 4 ROI's one after the other like its supposed to, which is time consuming as my processing takes time. I have read that there is a parallel for loop in C# which can process all 4 ROI's(conditions) together. I tried but unable to understand how to use it. My current for loop code is:

   for(int i = 0; i < imgROIcount; i++)
       {
         Image<Gray, byte> processimg = temp.Clone();
         if (cbThreshold == 1)
             {
                if (txttype.text == "Auto")
                   {
                      CvInvoke.Threshold(processimg , processimg , 0, 255, ThresholdType.Otsu);                        
                   }
                else if (txttype.text == "Manual")
                   {
                       processimg = processimg .ThresholdBinary(new Gray(this.tbocrthreshold.Value), new Gray(255));
                   }
             }
        }

I tried:

    Parallel.For(0, imgROIcount, i => {
         Image<Gray, byte> processimg = temp.Clone();
         if (cbThreshold == 1)
             {
                if (txttype.text == "Auto")
                   {
                      CvInvoke.Threshold(processimg , processimg , 0, 255, ThresholdType.Otsu);                        
                   }
                else if (txttype.text == "Manual")
                   {
                       processimg = processimg .ThresholdBinary(new Gray(this.tbocrthreshold.Value), new Gray(255));
                   }
             }
         });

But it does not run, the whole method is shown in green and then the application exits on continuing.

I think you have a cross-thread processing issue. Store the values from the UI, such as txttype.Text into local variables before calling Paralle.For() .

string tt = txttype.Text;
var tcr = this.tbocrthreshold.Value;

Parallel.For(0, imgROIcount, i => {
     Image<Gray, byte> processimg = temp.Clone();
     if (cbThreshold == 1)
         {
            if (tt == "Auto")
               {
                  CvInvoke.Threshold(processimg , processimg , 0, 255, ThresholdType.Otsu);                        
               }
            else if (tt == "Manual")
               {
                   processimg = processimg .ThresholdBinary(new Gray(tcr), new Gray(255));
               }
         }
     });

and so on for the remaining values accessed inside the loop. Since it is run on separate threads it cannot access any UI values directly. Best to keep local values before the loop starts and use only local variables inside the loop.

PS. Keep with naming conventions in terms of capitalizations (Methods and Properties start with capital letters) and fields and variables with lower case. This helps us understand what is what. For example txttype.Text vs. txttype.text

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM