Ejemplo n.º 1
0
/**
 * Constructs an OverlapStatistics object.  Compares the two input cubes and
 * finds where they overlap.
 *
 * @param x The first input cube
 * @param y The second input cube
 * @param progressMsg (Default value of "Gathering Overlap Statistics") Text
 *         for indicating progress during statistic gathering
 * @param sampPercent (Default value of 100.0) Sampling percent, or the percentage
 *       of lines to consider during the statistic gathering procedure
 *
 * @throws Isis::iException::User - All images must have the same number of
 *                                  bands
 */
OverlapStatistics::OverlapStatistics(Isis::Cube &x, Isis::Cube &y,
                                     std::string progressMsg, double sampPercent) {
    // Test to ensure sampling percent in bound
    if (sampPercent <= 0.0 || sampPercent > 100.0) {
        string msg = "The sampling percent must be a decimal (0.0, 100.0]";
        throw iException::Message(iException::Programmer,msg,_FILEINFO_);
    }

    p_sampPercent = sampPercent;

    // Extract filenames and band number from cubes
    p_xFile = x.Filename();
    p_yFile = y.Filename();

    // Make sure number of bands match
    if (x.Bands() != y.Bands()) {
        string msg = "Number of bands do not match between cubes [" +
                     p_xFile.Name() + "] and [" + p_yFile.Name() + "]";
        throw iException::Message(iException::User,msg,_FILEINFO_);
    }
    p_bands = x.Bands();
    p_stats.resize(p_bands);

    //Create projection from each cube
    Projection *projX = x.Projection();
    Projection *projY = y.Projection();

    // Test to make sure projection parameters match
    if (*projX != *projY) {
        string msg = "Mapping groups do not match between cubes [" +
                     p_xFile.Name() + "] and [" + p_yFile.Name() + "]";
        throw iException::Message(iException::Programmer,msg,_FILEINFO_);
    }

    // Figure out the x/y range for both images to find the overlap
    double Xmin1 = projX->ToProjectionX(0.5);
    double Ymax1 = projX->ToProjectionY(0.5);
    double Xmax1 = projX->ToProjectionX(x.Samples()+0.5);
    double Ymin1 = projX->ToProjectionY(x.Lines()+0.5);

    double Xmin2 = projY->ToProjectionX(0.5);
    double Ymax2 = projY->ToProjectionY(0.5);
    double Xmax2 = projY->ToProjectionX(y.Samples()+0.5);
    double Ymin2 = projY->ToProjectionY(y.Lines()+0.5);

    // Find overlap
    if ((Xmin1<Xmax2) && (Xmax1>Xmin2) && (Ymin1<Ymax2) && (Ymax1>Ymin2)) {
        double minX = Xmin1 > Xmin2 ? Xmin1 : Xmin2;
        double minY = Ymin1 > Ymin2 ? Ymin1 : Ymin2;
        double maxX = Xmax1 < Xmax2 ? Xmax1 : Xmax2;
        double maxY = Ymax1 < Ymax2 ? Ymax1 : Ymax2;

        // Find Sample range of the overlap
        p_minSampX = (int)(projX->ToWorldX(minX) + 0.5);
        p_maxSampX = (int)(projX->ToWorldX(maxX) + 0.5);
        p_minSampY = (int)(projY->ToWorldX(minX) + 0.5);
        p_maxSampY = (int)(projY->ToWorldX(maxX) + 0.5);
        p_sampRange = p_maxSampX - p_minSampX + 1;

        // Test to see if there was only sub-pixel overlap
        if (p_sampRange <= 0) return;

        // Find Line range of overlap
        p_minLineX = (int)(projX->ToWorldY(maxY) + 0.5);
        p_maxLineX = (int)(projX->ToWorldY(minY) + 0.5);
        p_minLineY = (int)(projY->ToWorldY(maxY) + 0.5);
        p_maxLineY = (int)(projY->ToWorldY(minY) + 0.5);
        p_lineRange = p_maxLineX - p_minLineX + 1;

        // Print percent processed
        Progress progress;
        progress.SetText(progressMsg);

        int linc = (int)(100.0 / sampPercent + 0.5); // Calculate our line increment

        // Define the maximum number of steps to be our line range divided by the
        // line increment, but if they do not divide evenly, then because of
        // rounding, we need to do an additional step for each band
        int maxSteps = (int)(p_lineRange / linc + 0.5);

        if (p_lineRange % linc != 0) maxSteps += 1;
        maxSteps *= p_bands;


        progress.SetMaximumSteps(maxSteps);
        progress.CheckStatus();

        // Collect and store off the overlap statistics
        for (int band=1; band<=p_bands; band++) {
            Brick b1(p_sampRange,1,1,x.PixelType());
            Brick b2(p_sampRange,1,1,y.PixelType());

            int i=0;
            while (i<p_lineRange) {
                b1.SetBasePosition(p_minSampX,(i+p_minLineX),band);
                b2.SetBasePosition(p_minSampY,(i+p_minLineY),band);
                x.Read(b1);
                y.Read(b2);
                p_stats[band-1].AddData(b1.DoubleBuffer(), b2.DoubleBuffer(), p_sampRange);

                // Make sure we consider the last line
                if (i+linc > p_lineRange-1 && i != p_lineRange-1) {
                    i = p_lineRange-1;
                    progress.AddSteps(1);
                }
                else i+=linc; // Increment the current line by our incrementer

                progress.CheckStatus();
            }
        }
    }
}