Пример #1
0
        /// <summary>
        /// Change the position of the cube by rotating it on the given layer and the given direction
        /// </summary>
        /// <param name="layer">Defines the layer the cube is to rotate on</param>
        /// <param name="direction">Defines the direction of the rotation (true == clockwise)</param>
        public void NextPos(CubeFlag layer, bool direction)
        {
            Cube oldCube = DeepClone();

            Position.NextFlag(layer, direction);
            #region Colors
            if (this.IsCorner)
            {
                //Set colors
                Face  layerFace  = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(layer));
                Color layerColor = layerFace.Color;

                CubeFlag newFlag    = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, oldCube.Position.Flags);
                CubeFlag commonFlag = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, newFlag | layer);
                CubeFlag oldFlag    = CubeFlagService.FirstNotInvalidFlag(oldCube.Position.Flags, commonFlag | layer);

                Color colorNewPos    = Faces.First(f => f.Position == CubeFlagService.ToFacePosition(commonFlag)).Color;
                Color colorCommonPos = Faces.First(f => f.Position == CubeFlagService.ToFacePosition(oldFlag)).Color;

                ResetColors();
                SetFaceColor(layerFace.Position, layerColor);
                SetFaceColor(CubeFlagService.ToFacePosition(newFlag), colorNewPos);
                SetFaceColor(CubeFlagService.ToFacePosition(commonFlag), colorCommonPos);
            }

            if (this.IsCenter)
            {
                CubeFlag oldFlag     = CubeFlagService.FirstNotInvalidFlag(oldCube.Position.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
                Color    centerColor = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(oldFlag)).Color;
                CubeFlag newPos      = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, CubeFlag.MiddleSliceSides | CubeFlag.MiddleSlice | CubeFlag.MiddleLayer);

                ResetColors();
                SetFaceColor(CubeFlagService.ToFacePosition(newPos), centerColor);
            }

            if (this.IsEdge)
            {
                CubeFlag newFlag    = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, oldCube.Position.Flags | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | CubeFlag.MiddleLayer);
                CubeFlag commonFlag = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, newFlag | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | CubeFlag.MiddleLayer);
                CubeFlag oldFlag    = CubeFlagService.FirstNotInvalidFlag(oldCube.Position.Flags, commonFlag | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | CubeFlag.MiddleLayer);

                Color colorNewPos    = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(commonFlag)).Color;
                Color colorCommonPos = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(oldFlag)).Color;


                ResetColors();
                if (layer == CubeFlag.MiddleLayer || layer == CubeFlag.MiddleSlice || layer == CubeFlag.MiddleSliceSides)
                {
                    SetFaceColor(CubeFlagService.ToFacePosition(newFlag), colorNewPos);
                    SetFaceColor(CubeFlagService.ToFacePosition(commonFlag), colorCommonPos);
                }
                else
                {
                    SetFaceColor(CubeFlagService.ToFacePosition(commonFlag), colorNewPos);
                    SetFaceColor(CubeFlagService.ToFacePosition(newFlag), colorCommonPos);
                }
            }
            #endregion
        }
Пример #2
0
 public FacesViewModel(MediaFile photo, IEnumerable <DetectedFace> faces)
 {
     Faces        = faces.Select(f => new FaceViewModel(photo, f));
     SelectedFace = Faces.First();
 }
