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

Revision 89, 7.8 KB checked in by dave, 11 years ago (diff)

renamed faceident as it's not so simple these days

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