source: foam/trunk/vision/src/Image.cpp @ 95

Revision 95, 8.3 KB checked in by dave, 10 years ago (diff)

eigenface user classification seems to work on the test video

RevLine 
[72]1// Copyright (C) 2009 foam
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
[80]17#include "Image.h"
[72]18
19#include <iostream>
[79]20#include "highgui.h"
21
[72]22using namespace std;
23
[79]24Image::Image(int w, int h, int d, int c)
25{
[86]26        m_Image=cvCreateImage(cvSize(w, h), d, c);
[79]27}
[72]28
[79]29Image::Image(const string &filename)
[72]30{
[79]31        m_Image=cvLoadImage(filename.c_str());
[93]32        if (m_Image==NULL) cerr<<"Could not open image: "<<filename<<endl;
[85]33        assert(m_Image);
[72]34}
35
[85]36Image::Image(const Image &other)
[79]37{
[85]38        m_Image=cvCloneImage(other.m_Image);
[79]39}
[72]40
[85]41Image::Image(const IplImage *other)
42{
43        m_Image=cvCloneImage(other);
44}
45
[89]46Image::Image(int w, int h, int c, const Vector<float> &v, float gain)
[86]47{
48        m_Image=cvCreateImage(cvSize(w, h), 8, c);
49        unsigned int pos=0;
50        for(int y=0; y<m_Image->height; y++)
51        {
52        for(int x=0; x<m_Image->width; x++)
53                {
54                        CvScalar s;
55                        for (int c=0; c<m_Image->nChannels; c++)
56                        {
[89]57                                s.val[c]=(0.5+v[pos++]*gain)*127.0f;
[86]58                        }
59                        cvSet2D(m_Image,y,x,s);
60                }
61        }
62}
63
[79]64Image::~Image()
[72]65{
[79]66        cvReleaseImage(&m_Image);
67}
68
[85]69void Image::Clear()
70{
71    for(int y=0; y<m_Image->height; y++)
72        {
73        for(int x=0; x<m_Image->width; x++)
74                {
75                        CvScalar v;
76                       
77                        for (int c=0; c<m_Image->nChannels; c++)
78                        {
79                                v.val[c]=0;
80                        }
81                                               
82                        cvSet2D(m_Image,y,x,v);
83                }
84        }
85}
86
87Image Image::operator-(const Image &other)
88{
89        assert(other.m_Image->width == m_Image->width);
90        assert(other.m_Image->height == m_Image->height);
91        assert(other.m_Image->nChannels == m_Image->nChannels);
92
93        Image ret(*this);
94
95    for(int y=0; y<m_Image->height; y++)
96        {
97        for(int x=0; x<m_Image->width; x++)
98                {
99                        CvScalar v;
100                        v.val[0]=0;v.val[1]=0;v.val[2]=0;v.val[3]=0;
101                        for (int c=0; c<m_Image->nChannels; c++)
102                        {
103                                v.val[c]=abs((int)(cvGet2D(m_Image,y,x).val[c] -
104                                                   cvGet2D(other.m_Image,y,x).val[c]));         
105                        }
106                        cvSet2D(ret.m_Image,y,x,v);
107                }
108        }
109        return ret;
110}
111
112Image Image::operator+(const Image &other)
113{
114        assert(other.m_Image->width == m_Image->width);
115        assert(other.m_Image->height == m_Image->height);
116        assert(other.m_Image->nChannels == m_Image->nChannels);
117
118        Image ret(*this);
119
120    for(int y=0; y<m_Image->height; y++)
121        {
122        for(int x=0; x<m_Image->width; x++)
123                {
124                        CvScalar v;
125                        for (int c=0; c<m_Image->nChannels; c++)
126                        {
127                                v.val[c]=cvGet2D(m_Image,y,x).val[c] +
128                                         cvGet2D(other.m_Image,y,x).val[c];             
129                        }
130                        cvSet2D(&ret,y,x,v);
131                }
132        }
133       
134        return ret;
135}
136
[90]137Image &Image::operator=(const Image &other)
138{
139        m_Image=cvCloneImage(other.m_Image);
140        return *this;
141}
142
[79]143// safe accessor, which returns 0 if out of range
144unsigned char Image::SafeGet2D(int y, int x, int c)
145{
146        if (x<0 || x>=m_Image->width || y<0 || y>=m_Image->height)
[72]147        {
148                return 0;
149        }
150       
[79]151        return cvGet2D(m_Image,y,x).val[c];
[72]152}
153
[79]154void Image::PrintInfo()
155{
156        cerr<<m_Image->width<<"x"<<m_Image->height<<"x"<<m_Image->nChannels
157                <<" @ "<<m_Image->depth<<" bpp"<<endl;
158}
[72]159
[79]160void Image::Crop(int x, int y, int w, int h)
[72]161{
[79]162        CvRect roi;
163        roi.x=x;
164        roi.y=y;
165        roi.width=w;
166        roi.height=h;
167        IplImage *newimage;
168        cvSetImageROI(m_Image,roi);
169        newimage = cvCreateImage( cvSize(roi.width, roi.height), m_Image->depth, m_Image->nChannels );
170        cvCopy(m_Image,newimage);
171        cvReleaseImage(&m_Image);
172        m_Image=newimage;
173}
174
[94]175Image Image::SubImage(int x, int y, int w, int h)
176{
177        CvRect roi;
178        roi.x=x;
179        roi.y=y;
180        roi.width=w;
181        roi.height=h;
182        IplImage *newimage;
183        cvSetImageROI(m_Image,roi);
184        newimage = cvCreateImage( cvSize(roi.width, roi.height), m_Image->depth, m_Image->nChannels );
[95]185        cvCopy(m_Image,newimage);       
186        cvResetImageROI(m_Image);
[94]187        return newimage;
188}
189
[86]190Image Image::GRAY2RGB()
[79]191{
192        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3);
193    cvCvtColor(m_Image, newimage, CV_GRAY2RGB);
[86]194        return Image(newimage);
[79]195}
196
[86]197Image Image::RGB2GRAY()
[79]198{
199        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 1);
200    cvCvtColor(m_Image, newimage, CV_RGB2GRAY);
[86]201        return Image(newimage);
[79]202}
203
[86]204Image Image::BayerGB2RGB()
[79]205{
206        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3);
207    cvCvtColor(m_Image, newimage, CV_BayerGB2RGB);
[86]208        return Image(newimage);
[79]209}
210
[86]211Image Image::Scale(int w, int h)
[79]212{
213        IplImage *newimage = cvCreateImage(cvSize(w,h), m_Image->depth, m_Image->nChannels);
214        cvResize( m_Image, newimage, CV_INTER_LINEAR );
[86]215        return Image(newimage);
[79]216}
217
[85]218void Image::Blit(const Image &image, int px, int py)
[79]219{       
220        for(int y=0; y<image.m_Image->height; y++)
[72]221        {
[79]222        for(int x=0; x<image.m_Image->width; x++)
[72]223                {
[85]224                        if (x+px>0 && x+px<m_Image->width &&
225                                y+py>0 && y+py<m_Image->height)
[72]226                        {
[89]227                if (image.m_Image->nChannels==1)
228                                {
229                                        CvScalar v;
230                                        v.val[0]=cvGet2D(image.m_Image,y,x).val[0];
231                                        v.val[1]=cvGet2D(image.m_Image,y,x).val[0];
232                                        v.val[2]=cvGet2D(image.m_Image,y,x).val[0];
233                        cvSet2D(m_Image,y+py,x+px,v);
234                                }
235                                else
236                                {
237                                        cvSet2D(m_Image,y+py,x+px,cvGet2D(image.m_Image,y,x));
238                                }
[72]239                        }
240                }
241        }
242}
243
[79]244void Image::SubMean()
245{       
246        // get the mean of each channel
247        CvScalar v;
248        for (int c=0; c<m_Image->nChannels; c++)
249        {
250                v.val[c]=0;
251        }
[72]252
[79]253        float s=m_Image->width*m_Image->height;
[72]254
[79]255    for(int y=0; y<m_Image->height; y++)
[72]256        {
[79]257        for(int x=0; x<m_Image->width; x++)
[72]258                {
[79]259                        for (int c=0; c<m_Image->nChannels; c++)
260                        {
261                                v.val[c]+=cvGet2D(m_Image,y,x).val[c]/256.0f;
262                        }
[72]263                }
264        }
265       
[79]266        for (int c=0; c<m_Image->nChannels; c++)
[72]267        {
[79]268                v.val[c]/=s;
269        }
270       
271        // now subtract it from each pixel
272        for(int y=0; y<m_Image->height; y++)
273        {
274        for(int x=0; x<m_Image->width; x++)
[72]275                {
[79]276                        for (int c=0; c<m_Image->nChannels; c++)
277                        {
278                                // force the average to be 127
279                                v.val[c]=127+(cvGet2D(m_Image,y,x).val[c] - v.val[c]*256.0f);
280                        }
281               
282            cvSet2D(m_Image,y,x,v);
[72]283                }
284        }
285}
286
[79]287float Image::SSD(Image &other)
[72]288{
[79]289        assert(other.m_Image->width == m_Image->width);
290        assert(other.m_Image->height == m_Image->height);
[72]291       
[79]292        float ret=0;
293        float dif=0;
[72]294       
[79]295    for(int y=0; y<m_Image->height; y++)
[72]296        {
[79]297        for(int x=0; x<m_Image->width; x++)
[72]298                {
[79]299                        for (int c=0; c<m_Image->nChannels; c++)
300                        {
301                                dif = (cvGet2D(m_Image,y,x).val[c]/256.0f) -
302                                      (cvGet2D(other.m_Image,y,x).val[c]/256.0f);
303                ret+=dif*dif;
304            }
[72]305                }
306        }
[79]307       
308        // not sure strictly whether the difference should be
309        // invariant to the number of pixels, but it helps
310        ret/=m_Image->width*m_Image->height*m_Image->nChannels;
311       
[72]312        return ret;
313}
314
[79]315void Image::LBP()
[72]316{
[79]317        IplImage *newimage;
318        newimage = cvCreateImage(cvGetSize(m_Image), m_Image->depth, m_Image->nChannels);
319               
[72]320    // for each pixel
[79]321    for(int y=0; y<m_Image->height; y++)
[72]322        {
[79]323        for(int x=0; x<m_Image->width; x++)
[72]324                {
325                        CvScalar sc;
326                       
327                        // for each channel
[79]328                        for(int c=0; c<m_Image->nChannels; c++)
[72]329                        {
330                                unsigned char v=0;
[79]331                                unsigned char o=cvGet2D(m_Image,y,x).val[c];
[72]332                                unsigned char b=0;
333
334                                // loop through a 3x3 kernel
335                                for (int kx=-1; kx<=1; kx++)
336                                {
337                                        for (int ky=-1; ky<=1; ky++)
338                                        {
339                                                // don't compare with ourself
340                                                if (!(kx==0 && ky==0))
341                                                {
342                                                        // threshold
[79]343                                                        if (o>SafeGet2D(y+ky,x+kx,c))
[72]344                                                        {
345                                                                // bit magic
346                                                                v|=(1<<b);
347                                                        }
348                                                        b++;
349                                                }
350                                        }
351                                }
352                                sc.val[c]=v;
353                        }
[79]354                        cvSet2D(newimage,y,x,sc);
[72]355                }
356        }
[79]357       
358        cvReleaseImage(&m_Image);
359        m_Image=newimage;
[72]360}
361
[79]362unsigned int *Image::Hist(int channel)
[72]363{
[79]364        assert(channel<m_Image->nChannels);
365        assert(m_Image->depth == 8);
366       
[72]367        unsigned int *h=new unsigned int[256];
368
369        for(int i=0; i<256; i++)
370        {
371                h[i]=0;
372        }
373
374    // for each pixel
[79]375    for(int y=0; y<m_Image->height; y++)
[72]376        {
[79]377        for(int x=0; x<m_Image->width; x++)
[72]378                {
[79]379                        h[(unsigned char)cvGet2D(m_Image,y,x).val[channel]]++;
[72]380                }
381        }
382       
383        return h;
384}
385
[86]386Vector<float> Image::ToFloatVector()
387{
388        Vector<float> v(m_Image->width*m_Image->height*m_Image->nChannels);
389    // for each pixel
390        unsigned int pos=0;
391    for(int y=0; y<m_Image->height; y++)
392        {
393        for(int x=0; x<m_Image->width; x++)
394                {
395                        for (int c=0; c<m_Image->nChannels; c++)
396                        {
397                                v[pos++]=cvGet2D(m_Image,y,x).val[c]/256.0f;
398                        }
399                }
400        }
401        return v;
402}
Note: See TracBrowser for help on using the repository browser.