/*! Change the look up table (LUT) of an image. Considering pixel gray level values \f$ l \f$ in the range \f$[A, B]\f$, this method allows to rescale these values in \f$[A^*, B^*]\f$ by linear interpolation: \f$ \left\{ \begin{array}{ll} l \in ]-\infty, A] \mbox{, } & l = A^* \\ l \in [B, \infty[ \mbox{, } & l = B^* \\ l \in ]A, B[ \mbox{, } & l = A^* + (l-A) * \frac{B^*-A^*}{B-A} \end{array} \right. \f$ \param I : Image to process. \param A : Low gray level value of the range to consider. \param A_star : New gray level value \f$ A^*\f$ to attribute to pixel who's value was A \param B : Height gray level value of the range to consider. \param B_star : New gray level value \f$ B^*\f$ to attribute to pixel who's value was B \return The modified image. \exception vpImageException::incorrectInitializationError If \f$B \leq A\f$. As shown in the example below, this method can be used to binarize an image. For an unsigned char image (in the range 0-255), thresholding this image at level 127 can be done by: \code #include <visp3/core/vpImageTools.h> #include <visp3/core/vpImage.h> #include <visp3/io/vpImageIo.h> int main() { vpImage<unsigned char> I; #ifdef _WIN32 std::string filename("C:/temp/ViSP-images/Klimt/Klimt.ppm"); #else std::string filename("/local/soft/ViSP/ViSP-images/Klimt/Klimt.ppm"); #endif // Read an image from the disk vpImageIo::read(I, filename); // Binarize image I: // - gray level values less than or equal to 127 are set to 0, // - gray level values greater than 128 are set to 255 vpImageTools::changeLUT(I, 127, 0, 128, 255); vpImageIo::write(I, "Klimt.pgm"); // Write the image in a PGM P5 image file format } \endcode */ void vpImageTools::changeLUT(vpImage<unsigned char>& I, unsigned char A, unsigned char A_star, unsigned char B, unsigned char B_star) { // Test if input values are valid if (B <= A) { vpERROR_TRACE("Bad gray levels") ; throw (vpImageException(vpImageException::incorrectInitializationError , "Bad gray levels")); } unsigned char v; double factor = (double)(B_star - A_star)/(double)(B - A); for (unsigned int i=0 ; i < I.getHeight(); i++) for (unsigned int j=0 ; j < I.getWidth(); j++) { v = I[i][j]; if (v <= A) I[i][j] = A_star; else if (v >= B) I[i][j] = B_star; else I[i][j] = (unsigned char)(A_star + factor*(v-A)); } }
/*! Sets all the parameters needed to read the video or the image sequence. Grab the first frame and stores it in the image \f$ I \f$. \param I : The image where the frame is stored. */ void vpVideoReader::open(vpImage< vpRGBa > &I) { if (!initFileName) { vpERROR_TRACE("The generic filename has to be set"); throw (vpImageException(vpImageException::noFileNameError,"filename empty")); } if (formatType == FORMAT_PGM || formatType == FORMAT_PPM || formatType == FORMAT_JPEG || formatType == FORMAT_PNG) { imSequence = new vpDiskGrabber; imSequence->setGenericName(fileName); imSequence->setImageNumber((int)firstFrame); } #ifdef VISP_HAVE_FFMPEG else if (formatType == FORMAT_AVI || formatType == FORMAT_MPEG || formatType == FORMAT_MOV || formatType == FORMAT_OGV) { ffmpeg = new vpFFMPEG; if(!ffmpeg->openStream(fileName, vpFFMPEG::COLORED)) throw (vpException(vpException::ioError ,"Could not open the video")); ffmpeg->initStream(); } #else else if (formatType == FORMAT_AVI || formatType == FORMAT_MPEG || formatType == FORMAT_MOV || formatType == FORMAT_OGV) { vpERROR_TRACE("To read video files the FFmpeg library has to be installed"); throw (vpException(vpException::fatalError ,"the FFmpeg library is required")); } #endif else if (formatType == FORMAT_UNKNOWN) { vpERROR_TRACE("The format of the file does not correpsond to a readable format."); throw (vpException(vpException::fatalError ,"The format of the file does not correpsond to a readable format.")); } frameCount = firstFrame; if(!getFrame(I,firstFrame)) { vpERROR_TRACE("Could not read the first frame"); throw (vpException(vpException::ioError ,"Could not read the first frame")); } height = I.getHeight(); width = I.getWidth(); isOpen = true; findLastFrameIndex(); }
/*! Sets all the parameters needed to read the video or the image sequence. Grab the first frame and stores it in the image \f$ I \f$. \param I : The image where the frame is stored. */ void vpVideoReader::open(vpImage<unsigned char> &I) { if (!initFileName) { vpERROR_TRACE("The generic filename has to be set"); throw (vpImageException(vpImageException::noFileNameError,"filename empty")); } if (isImageExtensionSupported()) { imSequence = new vpDiskGrabber; imSequence->setGenericName(fileName); if (firstFrameIndexIsSet) imSequence->setImageNumber(firstFrame); } else if (isVideoExtensionSupported()) { #ifdef VISP_HAVE_FFMPEG ffmpeg = new vpFFMPEG; if (!ffmpeg->openStream(fileName, vpFFMPEG::GRAY_SCALED)) throw (vpException(vpException::ioError ,"Could not open the video with ffmpeg")); ffmpeg->initStream(); #elif VISP_HAVE_OPENCV_VERSION >= 0x020100 capture.open(fileName); if(!capture.isOpened()) { throw (vpException(vpException::ioError ,"Could not open the video with opencv")); } #else //vpERROR_TRACE("To read video files ViSP should be build with ffmpeg or opencv 3rd party libraries."); throw (vpException(vpException::fatalError ,"To read video files ViSP should be build with ffmpeg or opencv >= 2.1.0 3rd party libraries.")); #endif } else if (formatType == FORMAT_UNKNOWN) { //vpERROR_TRACE("The format of the file does not correspond to a readable format."); throw (vpException(vpException::fatalError ,"The format of the file does not correspond to a readable format supported by ViSP.")); } findFirstFrameIndex(); frameCount = firstFrame; if(!getFrame(I,firstFrame)) { //vpERROR_TRACE("Could not read the video first frame"); throw (vpException(vpException::ioError ,"Could not read the video first frame")); } height = I.getHeight(); width = I.getWidth(); isOpen = true; findLastFrameIndex(); frameCount = firstFrame; // open() should not increase the frame counter }
/*! It enables to set the path and the name of the file(s) which as/have to be read. If you want to read a video file, \f$ filename \f$ corresponds to the path to the file (example : /local/video.mpeg). If you want to read a sequence of images, \f$ filename \f$ corresponds to the path followed by the image name template. For exemple, if you want to read different images named image0001.jpeg, image0002.jpg, ... and located in the folder /local/image, \f$ filename \f$ will be "/local/image/image%04d.jpg". \param filename : Path to a video file or file name template of a image sequence. */ void vpVideoReader::setFileName(const char *filename) { if (filename == '\0') { vpERROR_TRACE("filename empty ") ; throw (vpImageException(vpImageException::noFileNameError,"filename empty ")) ; } strcpy(this->fileName,filename); formatType = getFormat(fileName); initFileName = true; }
/*! It enables to set the path and the name of the file(s) which as/have to be read. If you want to read a video file, \f$ filename \f$ corresponds to the path to the file (example : /local/video.mpeg). If you want to read a sequence of images, \f$ filename \f$ corresponds to the path followed by the image name template. For exemple, if you want to read different images named image0001.jpeg, image0002.jpg, ... and located in the folder /local/image, \f$ filename \f$ will be "/local/image/image%04d.jpg". \param filename : Path to a video file or file name template of a image sequence. */ void vpVideoReader::setFileName(const char *filename) { if (!filename || *filename == '\0') { vpERROR_TRACE("filename empty ") ; throw (vpImageException(vpImageException::noFileNameError,"filename empty ")) ; } if (strlen( filename ) >= FILENAME_MAX) { throw(vpException(vpException::memoryAllocationError, "Not enough memory to intialize the file name")); } strcpy(this->fileName,filename); formatType = getFormat(fileName); if (formatType == FORMAT_UNKNOWN) { throw(vpException(vpException::badValue, "Filename extension not supported")); } initFileName = true; }