private async void SeamCarve()
        {
            _isCarving = true;

            try
            {
                var optimizeMode = CarveWidth ? OptimizeMode.Width : OptimizeMode.Height;
                var imageMatrix  = ImageMatrixFactory.FromBitmapSource(InputImage, optimizeMode);

                var optimizedEnergyMatrix = ImageMatrixFactory.Empty <byte>(_energyMatrix.Width, _energyMatrix.Height, optimizeMode);
                for (var x = 0; x < _energyMatrix.Width; x++)
                {
                    for (var y = 0; y < _energyMatrix.Height; y++)
                    {
                        optimizedEnergyMatrix[x, y] = _energyMatrix[x, y];
                    }
                }

                var seamCarve = new SeamCarving(imageMatrix, optimizedEnergyMatrix);

                var direction        = CarveWidth ? Direction.Width : Direction.Height;
                var dimensionCount   = CarveWidth ? imageMatrix.Width : imageMatrix.Height;
                var pixelRemoveCount = dimensionCount - DimensionPixels;

                var resultImage = await Task.Run(() =>
                {
                    for (var i = 0; i < pixelRemoveCount; i++)
                    {
                        seamCarve.CarveSingle(direction);
                    }
                    return(seamCarve.ImageMatrix.ToBitmapSource());
                });

                OutputImage = resultImage;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                _isCarving = false;
                ((RelayCommand)SeamCarveCommand).RaiseCanExecuteChanged();
            }
        }
        private async void OpenImage()
        {
#if DEBUG
            var file = @"D:\test.jpg";
#else
            var dialog = new OpenFileDialog
            {
                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                DefaultExt       = ".jpeg",
                Filter           = "Image files|*.jpg;*.jpeg;*.png;*.gif|All files (*.*)|*.*"
            };

            var dialogResult = dialog.ShowDialog();

            if (dialogResult != true)
            {
                return;
            }
            var file = dialog.FileName;
#endif

            _isLoading = true;
            try
            {
                var image = await Task.Run(() =>
                {
                    using (var fileStream = File.Open(file, FileMode.Open))
                    {
                        var img = new BitmapImage();
                        img.BeginInit();
                        img.CacheOption  = BitmapCacheOption.OnLoad;
                        img.StreamSource = fileStream;
                        img.EndInit();
                        img.Freeze();

                        return(img);
                    }
                });

                InputImage  = image;
                OutputImage = image;

                var imageMatrix          = ImageMatrixFactory.FromBitmapSource(InputImage, OptimizeMode.Width);
                var grayscaleImageMatrix = ImageMatrixFactory.Empty <byte>(imageMatrix.Width, imageMatrix.Height, imageMatrix.OptimizeMode);
                imageMatrix.ToGrayScale(grayscaleImageMatrix);
                var energyMatrix = ImageMatrixFactory.Empty <byte>(imageMatrix.Width, imageMatrix.Height, imageMatrix.OptimizeMode);
                SeamCarvingHelper.ComputeEnergyMapBySobel(grayscaleImageMatrix, energyMatrix);

                _energyMatrix               = energyMatrix;
                EnergyFunctionImage         = energyMatrix.ToBitmapSource();
                EnergyFunctionWithBiasImage = EnergyFunctionImage;

                InputImageInfoStr = $"Width: {image.PixelWidth}, Height: {image.PixelHeight}";

                DimensionPixels = CarveWidth ? image.PixelWidth : image.PixelHeight;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                _isLoading = false;
                ((RelayCommand)OpenImageCommand).RaiseCanExecuteChanged();
            }
        }