Пример #1
0
        public override void Trigger(EditableView.ClickPosition.Sources source, EditableView pnlView, Transaction transaction)
        {
            IShapeContainer container = CurrentPage.SelectionContainer();

            if (container == null)
            {
                MessageBox.Show(Strings.Item("Container_Mismatch"));
                return;
            }

            transaction.Edit((Datum)container);
            Lined         mask  = FindSourceShape();
            ImportedImage image = FindSourceImage();

            transaction.Edit(mask);
            transaction.Edit(image);
            (mask as Pencil).ForceClosure(transaction);
            if (mask is Curve curve && !curve.Closed())
            {
                throw new UserException("[Mask_Not_Closed]");
            }
            MaskedImage result = new MaskedImage(image, mask);

            transaction.Create(result);

            int index = Math.Max(mask.Z, image.Z);             // this will be the Z-order of the new group

            result.Parent = container;
            container.Contents.Insert(index + 1, result);             // This index will be valid as the individual shapes are still in the list
            container.Contents.Remove(mask);
            container.Contents.Remove(image);
            container.FinishedModifyingContents(transaction, null);
            CurrentPage.SelectOnly(result);
        }
Пример #2
0
        /// <summary>
        /// Creates processed marker file
        /// </summary>
        private void CreateProcessedMask(string folder, MaskedImage maskedImage)
        {
            try
            {
                StringBuilder csvContent  = new StringBuilder();
                string        newFilePath = CreateNewPath(folder, maskedImage.csvMask);
                // Getting processed mask
                char[,] processedMask = FileProcess.GetProcessedMask(maskedImage, Effects);
                // Writing to new File
                int width  = processedMask.GetLength(0);
                int height = processedMask.GetLength(1);
                for (int y = 0; y < height; y++)
                {
                    string line = "";
                    for (int x = 0; x < width; x++)
                    {
                        line += processedMask[x, y] + ";";
                    }
                    csvContent.AppendLine(line);
                }

                File.AppendAllText(newFilePath, csvContent.ToString());
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message,
                                                     "Error",
                                                     MessageBoxButtons.OK,
                                                     MessageBoxIcon.Error);
            }
        }
Пример #3
0
    //-----------------------------------------------------
    public Inpaint(image input, bool[,] mask, int radius)
    {
        // initial image
        this.initial = new MaskedImage(input, mask);

        // patch radius
        this.radius = radius;
        int i = 0;

        // working copies
        source = new MaskedImage(initial.width, initial.height);
        source = initial;

        target = new MaskedImage(source.width, source.height);

        Debug.Log("build pyramid of images...");

        // build pyramid of downscaled images
        pyramid = new MaskedImage[12];
        this.pyramid[i] = source;

        //Debug.Log("pyramid0:"+ pyramid[0].width+"/"+pyramid[0].height);
        while(source.width>radius && source.height>radius)
        {
            source = source.downsample();
            i++;
            this.pyramid[i] = new MaskedImage(source.width, source.height);
            this.pyramid[i] = source;
        }
        maxlevel = i+1;
    }
Пример #4
0
        public static char[,] GetProcessedMask(MaskedImage maskedImage, List <int> effects)
        {
            BitmapImage bm = new BitmapImage(new Uri(maskedImage.source));

            int indent = EditPageVM.IndentToCrop;

            char[,] mask = ReadMaskFromCSV(maskedImage.csvMask, bm.PixelWidth, bm.PixelHeight);
            if (!effects.Contains(EditPageVM.EFFECT_CROP) && !effects.Contains(EditPageVM.EFFECT_ROTATE))
            {
                return(mask);
            }

            // Cropping mask
            if (effects.Contains(EditPageVM.EFFECT_CROP))
            {
                int width  = bm.PixelWidth - 2 * indent;
                int height = bm.PixelHeight - 2 * indent;
                mask = CropMask(width, height, indent, mask);
            }
            // Rotating mask
            int rotationCount = effects.FindAll(element => element.Equals(EditPageVM.EFFECT_ROTATE)).Count;

            for (int i = 0; i < rotationCount; i++)
            {
                mask = RotateMask90(mask);
            }

            return(mask);
        }
