예제 #1
0
void PreviewColorPickerTool::CalcCorrection(hugin_utils::FDiff2D pos)
{
    m_red=0;
    m_blue=0;
    m_count=0;
    HuginBase::Panorama* pano=helper->GetPanoramaPtr();
    HuginBase::UIntSet activeImages=pano->getActiveImages();
    if(activeImages.size()>0)
    {
        for(HuginBase::UIntSet::iterator it=activeImages.begin();it!=activeImages.end();++it)
        {
            //check if point is inside the image, check also all 4 corners of rectangle
            HuginBase::PTools::Transform trans;
            trans.createTransform(pano->getImage(*it),pano->getOptions());
            double x;
            double y;
            if(trans.transformImgCoord(x,y,pos.x,pos.y))
            {
                vigra::Point2D imagePos(x,y);
                if(pano->getImage(*it).isInside(imagePos) && 
                    pano->getImage(*it).isInside(imagePos + vigra::Point2D(-ColorPickerSize,-ColorPickerSize)) &&
                    pano->getImage(*it).isInside(imagePos + vigra::Point2D(-ColorPickerSize, ColorPickerSize)) &&
                    pano->getImage(*it).isInside(imagePos + vigra::Point2D( ColorPickerSize,-ColorPickerSize)) &&
                    pano->getImage(*it).isInside(imagePos + vigra::Point2D( ColorPickerSize, ColorPickerSize)) 
                   )
                {
                    CalcCorrectionForImage(*it,imagePos);
                };
            };
        };
    };
    if(m_count>0)
    {
        m_red=m_red/m_count;
        m_blue=m_blue/m_count;
    };
};
예제 #2
0
int main(int argc, char* argv[])
{
    // parse arguments
    const char* optstring = "hr";

    int c;
    bool reverse = false;
    while ((c = getopt (argc, argv, optstring)) != -1)
    {
        switch (c)
        {
            case 'h':
                usage(hugin_utils::stripPath(argv[0]).c_str());
                return 0;
            case 'r':
                reverse = true;
                break;
            case '?':
                break;
            default:
                abort ();
        }
    }

    if (argc - optind < 1 || argc - optind > 2)
    {
        usage(hugin_utils::stripPath(argv[0]).c_str());
        return 1;
    }

    std::string input=argv[optind];

    HuginBase::Panorama pano;
    std::ifstream prjfile(input.c_str());
    if (!prjfile.good())
    {
        std::cerr << "could not open script : " << input << std::endl;
        return 1;
    }
    pano.setFilePrefix(hugin_utils::getPathPrefix(input));
    AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
    if (err != AppBase::DocumentData::SUCCESSFUL)
    {
        std::cerr << "error while parsing panos tool script: " << input << std::endl;
        std::cerr << "AppBase::DocumentData::ReadWriteError code: " << err << std::endl;
        return 1;
    }

    // set up output format
    std::cout.setf ( std::ios::fixed ) ;
    std::cout.precision ( 6 ) ; // should be ample

    if ( argc - optind == 1 )
    {
        // no image number was passed. This triggers the new
        // behaviour to accept triplets on cin
        work_on_triplets ( pano , reverse ) ;
        return 0;
    }

    // an image number was passed, so proceed
    // as in the original version

    int imageNumber = atoi(argv[optind+1]);
    if (imageNumber >= pano.getNrOfImages())
    {
        std::cerr << "Not enough images in panorama" << std::endl;
        return 1;
    }

    // pano tools interface
    HuginBase::PTools::Transform trafo;
    if (reverse)
    {
        trafo.createTransform(pano.getSrcImage(imageNumber), pano.getOptions());
    }
    else
    {
        trafo.createInvTransform(pano.getSrcImage(imageNumber), pano.getOptions());
    }

    double xin , yin , xout , yout ;

    // here's where the old-style IO was, now it's all streams.
    // It's also format-free input, so newlines don't matter
    while ( std::cin >> xin >> yin )
    {
        trafo.transformImgCoord(xout, yout, xin, yin);
        std::cout << xout << " " << yout << std::endl ;
    }
}
예제 #3
0
void PreviewLayoutLinesTool::updateLineInformation()
{
    m_lines.clear();
    const HuginBase::Panorama & pano = *(helper->GetPanoramaPtr());
    unsigned int numberOfImages = pano.getNrOfImages();
    HuginBase::UIntSet active_images = pano.getActiveImages();
    // make a line for every image pair, but set the unneeded ones as dud.
    // This is for constant look up times when we scan control points.
    m_lines.resize(numberOfImages * numberOfImages);
    unsigned int numberOfControlPoints = pano.getNrOfCtrlPoints();
    // loop over all control points to count them and get error statistics.
    for (unsigned int cpi = 0 ; cpi < numberOfControlPoints ; cpi++)
    {
        const HuginBase::ControlPoint & cp = pano.getCtrlPoint(cpi);
        unsigned int low_index, high_index;
        if (cp.image1Nr < cp.image2Nr)
        {
            low_index = cp.image1Nr;
            high_index = cp.image2Nr;
        } else {
            low_index = cp.image2Nr;
            high_index = cp.image1Nr;
        }
        // find the line.
        // We use the formula in the line below to record image numbers to each
        // line later.
        LineDetails & line = m_lines[low_index * numberOfImages + high_index];
        // update control point count.
        line.numberOfControlPoints++;
        // update error statistics
        line.totalError += cp.error;
        if (cp.error > line.worstError)
        {
            line.worstError = cp.error;
        }
    }
    
    /* Find some locations of the images. We will test if they overlap using
     *  these locations. We don't need the last image as we can always take the
     * smallest numbered image as the source of points.
     */
    /** @todo Check both ways around.
     * This only checks if points from the smallest numbered image are
     * within the largest numbered image. If the first image is huge compared to
     * the second, then it many points will miss and we might not reach the
     * target even if the second image is contained within the first.
     */
    std::vector<PosMap>  positions(pano.getNrOfImages() - 1);
    for (unsigned int i = 0; i < numberOfImages - 1; i++)
    {
        const HuginBase::SrcPanoImage & img = pano.getImage(i);
        for (unsigned int x = 0; x < SAMPLE_FREQUENCY; x++)
        {
            for (unsigned int y = 0; y < SAMPLE_FREQUENCY; y++)
            {
                // scale (x, y) so it is always within the cropped region of the
                // image.
                vigra::Rect2D c = img.getCropRect();
                /** @todo Use only points inside the circle when circular crop
                 * is used.
                 */
                double xc = double (x) / double (SAMPLE_FREQUENCY)
                                        * double(c.width()) + c.left();
                double yc = double (y) / double (SAMPLE_FREQUENCY)
                                        * double(c.height()) + c.top();
                // now look up (xc, yc) in the image, find where in the panorama
                // it ends up.
                m_transforms[i]->transformImgCoord  (
                            positions[i][x][y].x, positions[i][x][y].y,
                            xc, yc                  );
            }
        }
    }
    
    // write other line data.
    for (unsigned int i = 0; i < numberOfImages; i++)
    {
        for (unsigned int j = 0; j < numberOfImages; j++)
        {
            LineDetails & line = m_lines[i * numberOfImages + j];
            line.image1 = i;
            line.image2 = j;
            /// test if the line should be visible.
            if (!(set_contains(active_images, i) &&
                  set_contains(active_images, j)))
            {
                // At least one of the images is hidden, so don't show the line.
                line.dud = true;
            }
            else if (line.numberOfControlPoints > 0)
            {
                line.dud = false;
            } else if (i >= j) {
                // We only use lines where image1 is the lowest numbered image.
                // We don't bother with lines from one image to the same one.
                line.dud = true;
            } else {
                // test overlapping regions.
                HuginBase::PTools::Transform transform;
                ViewState & viewState = *helper->GetViewStatePtr();
                HuginBase::SrcPanoImage & src = *viewState.GetSrcImage(j);
                transform.createTransform(src, *(viewState.GetOptions()));
                unsigned int overlapingSamples = 0;
                for (unsigned int x = 0; x < SAMPLE_FREQUENCY; x++)
                {
                    for (unsigned int y = 0; y < SAMPLE_FREQUENCY; y++)
                    {
                        // check if mapping a point that was found earilier to
                        // be inside an image in panorama space is inside the
                        // other image when transformed from panorama to image.
                        double dx, dy;
                        transform.transformImgCoord (
                                        dx, dy,
                                        positions[i][x][y].x,
                                        positions[i][x][y].y
                                                    );
                        if (src.isInside(vigra::Point2D((int) dx, (int) dy)))
                        {
                            // they overlap
                            overlapingSamples++;
                        }
                    }
                }
                // If the overlap isn't big enough, the line isn't used.
                line.dud = (overlapingSamples < MIN_SAMPLE_OVERLAPS);
            }
            
            if (!line.dud)
            {
                line.arc = GreatCircleArc(m_imageCentresSpherical[i].x,
                                          m_imageCentresSpherical[i].y,
                                          m_imageCentresSpherical[j].x,
                                          m_imageCentresSpherical[j].y,
                                          *(helper->GetVisualizationStatePtr()));
            }
        }
    }
}