/** * \brief Dark image construction function for arbitrary image sequences */ ImagePtr DarkFrameFactory::operator()(const ImageSequence& images) const { debug(LOG_DEBUG, DEBUG_LOG, 0, "processing %d images into dark frame", images.size()); // make sure we have at least one image if (images.size() == 0) { debug(LOG_ERR, DEBUG_LOG, 0, "cannot create dark from no images"); throw std::runtime_error("no images in sequence"); } // find out whether these are Bayer images, by looking at the first // image ImagePtr firstimage = *images.begin(); bool gridded = firstimage->getMosaicType().isMosaic(); debug(LOG_DEBUG, DEBUG_LOG, 0, "first image is %sgridded", (gridded) ? "" : "not "); // based on the bit size of the first image, decide whether to work // with floats or with doubles unsigned int floatlimit = std::numeric_limits<float>::digits; debug(LOG_DEBUG, DEBUG_LOG, 0, "float limit is %u", floatlimit); ImagePtr result; if (firstimage->bitsPerPlane() <= floatlimit) { result = dark<float>(images, gridded); } else { result = dark<double>(images, gridded); } if (firstimage->hasMetadata("INSTRUME")) { result->setMetadata(firstimage->getMetadata("INSTRUME")); } if (firstimage->hasMetadata("PROJECT")) { result->setMetadata(firstimage->getMetadata("PROJECT")); } result->setMosaicType(firstimage->getMosaicType()); return result; }
/** * \brief Check that the image sequence is consistent * * Only a if all the images are of the same size we can actually compute * a calibration image. * \param images */ bool consistent(const ImageSequence& images) { // make sure all images in the sequence are of the same size ImageSequence::const_iterator i = images.begin(); for (i++; i != images.end(); i++) { if ((*images.begin())->size() != (*i)->size()) { debug(LOG_DEBUG, DEBUG_LOG, 0, "image size mismatch"); return false; } } // make sure all the images are monochrome images. There is now way // to calibrate color image, for (i = images.begin(); i != images.end(); i++) { if (isColorImage(*i)) { return false; } } return true; }
void ImageMean<T>::setup_images(const ImageSequence& images) { // create an image of appropriate size size = (*images.begin())->size(); image = new Image<T>(size); if (enableVariance) { // prepare the variance image var = new Image<T>(size); } else { var = NULL; } }
void ImageMean<T>::setup_pv(const ImageSequence& images) { // the image sequence must be consistent, or we cannot do // anything about it if (!consistent(images)) { throw std::runtime_error("images not consistent"); } // we need access to the pixels, but we want to avoid all the // time consuming dynamic casts, so we create a vector of // PixelValue objects, which already do the dynamic casts // in the constructor ImageSequence::const_iterator i; for (i = images.begin(); i != images.end(); i++) { pvs.push_back(PV(*i)); } }