Пример #5
0
        /// <summary>
        /// Matches images and .csv masks by compairing the names
        /// </summary>
        private static bool TryToParceMaskedImages()
        {
            List <MaskedImage> parcedImages = new List <MaskedImage>();
            int imageCount = PathesToImages.Count();
            int maskCount  = PathesToCsvFiles.Count();

            for (int imgIndx = 0; imgIndx < imageCount; imgIndx++)
            {
                string imageName = Path.GetFileNameWithoutExtension(PathesToImages[imgIndx]);
                for (int maskIndx = 0; maskIndx < maskCount; maskIndx++)
                {
                    string maskName = Path.GetFileNameWithoutExtension(PathesToCsvFiles[maskIndx]);
                    if (imageName == maskName)
                    {
                        MaskedImage image = new MaskedImage();
                        image.source  = PathesToImages[imgIndx];
                        image.csvMask = PathesToCsvFiles[maskIndx];
                        parcedImages.Add(image);
                        break;
                    }
                }
            }
            if (parcedImages.Count > 0)
            {
                MaskedImages = parcedImages;
                return(true);
            }
            return(false);
        }
Пример #6
0
        private void DerivePitchEdges(Image <Bgr, Byte> image)
        {
            ThresholdedImage = ImageProcess.ThresholdHsv(image, 22, 89, 33, 240, 40, 250);
            MaskedImage      = image.Copy(ThresholdedImage);

            CannyImage = MaskedImage.Canny(200, 100);

            var lines = CannyImage.HoughLinesBinary(1, Math.PI / 360, 100, 200, 50)[0];

            foreach (var line in lines)
            {
                float dirY = line.Direction.Y;

                if (line.Length > 500 && dirY < 0.3 && dirY > -0.3f)
                {
                    if (line.P1.Y < image.Height / 2 && line.P2.Y < image.Height / 2)
                    {
                        m_TopBorderCandidateLines.Enqueue(line);
                        if (m_TopBorderCandidateLines.Count > 20)
                        {
                            m_TopBorderCandidateLines.Dequeue();
                        }
                    }
                    else if (line.P1.Y > image.Height / 2 && line.P2.Y > image.Height / 2)
                    {
                        m_BottomBorderCandidates.Enqueue(line);
                        if (m_BottomBorderCandidates.Count > 20)
                        {
                            m_BottomBorderCandidates.Dequeue();
                        }
                    }
                }
            }
        }
