Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Image.hpp
00001 /* $Id$ */
00002 
00003 #ifndef _JAFAR_IMAGE_IMAGE_HPP_
00004 #define _JAFAR_IMAGE_IMAGE_HPP_
00005 
00006 #include <fstream>  
00007 #include <iostream>  
00008 
00009 #include <boost/archive/text_oarchive.hpp>
00010 #include <boost/archive/text_iarchive.hpp>
00011 #include "boost/archive/xml_iarchive.hpp"
00012 #include "boost/archive/xml_oarchive.hpp"
00013 #include "boost/archive/binary_iarchive.hpp"
00014 #include "boost/archive/binary_oarchive.hpp"
00015 #include "boost/serialization/split_member.hpp"
00016 #include "boost/serialization/binary_object.hpp"
00017 #include <boost/serialization/string.hpp>
00018 #include "boost/shared_ptr.hpp"
00019 
00020 #include <kernel/jafarMacro.hpp>
00021 #include "image/cImage.h"
00022 #include <opencv/cxcore.h>
00023 #if CV_MAJOR_VERSION*10 + CV_MINOR_VERSION > 21
00024 #include <opencv2/core/core.hpp>
00025 #include <opencv2/imgproc/imgproc.hpp>
00026 #include <opencv2/highgui/highgui.hpp>
00027 #include <opencv2/legacy/legacy.hpp>
00028 #else
00029 #include <cxcore.hpp> // opencv
00030 #include <cvaux.hpp>
00031 #include <highgui.hpp>
00032 #endif
00033 
00034 #ifndef SWIG
00035 namespace cv {
00036 std::ostream& operator<<(std::ostream& os, const cv::Rect &r);
00037 std::ostream& operator<<(std::ostream& os, const cv::Point &p);
00038 std::ostream& operator<<(std::ostream& os, const cv::Size &s);
00039 }
00040 #endif
00041 
00042 namespace jafar {
00043 
00045   namespace image {
00046     void getQuadrangleSubPix(const cv::Mat& src, cv::Mat& dst, const cv::Mat& mapMatrix);
00047 
00048     class Image;
00049     typedef boost::shared_ptr<Image>  image_ptr_t;
00050     
00055     class Image {
00056       // Cubic kernels generated with generateCubicKernel
00057       static const int cubicKernelResolution = 255;
00058       static const double cubicKernel1[256];
00059       static const double cubicKernel2[256];
00061       cv::Mat m_matrix;
00062     public:
00063       Image() { }
00064       ~Image();
00075       Image(int width, int height, int depth, JfrImage_TypeColorSpace colorSpace);
00077       Image( Image const & img );
00079       Image& operator=( Image const & img );
00081       Image& operator=( const cv::Mat& matrix );
00083       Image( const CvImage& img );
00085       Image( IplImage* img );
00087       Image( const cv::Mat& matrix );
00090       Image(const Image& img, const cv::Rect& roi);
00091 
00093       Image clone() const;
00094 
00095       
00097       void copyTo(image::Image& dst, 
00098       const image::Image& mask = image::Image()) const;
00099 
00109       void create( int width, int height, int depth, JfrImage_TypeColorSpace colorSpace );
00110       
00127       static Image* loadImage( const char* filename, int iscolor = -1);
00128       
00145       bool load( const std::string& filename, int iscolor = -1 );
00146       
00152       void save( const std::string& filename) const {
00153         //std::string name(filename);
00154         cv::imwrite(filename, m_matrix);
00155       }
00160       void save( const std::string& filename, const std::string& imgname ) {
00161         //std::string name(filename);
00162         cv::imwrite(filename, m_matrix);
00163         m_name = imgname;
00164       }
00168       void save( const std::string& filename, const std::vector<int>& params ) {
00169         cv::imwrite(filename, m_matrix, params);
00170         m_name = filename;
00171       };
00172 
00173       void print() { JFR_DEBUG(*this); }
00174 
00181       void convertColorMode(jafar::image::Image& dst_) const;
00186       void convertDepth(jafar::image::Image& dst_, double scale = 1.0, double offset = 0.0, bool _abs = false) const;
00187       
00190       void resize(Image& resizedImage, int interpolation = CV_INTER_LINEAR) const;
00191       
00197       Image* resize(double scale, int interpolation = CV_INTER_LINEAR) const;
00198       
00205       Image* resize(int newWidth, int newHeight, int interpolation = CV_INTER_LINEAR) const;
00206       
00212       void resize(int newWidth, int newHeight, int interpolation = CV_INTER_LINEAR);
00213       
00217       int imageSize() const;
00218       
00221       inline JfrImage_TypeColorSpace colorSpace() const {
00222         return header.colorSpace;
00223       };
00224       void setColorSpace(JfrImage_TypeColorSpace cs);
00229       inline uchar* data(int line =0) {
00230         return m_matrix.ptr(line);
00231       };
00232       
00237       inline const uchar* data(int line =0) const {
00238         return m_matrix.ptr(line);
00239       };
00240       
00249       void copy( jafar::image::Image & dst, int x_src = 0, int y_src = 0, int x_dst = 0, int y_dst = 0 , int width = -1, int height = -1) const;
00254       bool robustCopy( jafar::image::Image & dst, int x_src = 0, int y_src = 0, int x_dst = 0, int y_dst = 0 , int width = -1, int height = -1) const;
00255 
00256       bool extractPatch(image::Image &dst, int x, int y, int width, int height) const;
00257       
00269       cv::Rect getROI() const
00270       {
00271   cv::Size size;
00272   return getROI(size);
00273       }
00278       cv::Rect getROI(cv::Size &size) const
00279       {
00280   //return cvROIToRect((*this)->roi);
00281   //return roi();
00282         
00283   cv::Point offset;
00284   m_matrix.locateROI(size, offset);
00285   return cv::Rect(offset.x,offset.y,m_matrix.size().width,m_matrix.size().height);
00286       }
00293       void setROI(const cv::Rect &rect)
00294       {
00295   //cvSetImageROI(*this, rect);
00296   //set_roi(rect);
00297         
00298   setROI(rect.x, rect.y, rect.width, rect.height);
00299       }
00303       void setROI(int x, int y, int w, int h)
00304       {
00305         
00306   cv::Size size; cv::Point offset;
00307   m_matrix.locateROI(size, offset);
00308   m_matrix.adjustROI(offset.y-y, (h+y)-(m_matrix.size().height+offset.y),
00309          offset.x-x, (w+x)-(m_matrix.size().width +offset.x));
00310       }
00314       void resetROI()
00315       {
00316   //cvResetImageROI(*this);
00317   //reset_roi();
00318         
00319   cv::Size size; cv::Point offset;
00320   m_matrix.locateROI(size, offset);
00321   m_matrix.adjustROI(offset.y,size.height-(m_matrix.size().height+offset.y),
00322          offset.x,size.width-(m_matrix.size().width+offset.x));
00323       }
00324 
00325       
00329       inline std::string name() const {
00330         return m_name;
00331       }
00332 
00337       void setName(const std::string& _name) {
00338         m_name = _name;
00339       }
00340 
00349       template<typename channeltype>
00350       inline channeltype getPixelValue(int x_, int y_, int channel_=0) const;
00351       
00364       template<typename channeltype>
00365       double getSubPixelValue(double x_, double y_, int channel_=0, JfrImage_InterpolationType _interpolation = JfrImage_INTERP_BILINEAR) const;
00366       
00376       template<typename channeltype>
00377       void setPixelValue(channeltype val_, int x_, int y_, int channel_ = 0);
00378       
00383       double computeZncc(Image const* im2) const;
00395       double computeZnccRoisWeight(Image const* im2, cv::Rect const* roi1_ = NULL, cv::Rect const* roi2_ = NULL, float const* weightMatrix = NULL ) const;
00402       double computeZnccRoi(Image const* im2, cv::Rect const* rectRoi) const;
00403       
00409       double computeRotatingZncc( Image const* im2, int rotationStep) const;
00410       
00415       Image* rankTransform (const int radius);
00416 
00423       void rotateScale(double angle, double factor, Image &dest) const;
00424 
00428       double orientation(double sigma = 1.5);
00429       
00433       bool compHeader(Image const & img) const {
00434   return (width() == img.width() && 
00435     height() == img.height() &&
00436     depth() == img.depth() &&
00437     colorSpace() == img.colorSpace());
00438       }
00440       operator cv::Mat& () { return this->m_matrix; }
00442       operator const cv::Mat& () const { return this->m_matrix; }
00443 
00444 #if CV_MAJOR_VERSION*10 + CV_MINOR_VERSION > 22
00445       // OpenCV 2.3 or later
00446       // need this because no more than one implicit conversion using user-defined convertor can be made
00447       operator cv::_OutputArray() { return this->m_matrix; }
00448       operator const cv::_OutputArray() const { return const_cast<cv::Mat&>(this->m_matrix); }
00449 #endif
00450 
00452       operator const IplImage () const { 
00453         return (const IplImage)m_matrix;
00454       }
00456       operator IplImage () { 
00457   return (IplImage)m_matrix;
00458       }
00460       operator const CvMat () const { return (const CvMat)m_matrix; }
00462       operator CvMat () { return (CvMat)m_matrix; }
00464       inline cv::Size size() const { return m_matrix.size(); }
00466       inline bool empty() const { return m_matrix.empty(); }
00468       inline int width() const { return m_matrix.cols; }
00470       inline int height() const { return m_matrix.rows; }
00472       inline size_t step() const { return m_matrix.step; }
00474       inline size_t step1() const { return m_matrix.step1(); }
00476       inline int depth() const { return m_matrix.depth(); }
00478       inline int channels() const { return m_matrix.channels(); }
00480       inline int type() const { return m_matrix.type(); }
00482       inline cv::Mat mat() const { return m_matrix; }
00484       inline void detach() { m_matrix.release(); }
00486       inline size_t pix_size() { return !m_matrix.empty() ? m_matrix.elemSize() : 0; }
00488       void setTo(const cv::Scalar& s, const image::Image& mask=image::Image()) {
00489   m_matrix.setTo(s, mask);
00490       }
00492       void convertTo(image::Image& dst, double alpha=1, double beta=0) const {
00493   m_matrix.convertTo(dst, dst.type(), alpha, beta);
00494       }
00495 
00496     private:
00497       
00498       void initImageHeader();
00499       // serialization
00500       friend class boost::serialization::access;
00501       
00502       template<class Archive>
00503       void save(Archive & ar, const unsigned int version) const {
00504   JFR_PRECOND(!m_matrix.empty(), "Nothing to save");
00505   IplImage image = (IplImage)m_matrix;
00506   ar << boost::serialization::make_nvp("width",image.width);  
00507   ar << boost::serialization::make_nvp("height",image.height);  
00508   ar << boost::serialization::make_nvp("depth",image.depth);
00509   ar << boost::serialization::make_nvp("colorSpace",header.colorSpace); 
00510   ar << boost::serialization::make_nvp("nChannels",image.nChannels);
00511   ar << boost::serialization::make_nvp("nSize",image.nSize);  
00512   ar << boost::serialization::make_nvp("ID",image.ID);   
00513   ar << boost::serialization::make_nvp("dataOrder",image.dataOrder);  
00514   ar << boost::serialization::make_nvp("origin",image.origin);   
00515   ar << boost::serialization::make_nvp("imageSize",image.imageSize);  
00516   ar << boost::serialization::make_nvp("pixeldata", boost::serialization::make_binary_object(image.imageData, image.imageSize));
00517   ar << boost::serialization::make_nvp("widthStep",image.widthStep);
00518       }
00519       
00520       template<class Archive>
00521       void load(Archive & ar, const unsigned int version) {
00522   int width, height, depth;
00523   JfrImage_TypeColorSpace cs;
00524   ar >> boost::serialization::make_nvp("width",width);
00525   ar >> boost::serialization::make_nvp("height",height);
00526   ar >> boost::serialization::make_nvp("depth",depth);
00527   ar >> boost::serialization::make_nvp("colorSpace",cs);
00528   create(width, height, depth, cs);
00529   IplImage image = (IplImage)m_matrix;
00530   ar >> boost::serialization::make_nvp("nChannels",image.nChannels);
00531   ar >> boost::serialization::make_nvp("nSize",image.nSize);  
00532   ar >> boost::serialization::make_nvp("ID",image.ID);
00533   ar >> boost::serialization::make_nvp("dataOrder",image.dataOrder);  
00534   ar >> boost::serialization::make_nvp("origin",image.origin);
00535   ar >> boost::serialization::make_nvp("imageSize",image.imageSize);
00536   ar >> boost::serialization::make_nvp("pixeldata", boost::serialization::make_binary_object(image.imageData, image.imageSize));  
00537   ar >> boost::serialization::make_nvp("widthStep",image.widthStep);  
00538   memset(image.BorderMode, 0, 4);  
00539   memset(image.BorderConst, 0, 4);  
00540   image.imageDataOrigin = image.imageData;
00541       }
00542 #ifndef SWIG
00543       BOOST_SERIALIZATION_SPLIT_MEMBER()
00544 #endif /* NOT SWIG */
00545 
00546     private:
00552       inline double cubicKernel( int t, double dt ) const;
00553       inline double cubicKernelI( int t, int idx ) const;
00554     private:
00555       JfrImage_ImageHeader header;
00556 
00557       std::string m_name;
00558     }; // class Image
00559     
00560     template<typename channeltype>
00561     channeltype Image::getPixelValue(int x_, int y_, int channel_) const {
00562       JFR_PRECOND(x_ >= 0 && y_ >= 0 && x_ < width() && y_ < height(), "JfrImage::pixelValue pixel coordinates are not in the image.");
00563       JFR_PRECOND( 0 <= channel_ && channel_ < channels(), "JfrImage::pixelValue wrong channel parameter ");
00564       channeltype const *pxPtr;
00565       pxPtr = reinterpret_cast<channeltype const *>(data(y_));
00566       return *(pxPtr + x_*channels() + channel_);
00567     }
00568 
00569     inline double Image::cubicKernelI( int _t, int _idx ) const
00570     {
00571       switch( _t )
00572       {
00573         case -1:
00574           return cubicKernel2[_idx];
00575         case 0:
00576           return cubicKernel1[_idx];
00577         case 1:
00578           return cubicKernel1[cubicKernelResolution - _idx];
00579         case 2:
00580           return cubicKernel2[cubicKernelResolution - _idx];
00581       }
00582       return 0;
00583     }
00584     inline double Image::cubicKernel( int _t, double _dt ) const
00585     {
00586       int idx =int (_dt * cubicKernelResolution );
00587       return cubicKernelI( _t, idx );
00588     }
00589     
00590     template<typename channeltype>
00591     double Image::getSubPixelValue(double x_, double y_, int channel_, JfrImage_InterpolationType _interpolation ) const {
00592       int height_ = height();
00593       int width_ = width();
00594       JFR_PRECOND(x_ >= 0. && y_ >= 0. && x_ <= (double)width_ - 1 && y_ <= (double)height_ - 1, 
00595                   "JfrImage::pixelValue pixel coordinates are not in the image.");
00596       JFR_PRECOND( 0 <= channel_ && channel_ < channels(), "JfrImage::getSubpixelValue wrong channel parameter ");
00597       if( x_ == width() - 1) x_ -= 1e-6;
00598       if( y_ == height() - 1) y_ -= 1e-6;
00599   
00600       switch( _interpolation )
00601       {
00602         case JfrImage_INTERP_NEAREST:
00603         {
00604           return getPixelValue<channeltype>( lrint( x_ ), lrint( y_ ), channel_ );
00605         }
00606         case JfrImage_INTERP_BILINEAR:
00607         {
00608           int xi = (int)floor(x_);
00609           int yi = (int)floor(y_);
00610       
00611           double dx = x_-floor(x_);
00612           double dy = y_-floor(y_);
00613           double c11 = (1-dx)*(1-dy);
00614           double c12 = (1-dy)*dx;
00615           double c21 = (1-dx)*dy;
00616           double c22 = dx*dy;
00617       
00618           return (
00619               c11 * getPixelValue<channeltype>(xi,yi, channel_)
00620               + c12 * getPixelValue<channeltype>(xi+1,yi, channel_)
00621               + c21 * getPixelValue<channeltype>(xi,yi+1, channel_)
00622               + c22 * getPixelValue<channeltype>(xi+1,yi+1, channel_));
00623         }
00624         case JfrImage_INTERP_CUBIC:
00625         {
00626           double result = 0.0;
00627           int xi = int(x_);
00628           int yi = int(y_);
00629           double dx = x_ - xi;
00630           int idxX =int( dx * cubicKernelResolution );
00631           double dy = y_ - yi;
00632           int idxY =int( dy * cubicKernelResolution );
00633           int channelsCount = channels();
00634           int offset = (xi - 1) * channelsCount + channel_;
00635           for(int v = -1; v < 3; ++v)
00636           {
00637             int yt = yi + v;
00638             if( yt >= 0 and yt < height_ )
00639             {
00640               channeltype const *pxPtr = reinterpret_cast<channeltype const *>(data(yt));
00641               pxPtr += offset;
00642               
00643               double ycoef = cubicKernelI( v, idxY);
00644               for(int u = -1; u < 3; ++u, pxPtr += channelsCount)
00645               {
00646                 int xt = xi + u;
00647                 if( xt >= 0 and xt < width_ ) // TODO use a better value than 0 when out of range
00648                 {
00649                   result += ycoef * cubicKernelI( u, idxX ) * *pxPtr;
00650                 }
00651               }
00652             }
00653           }
00654           return result;
00655         }
00656       }
00657       return -1;
00658     }
00659     
00660     template<typename channeltype>
00661     void Image::setPixelValue(channeltype val_, int x_, int y_, int channel_) {
00662       JFR_PRECOND(x_ >= 0 && y_ >= 0 && x_ < width() && y_ < height(), 
00663           "JfrImage::pixelValue pixel coordinates are not in the image.");
00664       JFR_PRECOND( 0 <= channel_ && channel_ < channels(), "JfrImage::pixelValue "
00665           "wrong channel parameter ");
00666       channeltype *pxPtr = reinterpret_cast<channeltype*>(data(y_));
00667       *(pxPtr+ x_ * channels() + channel_) = val_;
00668     }
00669 
00670     std::ostream& operator<<(std::ostream& s, const Image& image);
00671     std::ostream& operator<<(std::ostream& s, const JfrImage_TypeColorSpace tcs);
00672 
00682     class ImageIO {
00683     public:
00684       static void xml_load(jafar::image::Image & img, std::string const & filename);
00685       static void xml_save(jafar::image::Image & img, std::string const & filename);
00686       static void bin_load(jafar::image::Image & img, std::string const & filename);
00687       static void bin_save(jafar::image::Image & img, std::string const & filename);
00688     private:
00689       ImageIO() {};
00690     }; /* ImageIO */
00691     
00692   } /* image */
00693 } /* jafar */
00694 
00695 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:21 for Jafar by doxygen 1.7.6.1
LAAS-CNRS