cvd/draw.h

00001 /*
00002         This file is part of the CVD Library.
00003 
00004         Copyright (C) 2005 The Authors
00005 
00006         This library is free software; you can redistribute it and/or
00007         modify it under the terms of the GNU Lesser General Public
00008         License as published by the Free Software Foundation; either
00009         version 2.1 of the License, or (at your option) any later version.
00010 
00011         This library is distributed in the hope that it will be useful,
00012         but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014         Lesser General Public License for more details.
00015 
00016         You should have received a copy of the GNU Lesser General Public
00017         License along with this library; if not, write to the Free Software
00018         Foundation, Inc.,
00019     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 */
00021 
00022 #ifndef CVD_DRAW_H_
00023 #define CVD_DRAW_H_
00024 
00025 #include <cvd/exceptions.h>
00026 #include <cvd/image.h>
00027 #include <cvd/image_ref.h>
00028 #include <cvd/internal/builtin_components.h>
00029 #include <cvd/internal/rgb_components.h>
00030 #include <cvd/image_convert.h>
00031 #include <cvd/utility.h>
00032 #include <vector>
00033 #include <algorithm>
00034 
00035 #include <cvd/config.h>
00036 #ifdef CVD_HAVE_TOON
00037 #include <TooN/TooN.h>
00038 #endif
00039 
00040 
00041 namespace CVD {
00042 
00043 namespace Exceptions {
00044 
00047     namespace Draw {
00050         struct All: public CVD::Exceptions::All {};
00051 
00054         struct ImageRefNotInImage : public All {
00055             ImageRefNotInImage(const std::string & function)
00056             {
00057                 what = "Input ImageRefs not in image in " + function;
00058             };
00059         };
00060 
00063         struct IncompatibleImageSizes : public All {
00064             IncompatibleImageSizes(const std::string & function)
00065             {
00066                 what = "Incompatible image sizes in " + function;
00067             };
00068         };
00069     };
00070 };
00071 
00074 template <class T, unsigned int N=Pixel::Component<T>::count> struct color {};
00075 
00079 template <class T> struct color<T,1> {
00080     typedef typename Pixel::Component<T>::type TComp;
00082     inline static const T& black() { static T c; Pixel::Component<T>::get(c,0) = 0; return c;}
00084     inline static const T& gray() { static T c; Pixel::Component<T>::get(c,0) = Pixel::traits<TComp>::max_intensity/2; return c;}
00086     inline static const T& white() { static T c; Pixel::Component<T>::get(c,0) = Pixel::traits<TComp>::max_intensity; return c;}
00087 };
00088 
00093 template <class T> struct color<T,3> {
00094     typedef typename Pixel::Component<T>::type TComp;
00095     static const TComp hi;
00096     inline static T make(const TComp& a, const TComp& b, const TComp& c) { 
00097     T t; 
00098     Pixel::Component<T>::get(t,0)=a;
00099     Pixel::Component<T>::get(t,1)=b;
00100     Pixel::Component<T>::get(t,2)=c;
00101     return t;
00102     }
00103     inline static const T&   black() { static const T c = make(0,0,0); return c;}
00104     inline static const T&   white() { static const T c = make(hi,hi,hi); return c;}
00105     inline static const T&     red() { static const T c = make(hi,0,0); return c;}
00106     inline static const T&   green() { static const T c = make(0,hi,0); return c;}
00107     inline static const T&    blue() { static const T c = make(0,0,hi); return c;}
00108     inline static const T&    cyan() { static const T c = make(0,hi,hi); return c; }
00109     inline static const T& magenta() { static const T c = make(hi,0,hi); return c;}
00110     inline static const T&  yellow() { static const T c = make(hi,hi,0); return c;}
00111     inline const T& shade(const T& c, double b) {
00112     return make((TComp)(Pixel::Component<T>::get(c,0)*b), (TComp)(Pixel::Component<T>::get(c,1)*b), (TComp)(Pixel::Component<T>::get(c,2)*b));
00113     }
00114 };
00115  template <class T> const typename color<T,3>::TComp color<T,3>::hi = Pixel::traits<TComp>::max_intensity;
00116 
00117 
00126 template <class T>
00127 void drawLine(Image<T>& im, double x1, double y1, double x2, double y2, const T& c)
00128 {
00129     double dx = x2-x1;
00130     double dy = y2-y1;
00131     int w = im.size().x;
00132     int h = im.size().y;
00133     double len = abs(dx)+abs(dy);
00134     for(int t=0;t<=len;t++) {
00135         int x = (int)(x1 + t/(len)*dx+0.5);
00136         int y = (int)(y1 + t/(len)*dy+0.5);
00137         if (x >=0 && x <w && y>=0 && y<h)
00138       im[y][x] = c;
00139     }
00140 }
00141 
00148 template <class T>
00149 void drawLine(Image<T>& im, const ImageRef& p1, const ImageRef& p2, const T& c)
00150 {
00151     drawLine(im, double(p1.x), double(p1.y), double(p2.x), double(p2.y), c);
00152 }
00153 
00154 #ifdef CVD_HAVE_TOON
00161 template <class T>
00162 void drawLine(Image<T>& im, const TooN::Vector<2>& p1, const TooN::Vector<2>& p2, const T& c)
00163 {
00164     drawLine(im, p1[0], p1[1], p2[0], p2[1], c);
00165 }
00166 #endif
00167 
00168 
00169 
00177 template <class T>
00178 void drawShape(Image<T>& im, const ImageRef& offset, const std::vector<ImageRef>& points, const T& c)
00179 {
00180     for (unsigned int i=0; i<points.size()-1; i++)
00181         drawLine(im, points[i]+offset, points[i+1]+offset, c);
00182     drawLine(im, points.back()+offset, points.front()+offset, c);
00183 }
00184 
00191 template <class T>
00192 void drawBox(Image<T> &im, const ImageRef & upperleft, const ImageRef & lowerright, const T& c)
00193 {
00194     drawLine(im, upperleft.x, upperleft.y, upperleft.x, lowerright.y, c);
00195     drawLine(im, upperleft.x, upperleft.y, lowerright.x, upperleft.y, c);
00196     drawLine(im, upperleft.x, lowerright.y, lowerright.x, lowerright.y, c);
00197     drawLine(im, lowerright.x, upperleft.y, lowerright.x, lowerright.y, c);
00198 }
00199 
00206 template <class T>
00207 void drawCross(Image<T>& im, const ImageRef& p, double len, const T& c)
00208 {
00209     drawLine(im, p.x-len, p.y, p.x+len, p.y, c);
00210     drawLine(im, p.x, p.y-len, p.x, p.y+len, c);
00211 }
00212 
00218 std::vector<ImageRef> getCircle(int radius);
00219 
00220 
00226 std::vector<ImageRef> getDisc(float radius);
00227 
00228 
00234 template <class S, class T, class U> void joinImages(const Image<S>& a, const Image<T>& b, Image<U>& J) {
00235   int h = std::max(a.size().y,b.size().y);
00236     J.resize(ImageRef(a.size().x+b.size().x, h));
00237     CVD::copy(a, J, a.size());
00238     CVD::copy(b, J, b.size(), ImageRef(), ImageRef(a.size().x, 0));
00239     ImageRef blackBegin, blackEnd;
00240     if (a.size().y < b.size().y) {
00241         blackBegin = ImageRef(0,a.size().y);
00242         blackEnd = ImageRef(a.size().x,J.size().y);
00243     } else {
00244         blackBegin = ImageRef(a.size().x, b.size().y);
00245         blackEnd = J.size();
00246     }
00247     for (int i = blackBegin.y; i<blackEnd.y; i++)
00248       for (int j= blackBegin.x; j<blackEnd.x; j++)
00249     J[i][j] = U();
00250 }
00251 
00252 
00259 template <class S, class T, class U> void combineImages(const Image<S>& a, const Image<T>& b, Image<U>& out, const ImageRef & dst = ImageRef_zero, ImageRef size = ImageRef(), const ImageRef & from = ImageRef_zero)
00260 {
00261     if(!a.in_image(dst))
00262         throw Exceptions::Draw::ImageRefNotInImage("combineImages");
00263     if(a.size() != out.size)
00264         throw Exceptions::Draw::IncompatibleImageSizes("combineImages");
00265 
00266     if( size == ImageRef_zero )
00267         size = b.size();
00268 
00269     if (size.x + dst.x >= a.size().x)
00270       size.x = a.size().x - dst.x;
00271     if (size.x + dst.x >= out.size().x)
00272       size.x = out.size().x - dst.x;
00273     if (size.y + dst.y >= a.size().y)
00274       size.y = a.size().y - dst.y;
00275     if (size.y + dst.y >= out.size().y)
00276       size.y = out.size().y - dst.y;
00277 
00278     if( &a != &out )
00279     {
00280         CVD::copy(a,out, a.size());
00281     }
00282 
00283     ImageRef sourceA = dst;
00284     ImageRef sourceB = from;
00285     ImageRef endA = dst + size;
00286     ImageRef endB = from + size;
00287 
00288     out[sourceA] += b[sourceB];
00289     while(sourceA.next(dst, endA))
00290     {
00291         sourceB.next(from, endB);
00292         out[sourceA] += b[sourceB];
00293     }
00294 }
00295 
00296 };
00297 #endif // CVD_DRAW_H_

Generated on Wed Feb 18 10:23:00 2009 for CVD by  doxygen 1.5.3