Пример #3
0
        /// <summary>
        /// Pick folder, then group detected faces by similarity
        /// </summary>
        /// <param name="sender">Event sender</param>
        /// <param name="e">Event arguments</param>
        private async void Grouping_Click(object sender, RoutedEventArgs e)
        {
            // Show folder picker
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            var result = dlg.ShowDialog();

            // Set the suggestion count is intent to minimum the data preparetion step only,
            // it's not corresponding to service side constraint
            const int SuggestionCount = 10;

            if (result == DialogResult.OK)
            {
                // User picked one folder
                List <Task> tasks         = new List <Task>();
                int         processCount  = 0;
                bool        forceContinue = false;

                // Clear previous grouping result
                GroupedFaces.Clear();
                Faces.Clear();

                Output = Output.AppendLine("Request: Preparing faces for grouping, detecting faces in choosen folder.");
                foreach (var img in Directory.EnumerateFiles(dlg.SelectedPath, "*.jpg", SearchOption.AllDirectories))
                {
                    tasks.Add(Task.Factory.StartNew(
                                  async(obj) =>
                    {
                        var imgPath = obj as string;

                        // Detect faces in image
                        using (var fStream = File.OpenRead(imgPath))
                        {
                            try
                            {
                                var faces = await App.Instance.DetectAsync(fStream);
                                return(new Tuple <string, ClientContract.Face[]>(imgPath, faces));
                            }
                            catch (ClientException)
                            {
                                // Here we simply ignore all detection failure in this sample
                                // You may handle these exceptions by check the Error.Code and Error.Message property for ClientException object
                                return(new Tuple <string, ClientContract.Face[]>(imgPath, null));
                            }
                        }
                    },
                                  img).Unwrap().ContinueWith((detectTask) =>
                    {
                        // Update detected faces on UI
                        var res = detectTask.Result;
                        if (res.Item2 == null)
                        {
                            return;
                        }

                        foreach (var f in res.Item2)
                        {
                            this.Dispatcher.Invoke(
                                new Action <ObservableCollection <Face>, string, ClientContract.Face>(UIHelper.UpdateFace),
                                Faces,
                                res.Item1,
                                f);
                        }
                    }));
                    if (processCount >= SuggestionCount && !forceContinue)
                    {
                        var continueProcess = System.Windows.Forms.MessageBox.Show("Found many images under choosen folder, may take long time if proceed. Continue?", "Warning", MessageBoxButtons.YesNo);
                        if (continueProcess == DialogResult.Yes)
                        {
                            forceContinue = true;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                await Task.WhenAll(tasks);

                Output = Output.AppendLine(string.Format("Response: Success. Total {0} faces are detected.", Faces.Count));

                try
                {
                    Output = Output.AppendLine(string.Format("Request: Grouping {0} faces.", Faces.Count));

                    // Call grouping, the grouping result is a group collection, each group contains similar faces
                    var groupRes = await App.Instance.GroupAsync(Faces.Select(f => Guid.Parse(f.FaceId)).ToArray());

                    // Update grouping results for rendering
                    foreach (var g in groupRes.Groups)
                    {
                        var gg = new GroupingResult()
                        {
                            Faces        = new ObservableCollection <Face>(),
                            IsMessyGroup = false,
                        };

                        foreach (var fr in g)
                        {
                            gg.Faces.Add(Faces.First(f => f.FaceId == fr.ToString()));
                        }

                        GroupedFaces.Add(gg);
                    }

                    // MessyGroup contains all faces which are not similar to any other faces.
                    // Take an extreme case for exampe:
                    // On grouping faces which are not similar to any other faces, the grouping result will contains only one messy group
                    if (groupRes.MessyGroup.Length > 0)
                    {
                        var messyGroup = new GroupingResult()
                        {
                            Faces        = new ObservableCollection <Face>(),
                            IsMessyGroup = true
                        };
                        foreach (var messy in groupRes.MessyGroup)
                        {
                            messyGroup.Faces.Add(Faces.First(f => f.FaceId == messy.ToString()));
                        }

                        GroupedFaces.Add(messyGroup);
                    }

                    Output = Output.AppendLine(string.Format("Response: Success. {0} faces are grouped into {1} groups.", Faces.Count, GroupedFaces.Count));
                }
                catch (ClientException ex)
                {
                    Output = Output.AppendLine(string.Format("Response: {0}. {1}", ex.Error.Code, ex.Error.Message));
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Pick folder, then group detected faces by similarity
        /// </summary>
        /// <param name="sender">Event sender</param>
        /// <param name="e">Event arguments</param>
        private async void Grouping_Click(object sender, RoutedEventArgs e)
        {
            // Show folder picker
            System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
            var result = dlg.ShowDialog();

            // Set the suggestion count is intent to minimum the data preparation step only,
            // it's not corresponding to service side constraint
            const int SuggestionCount = 10;

            if (result == System.Windows.Forms.DialogResult.OK)
            {
                // User picked one folder
                List <Task> tasks         = new List <Task>();
                int         processCount  = 0;
                bool        forceContinue = false;

                // Clear previous grouping result
                GroupedFaces.Clear();
                Faces.Clear();

                MainWindow mainWindow        = Window.GetWindow(this) as MainWindow;
                string     subscriptionKey   = mainWindow._scenariosControl.SubscriptionKey;
                string     endpoint          = mainWindow._scenariosControl.SubscriptionEndpoint;
                var        faceServiceClient = new FaceServiceClient(subscriptionKey, endpoint);

                MainWindow.Log("Request: Preparing faces for grouping, detecting faces in chosen folder.");

                var imageList =
                    new ConcurrentBag <string>(
                        Directory.EnumerateFiles(dlg.SelectedPath, "*.*", SearchOption.AllDirectories)
                        .Where(s => s.ToLower().EndsWith(".jpg") || s.ToLower().EndsWith(".png") || s.ToLower().EndsWith(".bmp") || s.ToLower().EndsWith(".gif")));

                string img;
                while (imageList.TryTake(out img))
                {
                    tasks.Add(Task.Factory.StartNew(
                                  async(obj) =>
                    {
                        var imgPath = obj as string;
                        // Detect faces in image
                        using (var fStream = File.OpenRead(imgPath))
                        {
                            try
                            {
                                var faces = await faceServiceClient.DetectAsync(fStream);
                                return(new Tuple <string, ClientContract.Face[]>(imgPath, faces));
                            }
                            catch (FaceAPIException ex)
                            {
                                // if operation conflict, retry.
                                if (ex.ErrorCode.Equals("ConcurrentOperationConflict"))
                                {
                                    imageList.Add(imgPath);
                                    return(null);
                                }
                                // Here we simply ignore all detection failure in this sample
                                // You may handle these exceptions by check the Error.Error.Code and Error.Message property for ClientException object
                                return(new Tuple <string, ClientContract.Face[]>(imgPath, null));
                            }
                        }
                    },
                                  img).Unwrap().ContinueWith((detectTask) =>
                    {
                        // Update detected faces on UI
                        var res = detectTask?.Result;
                        if (res?.Item2 == null)
                        {
                            return;
                        }

                        foreach (var f in res.Item2)
                        {
                            this.Dispatcher.Invoke(
                                new Action <ObservableCollection <Face>, string, ClientContract.Face>(UIHelper.UpdateFace),
                                Faces,
                                res.Item1,
                                f);
                        }
                    }));
                    if (processCount >= SuggestionCount && !forceContinue)
                    {
                        var continueProcess = System.Windows.Forms.MessageBox.Show("Found many images under chosen folder, may take long time if proceed. Continue?", "Warning", System.Windows.Forms.MessageBoxButtons.YesNo);
                        if (continueProcess == System.Windows.Forms.DialogResult.Yes)
                        {
                            forceContinue = true;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (tasks.Count >= _maxConcurrentProcesses || imageList.IsEmpty)
                    {
                        await Task.WhenAll(tasks);

                        tasks.Clear();
                    }
                }

                MainWindow.Log("Response: Success. Total {0} faces are detected.", Faces.Count);

                try
                {
                    MainWindow.Log("Request: Grouping {0} faces.", Faces.Count);

                    // Call grouping, the grouping result is a group collection, each group contains similar faces
                    var groupRes = await faceServiceClient.GroupAsync(Faces.Select(f => Guid.Parse(f.FaceId)).ToArray());

                    // Update grouping results for rendering
                    foreach (var g in groupRes.Groups)
                    {
                        var gg = new GroupingResult()
                        {
                            Faces        = new ObservableCollection <Face>(),
                            IsMessyGroup = false,
                        };

                        foreach (var fr in g)
                        {
                            gg.Faces.Add(Faces.First(f => f.FaceId == fr.ToString()));
                        }

                        GroupedFaces.Add(gg);
                    }

                    // MessyGroup contains all faces which are not similar to any other faces.
                    // Take an extreme case for example:
                    // On grouping faces which are not similar to any other faces, the grouping result will contains only one messy group
                    if (groupRes.MessyGroup.Length > 0)
                    {
                        var messyGroup = new GroupingResult()
                        {
                            Faces        = new ObservableCollection <Face>(),
                            IsMessyGroup = true
                        };
                        foreach (var messy in groupRes.MessyGroup)
                        {
                            messyGroup.Faces.Add(Faces.First(f => f.FaceId == messy.ToString()));
                        }

                        GroupedFaces.Add(messyGroup);
                    }

                    MainWindow.Log("Response: Success. {0} faces are grouped into {1} groups.", Faces.Count, GroupedFaces.Count);
                }
                catch (FaceAPIException ex)
                {
                    MainWindow.Log("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage);
                }
            }
            GC.Collect();
        }