private void SplitImageAdditionalThread(object parameter) { SplitImageThreadParameter input = parameter as SplitImageThreadParameter; if (input == null) { throw new ArgumentException("Неправильный формат потока"); } int fragmentSize = RecognitionParameters.RecognitionFragmentSize; var image = input.Image; var regions = input.ResultRegions; var samples = input.ResultSamples; int XCount = image.Width / fragmentSize; int YCount = image.Height / fragmentSize; if (XCount * fragmentSize < image.Width) { for (int y = 0; (y < YCount) && (!isRecognizingAborted); ++y) { int fromX = image.Width - fragmentSize; int fromY = y * fragmentSize; int toX = image.Width; int toY = fromY + fragmentSize; TextureSample sample = null; try { var imageData = image.GetGrayData(fromX, fromY, toX, toY); sample = new TextureSample(imageData, false); } catch (Exception ex) { if (MessageBox.Show("Возникла ошибка. Продолжать?\n" + ex.Message, "Внимание", MessageBoxButtons.YesNo) == DialogResult.No) { isRecognizingAborted = true; } else { continue; } } lock ((regions as ICollection).SyncRoot) { regions.Add(new Rectangle(fromX, fromY, fragmentSize, fragmentSize)); samples.Add(sample); } } } if (YCount * fragmentSize < image.Height) { for (int x = 0; (x < XCount) && (!isRecognizingAborted); ++x) { int fromX = x * fragmentSize; int fromY = image.Height - fragmentSize; int toX = fromX + fragmentSize; int toY = image.Height; TextureSample sample = null; try { var imageData = image.GetGrayData(fromX, fromY, toX, toY); sample = new TextureSample(imageData, false); } catch (Exception ex) { if (MessageBox.Show("Возникла ошибка. Продолжать?\n" + ex.Message, "Внимание", MessageBoxButtons.YesNo) == DialogResult.No) { isRecognizingAborted = true; } else { continue; } } lock ((regions as ICollection).SyncRoot) { regions.Add(new Rectangle(fromX, fromY, fragmentSize, fragmentSize)); samples.Add(sample); } } } if ((XCount * fragmentSize < image.Width) || (YCount * fragmentSize < image.Height) && (!isRecognizingAborted)) { int fromX = image.Width - fragmentSize; int fromY = image.Height - fragmentSize; int toX = image.Width; int toY = image.Height; TextureSample sample = null; try { var imageData = image.GetGrayData(fromX, fromY, toX, toY); sample = new TextureSample(imageData, false); } catch (Exception ex) { if (MessageBox.Show("Возникла ошибка. Продолжать?\n" + ex.Message, "Внимание", MessageBoxButtons.YesNo) == DialogResult.No) { isRecognizingAborted = true; } } lock ((regions as ICollection).SyncRoot) { regions.Add(new Rectangle(fromX, fromY, fragmentSize, fragmentSize)); samples.Add(sample); } } input.ResetEvent.Set(); }
private void SplitImage(SimpleImage image, List<TextureSample> samples, List<Rectangle> regions) { int YCount = image.Height / RecognitionParameters.RecognitionFragmentSize; int threadCount = Math.Min(YCount, Environment.ProcessorCount * 2); int threadPart = YCount / threadCount; var resetEvents = new ManualResetEvent[threadCount + 1]; var threadParameters = new SplitImageThreadParameter[threadCount + 1]; for (int i = 0; i < threadCount; ++i) { resetEvents[i] = new ManualResetEvent(false); threadParameters[i] = new SplitImageThreadParameter( image, threadPart * i, ((i + 1) < threadCount) ? (threadPart * (i + 1)) : (YCount), regions, samples, resetEvents[i]); ThreadPool.QueueUserWorkItem(new WaitCallback(SplitImageThread), threadParameters[i]); } resetEvents[threadCount] = new ManualResetEvent(false); threadParameters[threadCount] = new SplitImageThreadParameter( image, 0, 0, regions, samples, resetEvents[threadCount]); ThreadPool.QueueUserWorkItem(new WaitCallback(SplitImageAdditionalThread), threadParameters[threadCount]); WaitHandle.WaitAll(resetEvents); }