Exemple #1
0
        /// <summary>
        /// Clear blobs structure. (cvReleaseBlobs)
        /// </summary>
        /// <param name="blobs">List of blobs.</param>
        public static void ReleaseBlobs(CvBlobs blobs)
        {
            if (blobs == null)
                throw new ArgumentNullException("blobs");

            blobs.Dispose();
        }
Exemple #2
0
        //##############################################################################################################################################################################################

        /// <summary>
        /// Extract all pieces from the source image.
        /// </summary>
        private void extract_pieces()
        {
            try
            {
                CurrentSolverState = PuzzleSolverState.INIT_PIECES;
                Piece.NextPieceID  = 0;
                CurrentSolverStepPercentageFinished = 0;
                _logHandle.Report(new LogEventInfo("Extracting Pieces"));
                NumberPuzzlePieces = 0;

                Pieces.Clear();
                InputImages.Clear();

                List <string> imageExtensions = new List <string>()
                {
                    ".jpg", ".png", ".bmp", ".tiff"
                };
                FileAttributes  attr           = File.GetAttributes(PuzzlePiecesFolderPath);
                List <FileInfo> imageFilesInfo = new List <FileInfo>();
                if (attr.HasFlag(FileAttributes.Directory))      //detect whether its a directory or file
                {
                    DirectoryInfo folderInfo = new DirectoryInfo(PuzzlePiecesFolderPath);
                    imageFilesInfo = folderInfo.GetFiles().ToList();
                }
                else
                {
                    FileInfo fileInfo = new FileInfo(PuzzlePiecesFolderPath);
                    imageFilesInfo.Add(fileInfo);
                }

                imageFilesInfo = imageFilesInfo.Where(f => imageExtensions.Contains(f.Extension)).ToList();

                int loopCount = 0;

                ParallelOptions parallelOptions = new ParallelOptions
                {
                    CancellationToken      = _cancelToken,
                    MaxDegreeOfParallelism = (PluginFactory.GetGeneralSettingsPlugin().UseParallelLoops ? Environment.ProcessorCount : 1)
                };
                //For each input image
                Parallel.For(0, imageFilesInfo.Count, parallelOptions, (i) =>
                {
                    using (Image <Rgba, byte> sourceImg = new Image <Rgba, byte>(imageFilesInfo[i].FullName)) //.LimitImageSize(1000, 1000))
                    {
                        CvInvoke.MedianBlur(sourceImg, sourceImg, 5);

                        // Get the (first) enabled Plugin for input image mask generation
                        PluginGroupInputImageMask pluginInputImageMask = PluginFactory.GetEnabledPluginsOfGroupType <PluginGroupInputImageMask>().FirstOrDefault();

                        using (Image <Gray, byte> mask = pluginInputImageMask.GetMask(sourceImg))
                        {
                            _logHandle.Report(new LogEventInfo("Extracting Pieces from source image " + i.ToString()));
                            if (PluginFactory.GetGeneralSettingsPlugin().SolverShowDebugResults)
                            {
                                _logHandle.Report(new LogEventImage("Source image " + i.ToString(), sourceImg.Bitmap));
                                _logHandle.Report(new LogEventImage("Mask " + i.ToString(), mask.Bitmap));
                            }

                            CvBlobDetector blobDetector = new CvBlobDetector();                 // Find all blobs in the mask image, extract them and add them to the list of pieces
                            CvBlobs blobs = new CvBlobs();
                            blobDetector.Detect(mask, blobs);

                            foreach (CvBlob blob in blobs.Values.Where(b => b.BoundingBox.Width >= PluginFactory.GetGeneralSettingsPlugin().PuzzleMinPieceSize&& b.BoundingBox.Height >= PluginFactory.GetGeneralSettingsPlugin().PuzzleMinPieceSize))
                            {
                                if (_cancelToken.IsCancellationRequested)
                                {
                                    _cancelToken.ThrowIfCancellationRequested();
                                }

                                Rectangle roi = blob.BoundingBox;

                                Image <Rgba, byte> pieceSourceImg;
                                Image <Gray, byte> pieceMask;

                                try
                                {
                                    if (sourceImg.Height > roi.Height + 4 && sourceImg.Width > roi.Width + 4)
                                    {
                                        roi.Inflate(2, 2);
                                    }
                                    pieceSourceImg = sourceImg.Copy(roi);
                                    pieceMask      = mask.Copy(roi);
                                }
                                catch (Exception)
                                {
                                    roi            = blob.BoundingBox;
                                    pieceSourceImg = sourceImg.Copy(roi);
                                    pieceMask      = mask.Copy(roi);
                                }

                                // Mask out background of piece
                                Image <Rgba, byte> pieceSourceImageForeground = new Image <Rgba, byte>(pieceSourceImg.Size);
                                CvInvoke.BitwiseOr(pieceSourceImg, pieceSourceImg, pieceSourceImageForeground, pieceMask);

                                Image <Gray, byte> pieceMaskInverted = pieceMask.Copy(pieceMask);
                                pieceMaskInverted._Not();
                                Image <Rgba, byte> background = new Image <Rgba, byte>(pieceSourceImg.Size);
                                background.SetValue(new Rgba(255, 255, 255, 0));
                                Image <Rgba, byte> pieceSourceImageBackground = new Image <Rgba, byte>(pieceSourceImg.Size);
                                CvInvoke.BitwiseOr(background, background, pieceSourceImageBackground, pieceMaskInverted);

                                Image <Rgba, byte> pieceSourceImgMasked = new Image <Rgba, byte>(pieceSourceImg.Size);
                                CvInvoke.BitwiseOr(pieceSourceImageForeground, pieceSourceImageBackground, pieceSourceImgMasked);

                                Piece p = new Piece(pieceSourceImgMasked, pieceMask, imageFilesInfo[i].FullName, roi.Location, _logHandle, _cancelToken);
                                lock (_piecesLock) { Pieces.Add(p); }

                                sourceImg.Draw(roi, new Rgba(255, 0, 0, 1), 2);
                                int baseLine  = 0;
                                Size textSize = CvInvoke.GetTextSize(p.PieceID.Replace("Piece", ""), FontFace.HersheyDuplex, 3, 2, ref baseLine);
                                CvInvoke.PutText(sourceImg, p.PieceID.Replace("Piece", ""), Point.Add(roi.Location, new Size(0, textSize.Height + 10)), FontFace.HersheyDuplex, 3, new MCvScalar(255, 0, 0), 2);

                                NumberPuzzlePieces++;

                                pieceSourceImg.Dispose();
                                pieceMask.Dispose();
                                pieceSourceImageForeground.Dispose();
                                pieceMaskInverted.Dispose();
                                background.Dispose();
                                pieceSourceImageBackground.Dispose();
                                pieceSourceImgMasked.Dispose();

                                GC.Collect();
                            }

                            Interlocked.Add(ref loopCount, 1);
                            CurrentSolverStepPercentageFinished = (loopCount / (double)imageFilesInfo.Count) * 100;

                            if (PluginFactory.GetGeneralSettingsPlugin().SolverShowDebugResults)
                            {
                                _logHandle.Report(new LogEventImage("Source Img " + i.ToString() + " Pieces", sourceImg.Bitmap));
                            }
                            InputImages.Add(new ImageDescribedLight(Path.GetFileName(imageFilesInfo[i].FullName), PuzzlePiecesFolderPath + @"\Results\InputImagesMarked\" + Path.GetFileName(imageFilesInfo[i].FullName), sourceImg.Bitmap)); //sourceImg.LimitImageSize(1000, 1000).Bitmap));
                            blobs.Dispose();
                            blobDetector.Dispose();
                            GC.Collect();
                        }
                    }

                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                });

                Pieces.Sort(p => ((Piece)p).PieceIndex, null);
            }
            catch (OperationCanceledException)
            {
                _logHandle.Report(new LogEventWarning("The operation was canceled. Step: " + CurrentSolverState.ToString()));
                CurrentSolverState = PuzzleSolverState.UNSOLVED;
            }
            catch (Exception ex)
            {
                _logHandle.Report(new LogEventError("The following error occured in step " + CurrentSolverState.ToString() + ":\n" + ex.Message));
                CurrentSolverState = PuzzleSolverState.ERROR;
                CurrentSolverStepPercentageFinished = 100;
            }
        }