Changeset 79


Ignore:
Timestamp:
05/08/2009 02:06:23 PM (11 years ago)
Author:
dave
Message:

made an image class

Location:
foam/trunk/experiments/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • foam/trunk/experiments/src/ImageUtils.cpp

    r72 r79  
    1818 
    1919#include <iostream> 
     20#include "highgui.h" 
     21 
    2022using namespace std; 
    2123 
    22 ///////////////////////////////////////////////////////////// 
    23 // deep copy a sub image 
    24  
    25 IplImage* SubImage(IplImage *image, CvRect roi) 
    26 { 
    27         IplImage *result; 
    28         cvSetImageROI(image,roi); 
    29         result = cvCreateImage( cvSize(roi.width, roi.height), image->depth, image->nChannels ); 
    30         cvCopy(image,result); 
    31         cvResetImageROI(image); 
    32         return result; 
    33 } 
    34  
    35 ///////////////////////////////////////////////////////////// 
     24Image::Image(int w, int h, int d, int c) 
     25{ 
     26        cvCreateImage(cvSize(w, h), d, c); 
     27} 
     28 
     29Image::Image(const string &filename) 
     30{ 
     31        m_Image=cvLoadImage(filename.c_str()); 
     32} 
     33 
     34Image::Image(const Image *other) 
     35{ 
     36        m_Image=cvCloneImage(other->m_Image); 
     37} 
     38 
     39Image::~Image() 
     40{ 
     41        cvReleaseImage(&m_Image); 
     42} 
     43 
    3644// safe accessor, which returns 0 if out of range 
    37  
    38 unsigned char SafeGet2D(IplImage *image, int y, int x, int c) 
    39 { 
    40         CvSize size = cvGetSize(image); 
    41         if (x<0 || x>=size.width || y<0 || y>=size.height) 
     45unsigned char Image::SafeGet2D(int y, int x, int c) 
     46{ 
     47        if (x<0 || x>=m_Image->width || y<0 || y>=m_Image->height) 
    4248        { 
    4349                return 0; 
    4450        } 
    4551         
    46         return cvGet2D(image,y,x).val[c]; 
    47 } 
    48  
    49 ///////////////////////////////////////////////////////////// 
    50 // paste an image over the top of another 
    51  
    52 void BlitImage(IplImage *srcimage, IplImage *dstimage, CvPoint pos) 
    53 { 
    54         CvSize size = cvGetSize(srcimage); 
    55         CvSize dstsize = cvGetSize(dstimage); 
    56          
    57         for(int y=0; y<size.height; y++) 
    58         { 
    59         for(int x=0; x<size.width; x++) 
    60                 { 
    61                         if (x+pos.x>0 && x+pos.x<dstsize.width && 
    62                                 y+pos.y>0 && y+pos.y<dstsize.height) 
    63                         { 
    64                 cvSet2D(dstimage,y+pos.y,x+pos.x,cvGet2D(srcimage,y,x)); 
    65                         } 
    66                 } 
    67         } 
    68 } 
    69  
    70 ///////////////////////////////////////////////////////////// 
    71 // subtract the mean (RGB) 
    72  
    73 void SubMean(IplImage *image) 
    74 { 
    75         CvSize size = cvGetSize(image); 
    76  
    77         float r=0; 
    78         float g=0; 
    79         float b=0; 
    80  
    81         float s=size.width*size.height; 
    82  
    83     for(int y=0; y<size.height; y++) 
    84         { 
    85         for(int x=0; x<size.width; x++) 
    86                 { 
    87             r+=cvGet2D(image,y,x).val[0]/256.0f; 
    88             g+=cvGet2D(image,y,x).val[1]/256.0f; 
    89             b+=cvGet2D(image,y,x).val[2]/256.0f; 
    90                 } 
    91         } 
    92          
    93         r/=s; 
    94         g/=s; 
    95         b/=s; 
     52        return cvGet2D(m_Image,y,x).val[c]; 
     53} 
     54 
     55void Image::PrintInfo() 
     56{ 
     57        cerr<<m_Image->width<<"x"<<m_Image->height<<"x"<<m_Image->nChannels 
     58                <<" @ "<<m_Image->depth<<" bpp"<<endl; 
     59} 
     60 
     61void Image::Crop(int x, int y, int w, int h) 
     62{ 
     63        CvRect roi; 
     64        roi.x=x; 
     65        roi.y=y; 
     66        roi.width=w; 
     67        roi.height=h; 
     68        IplImage *newimage; 
     69        cvSetImageROI(m_Image,roi); 
     70        newimage = cvCreateImage( cvSize(roi.width, roi.height), m_Image->depth, m_Image->nChannels ); 
     71        cvCopy(m_Image,newimage); 
     72        cvReleaseImage(&m_Image); 
     73        m_Image=newimage; 
     74} 
     75 
     76void Image::GRAY2RGB() 
     77{ 
     78        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3); 
     79    cvCvtColor(m_Image, newimage, CV_GRAY2RGB); 
     80        cvReleaseImage(&m_Image); 
     81        m_Image=newimage; 
     82} 
     83 
     84void Image::RGB2GRAY() 
     85{ 
     86        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 1); 
     87    cvCvtColor(m_Image, newimage, CV_RGB2GRAY); 
     88        cvReleaseImage(&m_Image); 
     89        m_Image=newimage; 
     90} 
     91 
     92void Image::BayerGB2RGB() 
     93{ 
     94        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3); 
     95    cvCvtColor(m_Image, newimage, CV_BayerGB2RGB); 
     96        cvReleaseImage(&m_Image); 
     97        m_Image=newimage; 
     98} 
     99 
     100void Image::Scale(int w, int h) 
     101{ 
     102        IplImage *newimage = cvCreateImage(cvSize(w,h), m_Image->depth, m_Image->nChannels); 
     103        cvResize( m_Image, newimage, CV_INTER_LINEAR ); 
     104        cvReleaseImage(&m_Image); 
     105        m_Image=newimage; 
     106} 
     107 
     108void Image::Blit(const Image &image, CvPoint pos) 
     109{        
     110        for(int y=0; y<image.m_Image->height; y++) 
     111        { 
     112        for(int x=0; x<image.m_Image->width; x++) 
     113                { 
     114                        if (x+pos.x>0 && x+pos.x<m_Image->width && 
     115                                y+pos.y>0 && y+pos.y<m_Image->height) 
     116                        { 
     117                cvSet2D(m_Image,y+pos.y,x+pos.x,cvGet2D(image.m_Image,y,x)); 
     118                        } 
     119                } 
     120        } 
     121} 
     122 
     123void Image::SubMean() 
     124{        
     125        // get the mean of each channel 
     126        CvScalar v; 
     127        for (int c=0; c<m_Image->nChannels; c++) 
     128        { 
     129                v.val[c]=0; 
     130        } 
     131 
     132        float s=m_Image->width*m_Image->height; 
     133 
     134    for(int y=0; y<m_Image->height; y++) 
     135        { 
     136        for(int x=0; x<m_Image->width; x++) 
     137                { 
     138                        for (int c=0; c<m_Image->nChannels; c++) 
     139                        { 
     140                                v.val[c]+=cvGet2D(m_Image,y,x).val[c]/256.0f; 
     141                        } 
     142                } 
     143        } 
     144         
     145        for (int c=0; c<m_Image->nChannels; c++) 
     146        { 
     147                v.val[c]/=s; 
     148        } 
     149         
     150        // now subtract it from each pixel 
     151        for(int y=0; y<m_Image->height; y++) 
     152        { 
     153        for(int x=0; x<m_Image->width; x++) 
     154                { 
     155                        for (int c=0; c<m_Image->nChannels; c++) 
     156                        { 
     157                                // force the average to be 127 
     158                                v.val[c]=127+(cvGet2D(m_Image,y,x).val[c] - v.val[c]*256.0f); 
     159                        } 
    96160                 
    97         for(int y=0; y<size.height; y++) 
    98         { 
    99         for(int x=0; x<size.width; x++) 
    100                 { 
    101             cvSet2D(image,y,x,cvScalar(127+(cvGet2D(image,y,x).val[0] - r*256.0f), 
    102                                                                            127+(cvGet2D(image,y,x).val[1] - g*256.0f), 
    103                                                                            127+(cvGet2D(image,y,x).val[2] - b*256.0f))); 
    104                 } 
    105         } 
    106 } 
    107  
    108 ///////////////////////////////////////////////////////////// 
    109 // return a diff metric between two images (works in RGB) 
    110  
    111 float Diff(IplImage *imagea, IplImage *imageb) 
    112 { 
    113         CvSize sizea = cvGetSize(imagea); 
    114         CvSize sizeb = cvGetSize(imageb); 
    115          
    116         assert(sizea.width == sizeb.width); 
    117         assert(sizea.height == sizeb.height); 
     161            cvSet2D(m_Image,y,x,v); 
     162                } 
     163        } 
     164} 
     165 
     166float Image::SSD(Image &other) 
     167{ 
     168        assert(other.m_Image->width == m_Image->width); 
     169        assert(other.m_Image->height == m_Image->height); 
    118170         
    119171        float ret=0; 
    120  
    121     for(int y=0; y<sizea.height; y++) 
    122         { 
    123         for(int x=0; x<sizea.width; x++) 
    124                 { 
    125             ret+=fabs((cvGet2D(imagea,y,x).val[0]/256.0f)-(cvGet2D(imageb,y,x).val[0]/256.0f)); 
    126             ret+=fabs((cvGet2D(imagea,y,x).val[1]/256.0f)-(cvGet2D(imageb,y,x).val[1]/256.0f)); 
    127             ret+=fabs((cvGet2D(imagea,y,x).val[2]/256.0f)-(cvGet2D(imageb,y,x).val[2]/256.0f)); 
    128                 } 
    129         } 
    130         ret/=sizea.width*sizea.height*3; 
     172        float dif=0; 
     173         
     174    for(int y=0; y<m_Image->height; y++) 
     175        { 
     176        for(int x=0; x<m_Image->width; x++) 
     177                { 
     178                        for (int c=0; c<m_Image->nChannels; c++) 
     179                        { 
     180                                dif = (cvGet2D(m_Image,y,x).val[c]/256.0f) -  
     181                                      (cvGet2D(other.m_Image,y,x).val[c]/256.0f); 
     182                ret+=dif*dif; 
     183            } 
     184                } 
     185        } 
     186         
     187        // not sure strictly whether the difference should be 
     188        // invariant to the number of pixels, but it helps 
     189        ret/=m_Image->width*m_Image->height*m_Image->nChannels; 
     190         
    131191        return ret; 
    132192} 
    133193 
    134  
    135  
    136 ///////////////////////////////////////////////////////////// 
    137 // return a local binary patterns image of the src image 
    138  
    139  
    140 void LBPImage(IplImage *srcimage, IplImage *dstimage) 
    141 { 
    142         CvSize srcsize = cvGetSize(srcimage); 
    143         CvSize dstsize = cvGetSize(dstimage); 
    144          
    145         assert(srcsize.width == dstsize.width); 
    146         assert(srcsize.height == dstsize.height); 
    147         assert(srcimage->nChannels == dstimage->nChannels); 
    148  
     194void Image::LBP() 
     195{ 
     196        IplImage *newimage; 
     197        newimage = cvCreateImage(cvGetSize(m_Image), m_Image->depth, m_Image->nChannels); 
     198                 
    149199    // for each pixel 
    150     for(int y=0; y<srcsize.height; y++) 
    151         { 
    152         for(int x=0; x<srcsize.width; x++) 
     200    for(int y=0; y<m_Image->height; y++) 
     201        { 
     202        for(int x=0; x<m_Image->width; x++) 
    153203                { 
    154204                        CvScalar sc; 
    155205                         
    156206                        // for each channel 
    157                         for(int c=0; c<dstimage->nChannels; c++) 
     207                        for(int c=0; c<m_Image->nChannels; c++) 
    158208                        { 
    159209                                unsigned char v=0; 
    160                                 unsigned char o=cvGet2D(srcimage,y,x).val[c]; 
     210                                unsigned char o=cvGet2D(m_Image,y,x).val[c]; 
    161211                                unsigned char b=0; 
    162212 
     
    170220                                                { 
    171221                                                        // threshold 
    172                                                         if (o>SafeGet2D(srcimage,y+ky,x+kx,c)) 
     222                                                        if (o>SafeGet2D(y+ky,x+kx,c)) 
    173223                                                        { 
    174224                                                                // bit magic 
     
    181231                                sc.val[c]=v; 
    182232                        } 
    183                         cvSet2D(dstimage,y,x,sc); 
    184                 } 
    185         } 
    186 } 
    187  
    188 ///////////////////////////////////////////////////////////// 
    189 // calculate a histogram 
    190  
    191 unsigned int *HistMono8Bit(IplImage *image) 
    192 { 
    193         assert(image->nChannels == 1); 
    194         assert(image->depth == 8); 
    195         CvSize size = cvGetSize(image); 
    196  
     233                        cvSet2D(newimage,y,x,sc); 
     234                } 
     235        } 
     236         
     237        cvReleaseImage(&m_Image); 
     238        m_Image=newimage; 
     239} 
     240 
     241unsigned int *Image::Hist(int channel) 
     242{ 
     243        assert(channel<m_Image->nChannels); 
     244        assert(m_Image->depth == 8); 
     245         
    197246        unsigned int *h=new unsigned int[256]; 
    198247 
     
    203252 
    204253    // for each pixel 
    205     for(int y=0; y<size.height; y++) 
    206         { 
    207         for(int x=0; x<size.width; x++) 
    208                 { 
    209                         h[(unsigned char)cvGet2D(image,y,x).val[0]]++; 
     254    for(int y=0; y<m_Image->height; y++) 
     255        { 
     256        for(int x=0; x<m_Image->width; x++) 
     257                { 
     258                         
     259                        h[(unsigned char)cvGet2D(m_Image,y,x).val[channel]]++; 
    210260                } 
    211261        } 
     
    214264} 
    215265 
    216 ///////////////////////////////////////////////////////////// 
    217 // draw a histogram 
    218  
    219 void DrawHistogram8(int x, int y, float scale, CvScalar colour, unsigned int *h, IplImage *img) 
    220 { 
    221         for(int i=0; i<256; i++) 
    222         { 
    223                 cvLine(img, cvPoint(x+i,y),cvPoint(x+i,y+h[i]*-scale), colour);  
    224         } 
    225 } 
  • foam/trunk/experiments/src/ImageUtils.h

    r72 r79  
    1616 
    1717#include "cv.h" 
    18 #include "highgui.h" 
     18#include <string> 
    1919 
    20 #ifndef IMAGE_UTILS 
    21 #define IMAGE_UTILS 
     20#ifndef IMAGE 
     21#define IMAGE 
    2222 
    23 // I need to sort this out before it grows too much... 
     23class Image 
     24{ 
     25public: 
     26        Image(int w, int h, int d, int c); 
     27        Image(const std::string &filename); 
     28        Image(const Image *other); 
     29        ~Image(); 
    2430 
    25 IplImage* SubImage(IplImage *image, CvRect roi); 
    26 void BlitImage(IplImage *srcimage, IplImage *dstimage, CvPoint pos); 
    27 void SubMean(IplImage *image); 
    28 float Diff(IplImage *imagea, IplImage *imageb); 
    29 void LBPImage(IplImage *srcimage, IplImage *dstimage); 
    30 unsigned int *HistMono8Bit(IplImage *image); 
     31        void PrintInfo(); 
     32         
     33        void Crop(int x, int y, int w, int h); 
     34        void Scale(int w, int h); 
    3135 
    32 void DrawHistogram8(int x, int y, float scale, CvScalar colour, unsigned int *h, IplImage *img); 
     36        // Paste an image into this one 
     37        void Blit(const Image &image, CvPoint pos); 
     38         
     39        // Return a sum of squared differences, for giving a similarity metric  
     40        float SSD(Image &other); 
     41         
     42        // Subtract the mean - this is useful for accounting for global lighting changes 
     43        void SubMean(); 
     44         
     45        // Convert the image into a local binary patterns image 
     46        void LBP(); 
     47         
     48        // Convert to different colour spaces 
     49        void GRAY2RGB(); 
     50        void RGB2GRAY(); 
     51        void BayerGB2RGB(); 
     52         
     53        // Calculate a histogram for a given channel 
     54        unsigned int *Hist(int channel); 
     55         
     56        IplImage *m_Image; 
     57         
     58private: 
     59        unsigned char SafeGet2D(int y, int x, int c); 
     60}; 
    3361 
    3462#endif 
  • foam/trunk/experiments/src/main.cpp

    r72 r79  
    150150        {{255,0,255}} 
    151151    }; 
    152          
     152/* 
    153153void lpbhist(int x, int y, IplImage* img, IplImage* mainimg) 
    154154{ 
     
    164164        cvReleaseImage( &gray ); 
    165165} 
    166  
     166*/ 
    167167void detect_and_draw( IplImage* img ) 
    168168{ 
     
    178178    cvEqualizeHist( small_img, small_img ); 
    179179    cvClearMemStorage( storage ); 
    180   
     180         
     181        Image im("bayer.pgm"); 
     182        im.Crop(300,300,320,240); 
     183        im.RGB2GRAY(); 
     184        //im.PrintInfo(); 
     185        im.BayerGB2RGB(); 
     186    cvShowImage( "result", im.m_Image ); 
     187         
     188/*  
    181189        IplImage *li = cvLoadImage("test3-0.png"); 
    182190        lpbhist(0, 0, li, gray); 
     
    190198        lpbhist(200, 0, li, gray); 
    191199        cvReleaseImage( &li ); 
    192  
    193     cvShowImage( "result", gray ); 
     200*/ 
    194201    cvReleaseImage( &gray ); 
    195202    cvReleaseImage( &small_img ); 
Note: See TracChangeset for help on using the changeset viewer.