Пример #7
0
    //-----------------------------------------------------
    // distance between two patches in two images
    public static int distance(MaskedImage source,int xs,int ys, MaskedImage target,int xt,int yt, int S)
    {
        long distance=0, wsum=0, ssdmax = 9*255*255;

        // for each pixel in the source patch
        for(int dy=-S;dy<=S;dy++) {
            for(int dx=-S;dx<=S;dx++) {
                wsum+=ssdmax;

                int xks=xs+dx, yks=ys+dy;
                if (xks<1 || xks>=source.width-1) {distance+=ssdmax; continue;}
                if (yks<1 || yks>=source.height-1) {distance+=ssdmax; continue;}

                // cannot use masked pixels as a valid source of information
                if (source.isMasked(xks, yks)) {distance+=ssdmax; continue;}

                // corresponding pixel in the target patch
                int xkt=xt+dx, ykt=yt+dy;
                //Debug.Log("target.width:"+(target.getWidth()));
                //Debug.Log("xkt:"+xkt+" ykt:"+ykt);
                if (xkt < 1 || xkt >= target.width-1)
                                {
                                distance += ssdmax; continue;
                                }
                if (ykt<1 || ykt>=target.height-1)
                                {distance += ssdmax; continue;}

                // cannot use masked pixels as a valid source of information
                if (target.isMasked(xkt, ykt)) {distance+=ssdmax; continue;}

                // SSD distance between pixels (each value is in [0,255^2])
                long ssd=0;
                for(int band=0; band<3; band++) {
                    // pixel values
                    int s_value = source.getSample(xks, yks, band);
                    int t_value = source.getSample(xkt, ykt, band);

                    // pixel horizontal gradients (Gx)
                    float s_gx = 128+(source.getSample(xks+1, yks, band) - source.getSample(xks-1, yks, band))/2;
                    float t_gx = 128+(target.getSample(xkt+1, ykt, band) - target.getSample(xkt-1, ykt, band))/2;

                    // pixel vertical gradients (Gy)
                    float s_gy = 128+(source.getSample(xks, yks+1, band) - source.getSample(xks, yks-1, band))/2;
                    float t_gy = 128+(target.getSample(xkt, ykt+1, band) - target.getSample(xkt, ykt-1, band))/2;

                    ssd += (long) Mathf.Pow(s_value-t_value , 2); // distance between values in [0,255^2]
                    ssd += (long) Mathf.Pow(s_gx-t_gx , 2); // distance between Gx in [0,255^2]
                    ssd += (long) Mathf.Pow(s_gy-t_gy , 2); // distance between Gy in [0,255^2]
                }

                // add pixel distance to global patch distance
                distance += ssd;
            }
        }

        return (int)(DSCALE*distance/wsum);
    }
Пример #8
0
    //-----------------------------------------------------
    public MaskedImage(MaskedImage copy)
    {
        this.im = copy.im;
        width = copy.width;
        height = copy.height;
        this.mask = new bool[width,height];

        for(int y=0;y<height;y++)
            for(int x=0;x<width;x++)
                mask[x,y] = copy.mask[x,y];
    }
