예제 #1
0
        public async Task <List <Mat> > GenerateTiles(Quilter quilter, int size, float overlapQuotient, int nIter)
        {
            int qSize = (int)(Math.Sqrt(2) * size);

            if (qSize % 2 == 0)
            {
                qSize++;
            }
            int overlap = (int)(qSize / (2 - overlapQuotient) * overlapQuotient);

            if (overlap % 2 == 0)
            {
                overlap++;
            }
            int bs    = (qSize + overlap) / 2;
            int sSize = bs + overlap / 2;

            quilter.BlockSize = bs;
            quilter.Overlap   = overlap;
            quilter.WangMode  = true;

            //DEBUG
            quilter.RngSeed(42);

            float      minCutErr = float.MaxValue;
            List <Mat> bestTiles = null;

            for (int k = 0; k < nIter; k++)
            {
                float cutErr = 0;

                List <Mat> currTiles = new List <Mat>();
                List <Mat> vert = new List <Mat>(), horiz = new List <Mat>();
                for (int i = 0; i < vertColors; i++)
                {
                    vert.Add(quilter.GetRandomBlock(sSize));
                }
                for (int i = 0; i < horizColors; i++)
                {
                    horiz.Add(quilter.GetRandomBlock(sSize));
                }

                for (int i = 0; i < tiles.Count; i++)
                {
                    var tile = tiles[i];

                    quilter.Start(2, 2);
                    Mat l = new Mat(horiz[tile.L], new CvRect(overlap / 2, overlap / 2, bs, bs));
                    Mat t = new Mat(vert[tile.T], new CvRect(0, overlap / 2, bs, bs));
                    Mat b = new Mat(vert[tile.B], new CvRect(overlap / 2, 0, bs, bs));
                    Mat r = new Mat(horiz[tile.R], new CvRect(0, 0, bs, bs));

                    quilter.Step(l); l.Dispose();
                    quilter.Step(t); t.Dispose();
                    quilter.Step(b); b.Dispose();
                    quilter.Step(r); r.Dispose();

                    cutErr += quilter.CutError;
                    currTiles.Add(quilter.Quilt);

                    if (cutErr >= minCutErr)
                    {
                        break;
                    }

                    //if (float.IsInfinity(cutErr) || cutErr > 5000)
                    //{

                    //}
                }

                if (cutErr < minCutErr)
                {
                    minCutErr = cutErr;
                    if (bestTiles != null)
                    {
                        foreach (var m in bestTiles)
                        {
                            m.Dispose();
                        }
                    }
                    bestTiles = currTiles;
                }
                else
                {
                    foreach (var m in currTiles)
                    {
                        m.Dispose();
                    }
                }

                if (k % 100 == 0)
                {
                    System.Diagnostics.Debug.WriteLine($"{minCutErr} {cutErr}");
                }

                foreach (var m in vert)
                {
                    m.Dispose();
                }
                foreach (var m in horiz)
                {
                    m.Dispose();
                }

                await Task.Delay(1);
            }

            List <Mat> turned = new List <Mat>();

            //Remapping
            float[,] mapx = new float[size, size];
            float[,] mapy = new float[size, size];

            //float dxy = (0.5f * qSize - 0.5f * overlap) / size; //TODO: why not size + 1?
            //float x0 = 0.5f * qSize;
            //float y0 = 0.5f * overlap;
            float dxy = (0.5f * qSize - 0.5f) / size; //TODO: why not size + 1?
            float x0  = 0.5f * qSize;
            float y0  = 0.5f;

            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    mapx[i, j] = x0 + j * dxy;
                    mapy[i, j] = y0 + j * dxy;
                }

                x0 -= dxy;
                y0 += dxy;
            }

            Mat mMapx = new Mat(size, size, MatType.CV_32FC1, mapx);
            Mat mMapy = new Mat(size, size, MatType.CV_32FC1, mapy);

            foreach (var m in bestTiles)
            {
                Mat tm = new Mat(size, size, MatType.CV_32FC3);
                Cv2.Remap(m, tm, mMapx, mMapy, OpenCvSharp.Interpolation.Cubic, OpenCvSharp.BorderType.Wrap);
                turned.Add(tm);
                m.Dispose();
            }

            mMapx.Dispose();
            mMapy.Dispose();

            return(turned);
        }
