public override bool Equals(object obj)
        {
            EMPatch patch = obj as EMPatch;

            if (patch == null)
            {
                return(false);
            }
            else
            {
                return(patch.X == this.X && patch.Y == this.Y);
            }
        }
        public GaussianMixtureModel PatchGaussianMixtureModelFromPoint(System.Windows.Point imagePoint)
        {
            if (!workCompleted)
            {
                throw new EMWorkNotCompletedException("Cannot obtain mixture data before E-M work has been completed");
            }

            int patchX = (int)imagePoint.X / this.Configuration.PatchSize;
            int patchY = (int)imagePoint.Y / this.Configuration.PatchSize;
            int left   = patchX * this.Configuration.PatchSize;
            int top    = patchY * this.Configuration.PatchSize;
            int right  = Math.Min(left + this.Configuration.PatchSize, this.Width);
            int bottom = Math.Min(top + this.Configuration.PatchSize, this.Height);

            // Obtain mixture model for current patch
            EMPatch key = new EMPatch(patchX, patchY, left, right, top, bottom);

            return(this.Mixtures[key]);
        }
        public int[] PatchHistogramDataFromPoint(System.Windows.Point imagePoint)
        {
            if (!workCompleted)
            {
                throw new EMWorkNotCompletedException("Cannot obtain intensity data before E-M work has been completed");
            }

            int patchX = (int)imagePoint.X / this.Configuration.PatchSize;
            int patchY = (int)imagePoint.Y / this.Configuration.PatchSize;
            int left   = patchX * this.Configuration.PatchSize;
            int top    = patchY * this.Configuration.PatchSize;
            int right  = Math.Min(left + this.Configuration.PatchSize, this.Width);
            int bottom = Math.Min(top + this.Configuration.PatchSize, this.Height);

            // Obtain mixture model for current patch
            EMPatch key = new EMPatch(patchX, patchY, left, right, top, bottom);

            // Obtain intensity data for current patch
            int[] histogramData = key.CreateHistogram(this.IntensityBuffer, this.Width, this.Height);

            return(histogramData);
        }
        public void Run()
        {
            // Create thread workers
            currentWorkers          = new List <EMWorker>();
            currentWorkersCompleted = new List <bool>();
            currentWorkersProgress  = new List <int>();
            currentProgress         = 0;
            for (int worker = 0; worker < ThreadCount; worker++)
            {
                EMWorker thread = new EMWorker();
                thread.ProgressChanged    += new ProgressChangedEventHandler(OnWorkerProgressChanged);
                thread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(OnWorkerProgressCompleted);
                currentWorkers.Add(thread);
                currentWorkersCompleted.Add(false);
                currentWorkersProgress.Add(0);
            }

            // Create data objects for workers
            List <List <EMPatch> > workerPatches = new List <List <EMPatch> >();

            for (int t = 0; t < ThreadCount; t++)
            {
                workerPatches.Add(new List <EMPatch>());
            }

            // Patch size
            int patchArrayWidth  = (int)Math.Ceiling(Width / (double)Configuration.PatchSize);
            int patchArrayHeight = (int)Math.Ceiling(Height / (double)Configuration.PatchSize);

            int currentThreadIndex = 0;

            for (int patchX = 0; patchX < patchArrayWidth; patchX++)
            {
                for (int patchY = 0; patchY < patchArrayHeight; patchY++)
                {
                    // Calculate bounding box of the patch
                    int left   = patchX * Configuration.PatchSize;
                    int top    = patchY * Configuration.PatchSize;
                    int right  = Math.Min(left + Configuration.PatchSize, Width);
                    int bottom = Math.Min(top + Configuration.PatchSize, Height);

                    // Create a new EMPatch
                    EMPatch patch = new EMPatch(patchX, patchY, left, right, top, bottom);

                    // Assign patch to a worker thread
                    workerPatches[currentThreadIndex].Add(patch);
                    currentThreadIndex = (currentThreadIndex + 1) % ThreadCount;
                }
            }

            // Launch workers
            for (int worker = 0; worker < currentWorkers.Count; worker++)
            {
                currentWorkers[worker].IntensityBuffer = IntensityBuffer;
                currentWorkers[worker].Patches         = workerPatches[worker];
                currentWorkers[worker].Width           = this.Width;
                currentWorkers[worker].Height          = this.Height;
                currentWorkers[worker].Configuration   = this.Configuration;
                currentWorkers[worker].RunWorkerAsync();
            }
        }