Пример #9
0
 public static Mat ImageToMat_Mask(MaskedImage image)
 {
     Mat mat = new Emgu.CV.Mat(
         image.RowCount, image.ColumnCount, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
     for(int r = 0; r < image.RowCount; ++r)
     {
         for(int c = 0; c < image.ColumnCount; ++c)
         {
             byte m = image.HaveValueAt(r, c) ? (byte)255 : (byte)0;
             mat.SetByteValue(r, c, m);
         }
     }
     return mat;
 }
Пример #10
0
        public override void Trigger(EditableView.ClickPosition.Sources source, EditableView pnlView, Transaction transaction)
        {
            MaskedImage     masked    = (MaskedImage)CurrentPage.SelectedShapes.First();
            IShapeContainer container = (IShapeContainer)masked.Parent;

            transaction.Edit((Datum)container);
            transaction.Edit(masked.MaskShape);
            transaction.Edit(masked.Image);
            transaction.Delete(masked);

            masked.Image.Parent     = container;
            masked.MaskShape.Parent = container;
            container.Contents.Insert(masked.Z + 1, masked.Image);             // This index will be valid as the individual shapes are still in the list
            container.Contents.Insert(masked.Z + 2, masked.MaskShape);
            container.Contents.Remove(masked);
            container.FinishedModifyingContents(transaction, null);
            CurrentPage.SelectOnly(masked.MaskShape);             // arbitrarily seemd better to leave the shape selected
        }
Пример #11
0
        public MatchedImagesTab()
        {
            InitializeComponent();

            _camImageFirst.ImageSourceChanged += (s, e) =>
            {
                _imgLeft = new MaskedImage();
                _imgLeft.FromBitmapSource(e.NewImage);
            };

            _camImageSec.ImageSourceChanged += (s, e) =>
            {
                _imgRight = new MaskedImage();
                _imgRight.FromBitmapSource(e.NewImage);
            };

            _featureDetector = new FeatureDetectionAlgorithmController();
            _featureDetector.StatusChanged += _featureDetector_StatusChanged;
        }
Пример #12
0
        public FeatureImagesTab()
        {
            InitializeComponent();

            _camImageFirst.ImageSourceChanged += (s, e) =>
            {
                ImageLeft = new MaskedImage();
                ImageLeft.FromBitmapSource(e.NewImage);
            };

            _camImageSec.ImageSourceChanged += (s, e) =>
            {
                ImageRight = new MaskedImage();
                ImageRight.FromBitmapSource(e.NewImage);
            };

            _matcher = new FeatureMatchingAlgorithm();
            _matcher.StatusChanged += _matcher_StatusChanged;

            _camImageFirst.SelectedPointChanged += OnSelectedPointChanged;
            _camImageSec.SelectedPointChanged += OnSelectedPointChanged;
        }
Пример #13
0
    // initialize field from an existing (possibily smaller) NNF
    public void initialize(NNF nnf)
    {
        // field
        this.field = new int[input.width,input.height,3];
        this.input = nnf.input;
        this.output = nnf.output;
        this.S = nnf.S;

        int fx = input.width/nnf.input.width;
        int fy = input.height/nnf.input.height;
        //System.out.println("nnf upscale by "+fx+"x"+fy+" : "+nnf.input.W+","+nnf.input.H+" -> "+input.W+","+input.H);
        for(int y=0;y<input.height;y++) {
            for(int x=0;x<input.width;x++) {
                int xlow = Mathf.Min(x/fx, nnf.input.width-1);
                int ylow = Mathf.Min(y/fy, nnf.input.height-1);
                field[x,y,0] = nnf.field[xlow,ylow,0]*fx;
                field[x,y,1] = nnf.field[xlow,ylow,1]*fy;
                field[x,y,2] = MaskedImage.DSCALE;
            }
        }

        initialize();
    }
Пример #14
0
    //-----------------------------------------------------
    private void weightedCopy(MaskedImage src, int xs, int ys, double[,,] vote, int xd,int yd, double w)
    {
        //Debug.Log("src:"+src.width+"/"+src.height+" xs/ys:"+xs+"/"+ys+" xd/yd:"+xd+"/"+yd+ "  w: "+w);

        if (src.isMasked(xs, ys)) return;
        //Debug.Log("vote: "+vote.GetLength(0)+"/"+vote.GetLength(1));
        if(xd<vote.GetLength(0) && yd<vote.GetLength(1)){
        vote[xd,yd,0] += w*src.getSample(xs, ys, 0);
        vote[xd,yd,1] += w*src.getSample(xs, ys, 1);
        vote[xd,yd,2] += w*src.getSample(xs, ys, 2);
        vote[xd,yd,3] += w;
        }
        else Debug.Log("en dehors");
    }
Пример #15
0
    //-----------------------------------------------------
    // EM-Like algorithm (see "PatchMatch" - page 6)
    // Returns a double sized target image
    public MaskedImage ExpectationMaximization(int level)
    {
        int iterEM = 1+level/2;
        int iterNNF = Mathf.Min(7,1+level/2);

        //		source = nnf_SourceToTarget.input;
        //		target = nnf_SourceToTarget.output;
        newtarget = null;

        //		Debug.Log("source: "+source.width+"/"+source.height);
        //		Debug.Log("target: "+target.width+"/"+target.height);

        Debug.Log("EM loop (em="+iterEM+",nnf="+iterNNF+") : ");

        // EM Loop
        for(int emloop=1;emloop<=iterEM;emloop++) {

            Debug.Log((1+iterEM-emloop)+" ");

            // set the new target as current target
            if (newtarget!=null) {
                //nnf_SourceToTarget.output = newtarget;
                nnf_TargetToSource.input = newtarget;
                target = newtarget;
                newtarget = null;
            }

            // -- add constraint to the NNF

        if(level>0)
        {
            for(int y=0;y<target.height;y++)
                for(int x=0;x<target.width;x++)
                    if(!source.constainsMasked(x, y, radius))
                    {
                        nnf_TargetToSource.field[x,y,0] = x;
                        nnf_TargetToSource.field[x,y,1] = y;
                        nnf_TargetToSource.field[x,y,2] = 0;
                    }

            // -- minimize the NNF
            nnf_TargetToSource.minimize(iterNNF);
        }

            // -- Now we rebuild the target using best patches from source
            bool upscaled = false;

            // Instead of upsizing the final target, we build the last target from the next level source image
            // So the final target is less blurry (see "Space-Time Video Completion" - page 5)
            if (level>=1 && (emloop==iterEM))
            {
                newsource = pyramid[level-1];
                newtarget = target.upscale(newsource.width,newsource.height);
                //Debug.Log("newsource: "+newsource.width+"/"+newsource.height);
                upscaled = true;
            }
            else
            {
                newsource = pyramid[level];
                newtarget = target;
                upscaled = false;
            }

            // --- EXPECTATION STEP ---
            if(level>0)
            {
                // votes for best patch from NNF Source->Target (completeness) and Target->Source (coherence)
                double[,,] vote = new double[newtarget.width,newtarget.width,4];
                //ExpectationStep(nnf_SourceToTarget, true, vote, newsource, upscaled);
                ExpectationStep(nnf_TargetToSource, false, vote, newsource, upscaled);

                // --- MAXIMIZATION STEP ---
                // compile votes and update pixel values
                MaximizationStep(newtarget, vote);
            }
            // debug : display intermediary result
            result = MaskedImage.resize(newtarget.getBufferedImage(), initial.width, initial.height);
            //Demo.display(result);
        }

        return newtarget;
    }
Пример #16
0
 // constructor
 public NNF(MaskedImage input, MaskedImage output, int patchsize)
 {
     this.input = input;
     this.output= output;
     this.S = patchsize;
 }
Пример #17
0
    //-----------------------------------------------------
    // Maximization Step : Maximum likelihood of target pixel
    public void MaximizationStep(MaskedImage target, double[,,] vote)
    {
        for(int y=0;y<target.height;y++) {
            for(int x=0;x<target.width;x++) {
                if (vote[x,y,3]>0) {
                    int r = (int) ( vote[x,y,0]/vote[x,y,3] );
                    int g = (int) ( vote[x,y,1]/vote[x,y,3] );
                    int b = (int) ( vote[x,y,2]/vote[x,y,3] );

                    target.setSample(x, y, 0, r );
                    target.setSample(x, y, 1, g );
                    target.setSample(x, y, 2, b );
                    target.setMask(x,y,false);
                } else {
                    // conserve the values from previous target
                    //target.setMask(x,y,true);
                }
            }
        }
    }
Пример #18
0
    //-----------------------------------------------------
    // return a downsampled image (factor 1/2)
    public MaskedImage downsample()
    {
        int newW=width/2, newH=height/2;

        // Binomial coefficient
        int[] kernel = {1,5,10,10,5,1};

        MaskedImage newimage = new MaskedImage(newW, newH);

        for(int y=0;y<height-1;y+=2) {
            for(int x=0;x<width-1;x+=2) {

                int r=0,g=0,b=0,m=0,ksum=0;

                for(int dy=-2;dy<=3;dy++) {
                    int yk=y+dy;
                    if (yk<0 || yk>=height) continue;
                    int ky = kernel[2+dy];
                    for(int dx=-2;dx<=3;dx++) {
                        int xk = x+dx;
                        if (xk<0 || xk>=width) continue;

                        if (mask[xk,yk]) continue;
                        int k = kernel[2+dx]*ky;
                        r+= k*this.getSample(xk, yk, 0);
                        g+= k*this.getSample(xk, yk, 1);
                        b+= k*this.getSample(xk, yk, 2);
                        ksum+=k;
                        m++;
                    }
                }
                if (ksum>0) {r/=ksum; g/=ksum; b/=ksum;}

                if (m!=0) {
                    newimage.setSample(x/2, y/2, 0, r);
                    newimage.setSample(x/2, y/2, 1, g);
                    newimage.setSample(x/2, y/2, 2, b);
                    newimage.setMask(x/2, y/2, false);
                } else {
                    newimage.setMask(x/2, y/2, true);
                }
            }
        }

        return newimage;
    }
Пример #19
0
    //-----------------------------------------------------
    // return an upscaled image
    public MaskedImage upscale(int newW,int newH)
    {
        MaskedImage newimage = new MaskedImage(newW, newH);

        for(int y=0;y<newH;y++) {
            for(int x=0;x<newW;x++) {

                // original pixel
                int xs = (x*width)/newW;
                int ys = (y*height)/newH;

                // copy to new image
                if (!mask[xs,ys]) {
                    newimage.setSample(x, y, 0, this.getSample(xs, ys, 0));
                    newimage.setSample(x, y, 1, this.getSample(xs, ys, 1));
                    newimage.setSample(x, y, 2, this.getSample(xs, ys, 2));
                    newimage.setMask(x, y, false);
                } else {
                    newimage.setMask(x, y, true);
                }
            }
        }

        return newimage;
    }
Пример #20
0
        // Finds automatically calibration points on standard calibration image
        // (that is big black dots on white background )
        // In point managment one still have to set correct grid number for each point
        private void FindCalibrationPoints(object sender, RoutedEventArgs e)
        {
            if(_imageControl.ImageSource == null)
                return;

            _finderChooseWindow.ShowDialog();
            if(_finderChooseWindow.Accepted)
            {
                _currentImagePointFinder = (CalibrationPointsFinder)
                    _finderChooseWindow.GetSelectedProcessor("Calibration Points Finder");
                _currentImagePointFinder.PrimaryShapeChecker = (ShapeChecker)
                    _finderChooseWindow.GetSelectedProcessor("Primary CalibShape Qualifier");

                MaskedImage img = new MaskedImage();
                img.FromBitmapSource(_imageControl.ImageSource);
                _currentImagePointFinder.Image = img;
                _currentImagePointFinder.FindCalibrationPoints();

                if(_currentImagePointFinder.Points != null)
                {
                    _currentImagePointFinder.LinesExtractor.ExtractLines();

                    _currentImageGrid = _currentImagePointFinder.Points;
                    RefreshCalibrationPoints();

                    _butAcceptGrid.IsEnabled = true;
                }
            }
        }
Пример #21
0
        public MaskedImage TransfromImageBackwards(IImage image, bool preserveSize = false)
        {
            MaskedImage undistorted;
            FindTransformedImageSize(image.RowCount, image.ColumnCount);

            Matrix<double>[] matrices = new Matrix<double>[image.ChannelsCount];
            if(preserveSize)
            {
                undistorted = new MaskedImage(image.Clone());
                for(int i = 0; i < image.ChannelsCount; ++i)
                {
                    matrices[i] = new DenseMatrix(image.RowCount, image.ColumnCount);
                    undistorted.SetMatrix(matrices[i], i);
                }
            }
            else
            {
                IImage img = image.Clone();
                for(int i = 0; i < image.ChannelsCount; ++i)
                {
                    matrices[i] = new DenseMatrix(_finalSize.Y, _finalSize.X);
                    img.SetMatrix(matrices[i], i);
                }
                undistorted = new MaskedImage(image.Clone());
            }

            int R = InterpolationRadius;
            int R21 = R * 2 + 1;
            for(int x = 0; x < matrices[0].ColumnCount; ++x)
            {
                for(int y = 0; y < matrices[0].RowCount; ++y)
                {
                    // Cast point from new image to old one
                    Vector2 oldCoords = Transformation.TransformPointBackwards(new Vector2(x: x, y: y));
                    Vector2 aa = Transformation.TransformPointForwards(oldCoords);

                    IntVector2 oldPixel = new IntVector2(oldCoords);
                    // Check if point is in old image range or points to undefined point
                    if(oldCoords.X < 0 || oldCoords.X > image.ColumnCount ||
                        oldCoords.Y < 0 || oldCoords.Y > image.RowCount ||
                        image.HaveValueAt(oldPixel.Y, oldPixel.X) == false)
                    {
                        // Point out of range, so set to black
                        for(int i = 0; i < image.ChannelsCount; ++i)
                        {
                            matrices[i].At(y, x, 0.0);
                            undistorted.SetMaskAt(y, x, false);
                        }
                    }
                    else
                    {
                        // Interpolate value from patch in old image
                        double[,] influence = new double[R21, R21];
                        double totalInf = 0;
                        // For each pixel in neighbourhood find its distance and influence of Pu on it
                        for(int dx = -R; dx <= R; ++dx)
                        {
                            for(int dy = -R; dy <= R; ++dy)
                            {
                                double distance = _computeDistance(oldCoords, oldPixel.X + dx, oldPixel.Y + dy);
                                influence[dx + R, dy + R] = 1.0 / distance;
                                totalInf += influence[dx + R, dy + R];
                            }
                        }
                        double infScale = 1.0 / totalInf; // Scale influence, so that its sum over all pixels in radius is 1
                        double[] val = new double[image.ChannelsCount];
                        for(int dx = -R; dx <= R; ++dx)
                        {
                            for(int dy = -R; dy <= R; ++dy)
                            {
                                double inf = influence[dx + R, dy + R] * infScale;
                                // Store color for new point considering influence from neighbours
                                int ix = Math.Max(0, Math.Min(image.ColumnCount - 1, oldPixel.X + dx));
                                int iy = Math.Max(0, Math.Min(image.RowCount - 1, oldPixel.Y + dy));
                                for(int i = 0; i < image.ChannelsCount; ++i)
                                {
                                    val[i] += image[iy, ix, i] * inf;
                                }
                            }
                        }
                        for(int i = 0; i < image.ChannelsCount; ++i)
                        {
                            matrices[i].At(y, x, val[i]);
                        }
                    }
                }
            }

            return undistorted;
        }
Пример #22
0
        public MaskedImage TransfromImageForwards(IImage image, bool preserveSize = false)
        {
            MaskedImage undistorted;
            var influences = FindInfluenceMatrix(image.RowCount, image.ColumnCount);
            Matrix<double>[] matrices = new Matrix<double>[image.ChannelsCount];

            if(preserveSize)
            {
                // New image is in old one's coords
                undistorted = new MaskedImage(image.Clone());
                for(int i = 0; i < image.ChannelsCount; ++i)
                {
                    matrices[i] = new DenseMatrix(image.RowCount, image.ColumnCount);
                    undistorted.SetMatrix(matrices[i], i);
                }

                // Bound processing to smaller of images in each dimesions
                int minX = Math.Max(0, _finalTopLeft.X);
                int maxX = Math.Min(image.ColumnCount, _finalSize.X + _finalTopLeft.X);
                int minY = Math.Max(0, _finalTopLeft.Y);
                int maxY = Math.Min(image.RowCount, _finalSize.Y + _finalTopLeft.Y);
                for(int x = minX; x < maxX; ++x)
                {
                    for(int y = minY; y < maxY; ++y)
                    {
                        double influenceTotal = 0.0;
                        double[] val = new double[image.ChannelsCount];
                        foreach(var inf in influences[y - _finalTopLeft.Y, x - _finalTopLeft.X]) // Move Pu to influence matrix coords
                        {
                            for(int i = 0; i < image.ChannelsCount; ++i)
                                val[i] += image[inf.Yd, inf.Xd, i] * inf.Influence;
                            influenceTotal += inf.Influence;
                        }
                        if(influenceTotal > 0.25)
                        {
                            for(int i = 0; i < image.ChannelsCount; ++i)
                                matrices[i].At(y, x, val[i] / influenceTotal);
                            undistorted.SetMaskAt(y, x, true);
                        }
                        else
                        {
                            undistorted.SetMaskAt(y, x, false);
                        }
                    }
                }
            }
            else
            {
                // New image is in same coords as influence matrix
                for(int i = 0; i < image.ChannelsCount; ++i)
                    matrices[i] = new DenseMatrix(_finalSize.Y, _finalSize.X);
                IImage img = image.Clone();
                for(int i = 0; i < image.ChannelsCount; ++i)
                    img.SetMatrix(matrices[i], i);
                undistorted = new MaskedImage(image.Clone());

                for(int x = 0; x < _finalSize.X; ++x)
                {
                    for(int y = 0; y < _finalSize.Y; ++y)
                    {
                        double influenceTotal = 0.0;
                        double[] val = new double[image.ChannelsCount];
                        foreach(var inf in influences[y, x])
                        {
                            for(int i = 0; i < image.ChannelsCount; ++i)
                                val[i] += image[inf.Yd, inf.Xd, i] * inf.Influence;
                            influenceTotal += inf.Influence;
                        }
                        if(influenceTotal > 0.5)
                        {
                            for(int i = 0; i < image.ChannelsCount; ++i)
                                matrices[i].At(y, x, val[i] / influenceTotal);
                            undistorted.SetMaskAt(y, x, true);
                        }
                        else
                        {
                            undistorted.SetMaskAt(y, x, false);
                        }
                    }
                }
            }

            return undistorted;
        }
Пример #23
0
    //-----------------------------------------------------
    // Expectation Step : vote for best estimations of each pixel
    public void ExpectationStep(NNF nnf, bool sourceToTarget, double[,,] vote, MaskedImage source, bool upscale)
    {
        int[,,] field = nnf.getField();
        int R = nnf.S;
        for(int y=0;y<nnf.input.height;y++)
        {
            for(int x=0;x<nnf.input.width;x++)
            {
                // x,y = center pixel of patch in input

                // xp,yp = center pixel of best corresponding patch in output
                int xp=field[x,y,0], yp=field[x,y,1], dp=field[x,y,2];

                // similarity measure between the two patches
                double w=0;
                if(dp<MaskedImage.DSCALE+1)
                w = MaskedImage.similarity[dp];

                // vote for each pixel inside the input patch
                for(int dy=-R;dy<=R;dy++)
                {
                    for(int dx=-R;dx<=R;dx++)
                    {

                        // get corresponding pixel in output patch
                        int xs,ys,xt,yt;
                        if (sourceToTarget)
                            { xs=x+dx; ys=y+dy;	xt=xp+dx; yt=yp+dy;	}
                        else
                            { xs=xp+dx; ys=yp+dy; xt=x+dx; yt=y+dy; }

                        if (xs<0 || xs>=nnf.input.width) continue;
                        if (ys<0 || ys>=nnf.input.height) continue;
                        if (xt<0 || xt>=nnf.output.width) continue;
                        if (yt<0 || yt>=nnf.output.height) continue;

                        // add vote for the value
                        if (upscale)
                        {
                            weightedCopy(source, 2*xs,   2*ys,   vote, 2*xt,   2*yt,   w);
                            weightedCopy(source, 2*xs+1, 2*ys,   vote, 2*xt+1, 2*yt,   w);
                            weightedCopy(source, 2*xs,   2*ys+1, vote, 2*xt,   2*yt+1, w);
                            weightedCopy(source, 2*xs+1, 2*ys+1, vote, 2*xt+1, 2*yt+1, w);
                        }
                        else
                            weightedCopy(source, xs, ys, vote, xt, yt, w);
                    }
                } // vote
            }
        }
    }