Exemplo n.º 1
0
 static void so_stitching_points_append(so_stitching_points_t points, so_stitching_points_t other)
 {
     so_stitching_point_t[] newPoints = new so_stitching_point_t[points.capacity + other.capacity];
     for (int i = 0; i < points.count; i++)
     {
         newPoints[i] = points.points[i];
     }
     for (int i = 0; i < other.count; i++)
     {
         newPoints[i + points.count] = other.points[i];
     }
     points.points   = newPoints;
     points.capacity = points.capacity + other.capacity;
     points.count    = points.count + other.count;
 }
Exemplo n.º 2
0
    public static bool so_seam_optimize(so_seam_t seam, Color[] data, int w, int h, int c = 3, float lambda = 0.1f)
    {
        so_texel_set_t        texels          = seam.texels;
        so_stitching_points_t stitchingPoints = seam.stitchingPoints;

        int m = stitchingPoints.count;
        int n = texels.count;

        so_texel_t[] texelsFlat = new so_texel_t[n];
        for (int i = 0; i < n; i++)
        {
            texelsFlat[i] = new so_texel_t(0, 0);
        }

        float[] A = new float[(m + n) * 8];

        int[] AsparseIndices = new int[(m + n) * 8];

        float[] b = new float[m + n];

        float[] Atb = new float[n];

        float[] x = new float[n];

        for (int i = 0, j = 0; i < texels.capacity && j < n; i++)
        {
            if (texels.texels[i].x != -1)
            {
                texelsFlat[j++] = texels.texels[i];
            }
        }

        System.Array.Sort(texelsFlat, so_texel_cmp);

        int r = 0;

        for (int i = 0; i < m; i++)
        {
            int[] column0 = { 0, 0, 0, 0 };
            int[] column1 = { 0, 0, 0, 0 };
            bool  side0valid = false, side1valid = false;
            for (int k = 0; k < 4; k++)
            {
                so_texel_t t0 = stitchingPoints.points[i].sides[0].texels[k];
                so_texel_t t1 = stitchingPoints.points[i].sides[1].texels[k];
                column0[k] = System.Array.BinarySearch(texelsFlat, t0, so_texel_cmp);
                column1[k] = System.Array.BinarySearch(texelsFlat, t1, so_texel_cmp);

                if (column0[k] == -1)
                {
                    side0valid = false; break;
                }
                if (column1[k] == -1)
                {
                    side1valid = false; break;
                }

                // test for validity of stitching point
                for (int ci = 0; ci < c; ci++)
                {
                    side0valid |= data[t0.y * w + t0.x][ci] > 0.0f;
                    side1valid |= data[t1.y * w + t1.x][ci] > 0.0f;
                }
            }

            if (side0valid && side1valid)
            {
                for (int k = 0; k < 4; k++)
                {
                    A[r * 8 + k * 2 + 0] = stitchingPoints.points[i].sides[0].weights[k];
                    AsparseIndices[r * 8 + k * 2 + 0] = column0[k];
                    A[r * 8 + k * 2 + 1] = -stitchingPoints.points[i].sides[1].weights[k];
                    AsparseIndices[r * 8 + k * 2 + 1] = column1[k];
                }
                r++;
            }
        }

        m = r;

        // add error terms for deviation from original pixel value (scaled by lambda)
        for (int i = 0; i < n; i++)
        {
            A[(m + i) * 8] = lambda;
            AsparseIndices[(m + i) * 8 + 0] = i;
            AsparseIndices[(m + i) * 8 + 1] = -1;
        }

        so_sparse_entries_t AtA = so_matrix_At_times_A(A, AsparseIndices, 8, m + n, n);
        so_sparse_entries_t L   = so_matrix_cholesky_prepare(AtA, n);

        if (L.count == 0)
        {
            return(false);            // Cholesky decomposition failed
        }

        so_sparse_entries_t Lcols = new so_sparse_entries_t(L.count);

        for (int i = 0; i < L.count; i++)
        {
            so_sparse_matrix_add(Lcols, (L.entries[i].index % n) * n + (L.entries[i].index / n), L.entries[i].value);
        }
        so_sparse_matrix_sort(Lcols);

        // solve each color channel independently
        for (int ci = 0; ci < c; ci++)
        {
            for (int i = 0; i < n; i++)
            {
                b[m + i] = lambda * data[texelsFlat[i].y * w + texelsFlat[i].x][ci];
            }

            so_matrix_At_times_b(A, m + n, n, b, Atb, AsparseIndices, 8);
            so_matrix_cholesky_solve(L, Lcols, x, Atb, n);

            // write out results
            for (int i = 0; i < n; i++)
            {
                data[texelsFlat[i].y * w + texelsFlat[i].x][ci] = Mathf.Max(x[i], 0);
            }
        }

        return(true);
    }
Exemplo n.º 3
0
 static void so_stitching_points_add(so_stitching_points_t points, so_stitching_point_t point)
 {
     Debug.Assert(points.count < points.capacity);
     points.points[points.count++] = point;
 }