예제 #1
0
        // Todo: prevFile isn't necessary. Instead store the features of the current scan to be used on the next.
        // That could cause sync problems so it needs to be investigated.
        private void NewRun(Scan scan, int index)
        {
            var deltas            = new double[CompiledFeatures.FeatureCount];
            var benchmarks        = new double[CompiledFeatures.FeatureCount];
            var now               = scan.CurrentFrame.DateTime;
            var fileImageBase     = scan.CurrentFrame.Bitmap;
            var prevFileImageBase = CompiledFeatures.UsesDupeCheck(now) ? scan.PreviousFrame.Bitmap : null;

            try
            {
                foreach (var cWatchZone in CompiledFeatures.CWatchZones)
                {
                    CropScan(ref deltas, ref benchmarks, now, fileImageBase, prevFileImageBase, cWatchZone);
                }
            }
            catch (Exception e)
            {
                scan.Dispose();
                Log.Error(e, "Error scanning frame.");
                if (IsVideoSourceRunning() && !IsScannerLocked)
                {
                    ScanningCount--;
                }
            }

            var scanEnd = TimeStamp.CurrentDateTime.Time;

            try
            {
                DeltaManager?.AddResult(index, scan, scanEnd, deltas, benchmarks);
                NewResult(this, new DeltaOutput(DeltaManager, index, CurrentFPS));

                ScanningCount--;

                if (ScanFinished != null)
                {
                    ScanFinished(this, scan);
                }

                //scan.Dispose();

                // It's on its own thread so running it here should be okay.
                if (index % Math.Ceiling(AverageFPS) == 0)
                {
                    RefreshBenchmarks();
                }

                if (index >= DeltaManager.History.Count && AverageFPS > 70d)
                {
                    Log.Warning("Framerate is abnormally high, usually an indicator the video feed is not active.");
                    Restart();
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Unknown Scanner Error.");
            }
        }
예제 #2
0
        // @TODO: Break into separate methods?
        private async void RefreshThumbnailAsync(Scan scan, PreviewType previewType, PreviewFeature feature)
        {
            await Task.Delay(0);

            try
            {
                Geometry    minGeo;
                MagickImage mi;
                string      confidence = string.Empty;
                Geometry    cropGeo    = _CropGeometry;

                if (previewType == PreviewType.FullFrame)
                {
                    minGeo = Geometry.Min(_VideoGeometry, GetScaledGeometry(_VideoGeometry));
                    mi     = new MagickImage(scan.CurrentFrame.Bitmap);

                    if (!_Selecting)
                    {
                        var roundGeo = cropGeo.Round();
                        mi.Composite(_ScreenOverlay, (int)roundGeo.X, (int)roundGeo.Y, CompositeOperator.Over);
                    }
                    else
                    {
                        var numRect = NumGeometry.ToRectangle();
                        using (var overlay = new MagickImage(SCREEN_COLOR, numRect.Width, numRect.Height))
                        {
                            mi.Composite(overlay, numRect.X, numRect.Y, CompositeOperator.Over);
                        }
                    }
                }
                else if (previewType == PreviewType.FrameCrop)
                {
                    minGeo = Geometry.Min(cropGeo, GetScaledGeometry(cropGeo));
                    if (!_VideoGeometry.Contains(cropGeo))
                    {
                        mi = new MagickImage(scan.CurrentFrame.Bitmap);
                        mi.Extent(cropGeo.ToMagick(), STANDARD_GRAVITY, EXTENT_COLOR);
                    }
                    else
                    {
                        mi = new MagickImage(scan.CurrentFrame.Bitmap.Clone(cropGeo.ToRectangle(), PixelFormat.Format24bppRgb));
                    }

                    if (!_Selecting)
                    {
                        var roundGeo     = cropGeo.Round();
                        var roundTrueGeo = _TrueCropGeometry.Round();
                        int xOffset      = (int)(roundTrueGeo.X - cropGeo.X);
                        int yOffset      = (int)(roundTrueGeo.Y - cropGeo.Y);
                        mi.Composite(_WatchZoneOverlay, xOffset, yOffset, CompositeOperator.Over);
                    }
                }
                else if (previewType == PreviewType.Features && feature == null)
                {
                    var trueGeo = _TrueCropGeometry;

                    minGeo = Geometry.Min(trueGeo, GetScaledGeometry(trueGeo));
                    if (!_VideoGeometry.Contains(trueGeo))
                    {
                        mi = new MagickImage(scan.CurrentFrame.Bitmap);
                        mi.Extent(trueGeo.ToMagick(), STANDARD_GRAVITY, EXTENT_COLOR);
                    }
                    else
                    {
                        mi = new MagickImage(scan.CurrentFrame.Bitmap.Clone(trueGeo.ToRectangle(), PixelFormat.Format24bppRgb));
                    }

                    if (!_Selecting)
                    {
                        mi.Composite(_WatchZoneOverlay, CompositeOperator.Over);
                    }
                }
                else if (previewType == PreviewType.Features && feature != null)
                {
                    var wzGeo = feature.WatchZone.Geometry;

                    if (!ckbShowComparison.Checked)
                    {
                        var baseMGeo = new MagickGeometry(64, 64, (int)Math.Round(wzGeo.Width), (int)Math.Round(wzGeo.Height));

                        wzGeo.Adjust(-64, -64, 128, 128);

                        minGeo = Geometry.Min(wzGeo, GetScaledGeometry(wzGeo));
                        if (!_VideoGeometry.Contains(wzGeo))
                        {
                            mi = new MagickImage(scan.CurrentFrame.Bitmap);
                            mi.Extent(wzGeo.ToMagick(), STANDARD_GRAVITY, EXTENT_COLOR);
                        }
                        else
                        {
                            mi = new MagickImage(scan.CurrentFrame.Bitmap.Clone(wzGeo.ToRectangle(), PixelFormat.Format24bppRgb));
                        }

                        using (var baseM = new MagickImage(
                                   MagickColors.Transparent,
                                   baseMGeo.Width,
                                   baseMGeo.Height))
                            using (var overlay = new MagickImage(
                                       PREVIEW_EXTENT_COLOR,
                                       baseMGeo.Width + 128,
                                       baseMGeo.Height + 128))
                            {
                                overlay.Composite(baseM, new PointD(baseMGeo.X, baseMGeo.Y), CompositeOperator.Alpha);
                                mi.Composite(overlay, CompositeOperator.Atop);
                            }
                    }
                    else
                    {
                        minGeo = Geometry.Min(wzGeo, GetScaledGeometry(wzGeo));
                        if (!_VideoGeometry.Contains(wzGeo))
                        {
                            mi = new MagickImage(scan.CurrentFrame.Bitmap);
                            mi.Extent(wzGeo.ToMagick(), STANDARD_GRAVITY, EXTENT_COLOR);
                        }
                        else
                        {
                            mi = new MagickImage(scan.CurrentFrame.Bitmap.Clone(wzGeo.ToRectangle(), PixelFormat.Format24bppRgb));
                        }

                        // @TODO: Add previous frame stuff
                        using (var deltaImage = feature.WatchImage.MagickImage.Clone())
                        {
                            mi.ColorSpace         = feature.Watcher.ColorSpace;
                            deltaImage.ColorSpace = feature.Watcher.ColorSpace;
                            if (feature.WatchImage.HasAlpha)
                            {
                                mi.Composite(feature.WatchImage.AlphaChannel, CompositeOperator.Over);
                            }
                            if (feature.Watcher.Equalize)
                            {
                                mi.Equalize();
                            }
                            confidence = mi.Compare(deltaImage, feature.Watcher.ErrorMetric).ToString("F4");
                            mi.Composite(deltaImage, CompositeOperator.Difference);
                        }
                    }
                }
                else
                {
                    throw new InvalidEnumArgumentException("PreviewType out of bounds? This shouldn't happen.");
                }

                var drawingSize = minGeo.Size.ToDrawing();
                if (mi.Width > drawingSize.Width || mi.Height > drawingSize.Height)
                {
                    var mGeo = minGeo.ToMagick();
                    mGeo.IgnoreAspectRatio = false;
                    //mi.ColorSpace = ColorSpace.HCL;
                    mi.FilterType = DEFAULT_SCALE_FILTER;
                    mi.Resize(mGeo);
                }
                UpdatepictureBox(drawingSize, mi.ToBitmap(), confidence);
            }
            catch (Exception e)
            {
                Log.Error(e, "Thumbnail failed to render for the Scan Region.");
                scan.Dispose();
                _RenderingFrame = false;
            }
        }
예제 #3
0
 // lexer results keep available
 public virtual void Dispose()
 {
     scan.Dispose(); scan = null;
     Array.Fill(tokens, default, 0, tokenn);