예제 #2
0
        async void Quilt()
        {
            //for (;;)
            //{
            //    Mat b1 = new Mat(16, 16, MatType.CV_32FC3, new Scalar(1, 1, 1));
            //    Mat b2 = new Mat(16, 16, MatType.CV_32FC3, new Scalar(1, 1, 1));
            //    Mat b = new Mat(16, 16, MatType.CV_32FC3, new Scalar(1, 1, 1));
            //    Cv2.Subtract(b1, b2, b);

            //    b1.Dispose();
            //    b2.Dispose();
            //    b.Dispose();

            //    //GC.Collect();
            //}

            //int size = 64;
            //int qSize = (int)Math.Round(Math.Sqrt(2) * size);
            //Mat m = new Mat(qSize, qSize, MatType.CV_32FC3, new Scalar(255,0,0));
            //Cv2.FillPoly(m, new[] { new[] { new CvPoint(0.5f * qSize, 0), new CvPoint(qSize, 0.5f * qSize), new CvPoint(0.5f * qSize, qSize), new CvPoint(0, 0.5f * qSize) } }, new Scalar(0, 0, 255));

            //Mat trans = Cv2.GetRotationMatrix2D(new Point2f(0.5f * qSize, 0.5f * qSize), -45, 1);
            //trans.Set<double>(0, 2, trans.At<double>(0, 2) - 0.5 * (qSize - size));
            //trans.Set<double>(1, 2, trans.At<double>(1, 2) - 0.5 * (qSize - size));
            //Mat tm = new Mat();
            //Cv2.WarpAffine(m, tm, trans, new CvSize(size, size), OpenCvSharp.Interpolation.Linear);

            //Cv2.ImShow("Test", tm);

            //DEBUG
            //int size = 64;
            //int qSize = (int)Math.Round(Math.Sqrt(2) * size);

            //Mat m = new Mat(qSize, qSize, MatType.CV_32FC3, new Scalar(255,0,0));
            //Cv2.FillPoly(m, new[] { new[] { new CvPoint(0.5f * qSize, 10), new CvPoint(qSize - 10, 0.5f * qSize), new CvPoint(0.5f * qSize, qSize - 10), new CvPoint(10, 0.5f * qSize) } }, new Scalar(0, 0, 255));

            //float[,] mapx = new float[size, size];
            //float[,] mapy = new float[size, size];

            //float dxy = (0.5f * qSize - 0.5f) / (size + 1);
            //float x0 = 0.5f * (qSize - 1);
            //float y0 = 0;

            //for (int i = 0; i < size; i++)
            //{
            //    for (int j = 0; j < size; j++)
            //    {
            //        mapx[i, j] = x0 + j * dxy;
            //        mapy[i, j] = y0 + j * dxy;
            //    }

            //    x0 -= dxy;
            //    y0 += dxy;
            //}

            //Mat mMapx = new Mat(size, size, MatType.CV_32FC1, mapx);
            //Mat mMapy = new Mat(size, size, MatType.CV_32FC1, mapy);

            //Mat tm = new Mat(size, size, MatType.CV_32FC3);
            //Cv2.Remap(m, tm, mMapx, mMapy, OpenCvSharp.Interpolation.Cubic, OpenCvSharp.BorderType.Wrap);

            //Cv2.ImShow("Src", m);
            //Cv2.ImShow("Dst", tm);

            //return;



            //DEBUG
            var wangTiler = new WangTiler(3, 3, 31337);
            var q         = new Quilter();

            q.Sources = sources;

            //System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
            //{
            List <Mat> tiles = await wangTiler.GenerateTiles(q, BlockSize, 1f / 6, 1000);

            //}
            //));
            //th.Start();
            Mat result = wangTiler.FitTiles(16, 16, BlockSize, tiles);

            //Cv2.ImShow("Test", result);
            Mat quilted8U = new Mat();

            result.ConvertTo(quilted8U, MatType.CV_8UC3, 255.0);
            WriteableBitmap quiltedBmp = quilted8U.ToWriteableBitmap();

            Result = quiltedBmp;

            return;


            //foreach (var src in sources)
            //{
            //    if (BlockSize > src.Cols || BlockSize > src.Rows)
            //    {
            //        MessageBox.Show("Block Size exceeds one of the source's size, please reduce Block Size or reload the sources.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            //        return;
            //    }
            //}

            //Quilter q = new Quilter();
            ////q.MatchTolerance = 100;
            //q.BlockSize = BlockSize;
            //q.Overlap = BlockSize / 6;
            //q.Sources = sources;



            //int step = q.BlockSize - q.Overlap;
            //int qw = (Width - q.Overlap - 1) / step + 1;
            //int qh = (Height - q.Overlap - 1) / step + 1;

            //q.Start(qw, qh);
            //for (;;)
            //{
            //    bool more = q.Step();
            //    Mat quilted8U = new Mat();
            //    q.Quilt.ConvertTo(quilted8U, MatType.CV_8UC3, 255.0);
            //    WriteableBitmap quiltedBmp = quilted8U.ToWriteableBitmap();
            //    Result = quiltedBmp;
            //    quilted8U.Dispose();
            //    await Task.Delay(1);
            //    if (!more) break;
            //}

            //System.Diagnostics.Debug.WriteLine(q.CutError);
        }