Alisha
Alisha

Reputation: 98

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.

Upvotes: 0

Views: 214

Answers (1)

John Alexiou
John Alexiou

Reputation: 29244

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

Upvotes: 2

Related Questions