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

Revision 113, 8.5 KB checked in by dave, 10 years ago (diff)

first pass expression recgn

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        if (m_Image==NULL) cerr<<"Could not open image: "<<filename<<endl;
33        assert(m_Image);
34}
35
36Image::Image(const Image &other)
37{
38        m_Image=cvCloneImage(other.m_Image);
39}
40
41Image::Image(const IplImage *other)
42{
43        m_Image=cvCloneImage(other);
44}
45
46Image::Image(int w, int h, int c, const Vector<float> &v, float gain)
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                        {
57                                s.val[c]=(0.5+v[pos++]*gain)*127.0f;
58                        }
59                        cvSet2D(m_Image,y,x,s);
60                }
61        }
62}
63
64Image::~Image()
65{
66        cvReleaseImage(&m_Image);
67}
68
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
137Image &Image::operator=(const Image &other)
138{
139        m_Image=cvCloneImage(other.m_Image);
140        return *this;
141}
142
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)
147        {
148                return 0;
149        }
150       
151        return cvGet2D(m_Image,y,x).val[c];
152}
153
154void Image::PrintInfo()
155{
156        cerr<<m_Image->width<<"x"<<m_Image->height<<"x"<<m_Image->nChannels
157                <<" @ "<<m_Image->depth<<" bpp"<<endl;
158}
159
160void Image::Crop(int x, int y, int w, int h)
161{
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
175Image Image::SubImage(Rect r)
176{
177        return SubImage(r.x, r.y, r.w, r.h);
178}
179
180Image Image::SubImage(int x, int y, int w, int h)
181{
182        CvRect roi;
183        roi.x=x;
184        roi.y=y;
185        roi.width=w;
186        roi.height=h;
187        IplImage *newimage;
188        cvSetImageROI(m_Image,roi);
189        newimage = cvCreateImage( cvSize(roi.width, roi.height), m_Image->depth, m_Image->nChannels );
190        cvCopy(m_Image,newimage);       
191        cvResetImageROI(m_Image);
192        return newimage;
193}
194
195Image Image::GRAY2RGB()
196{
197        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3);
198    cvCvtColor(m_Image, newimage, CV_GRAY2RGB);
199        return Image(newimage);
200}
201
202Image Image::RGB2GRAY()
203{
204        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 1);
205    cvCvtColor(m_Image, newimage, CV_RGB2GRAY);
206        return Image(newimage);
207}
208
209Image Image::BayerGB2RGB()
210{
211        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3);
212    cvCvtColor(m_Image, newimage, CV_BayerGB2RGB);
213        return Image(newimage);
214}
215
216Image Image::Scale(int w, int h)
217{
218        IplImage *newimage = cvCreateImage(cvSize(w,h), m_Image->depth, m_Image->nChannels);
219        cvResize( m_Image, newimage, CV_INTER_LINEAR );
220        return Image(newimage);
221}
222
223void Image::Blit(const Image &image, int px, int py)
224{       
225        for(int y=0; y<image.m_Image->height; y++)
226        {
227        for(int x=0; x<image.m_Image->width; x++)
228                {
229                        if (x+px>0 && x+px<m_Image->width &&
230                                y+py>0 && y+py<m_Image->height)
231                        {
232                if (image.m_Image->nChannels==1)
233                                {
234                                        CvScalar v;
235                                        v.val[0]=cvGet2D(image.m_Image,y,x).val[0];
236                                        v.val[1]=cvGet2D(image.m_Image,y,x).val[0];
237                                        v.val[2]=cvGet2D(image.m_Image,y,x).val[0];
238                        cvSet2D(m_Image,y+py,x+px,v);
239                                }
240                                else
241                                {
242                                        cvSet2D(m_Image,y+py,x+px,cvGet2D(image.m_Image,y,x));
243                                }
244                        }
245                }
246        }
247}
248
249void Image::SubMean()
250{       
251        // get the mean of each channel
252        CvScalar v;
253        for (int c=0; c<m_Image->nChannels; c++)
254        {
255                v.val[c]=0;
256        }
257
258        float s=m_Image->width*m_Image->height;
259
260    for(int y=0; y<m_Image->height; y++)
261        {
262        for(int x=0; x<m_Image->width; x++)
263                {
264                        for (int c=0; c<m_Image->nChannels; c++)
265                        {
266                                v.val[c]+=cvGet2D(m_Image,y,x).val[c]/256.0f;
267                        }
268                }
269        }
270       
271        for (int c=0; c<m_Image->nChannels; c++)
272        {
273                v.val[c]/=s;
274        }
275               
276        CvScalar o;
277       
278        // now subtract it from each pixel
279        for(int y=0; y<m_Image->height; y++)
280        {
281        for(int x=0; x<m_Image->width; x++)
282                {                       
283                        for (int c=0; c<m_Image->nChannels; c++)
284                        {
285                                // force the average to be 127
286                                o.val[c]=127+(cvGet2D(m_Image,y,x).val[c] - v.val[c]*256.0f);
287                        }
288                               
289            cvSet2D(m_Image,y,x,o);
290                }
291        }
292}
293
294float Image::SSD(Image &other)
295{
296        assert(other.m_Image->width == m_Image->width);
297        assert(other.m_Image->height == m_Image->height);
298       
299        float ret=0;
300        float dif=0;
301       
302    for(int y=0; y<m_Image->height; y++)
303        {
304        for(int x=0; x<m_Image->width; x++)
305                {
306                        for (int c=0; c<m_Image->nChannels; c++)
307                        {
308                                dif = (cvGet2D(m_Image,y,x).val[c]/256.0f) -
309                                      (cvGet2D(other.m_Image,y,x).val[c]/256.0f);
310                ret+=dif*dif;
311            }
312                }
313        }
314       
315        // not sure strictly whether the difference should be
316        // invariant to the number of pixels, but it helps
317        ret/=m_Image->width*m_Image->height*m_Image->nChannels;
318       
319        return ret;
320}
321
322void Image::LBP()
323{
324        IplImage *newimage;
325        newimage = cvCreateImage(cvGetSize(m_Image), m_Image->depth, m_Image->nChannels);
326               
327    // for each pixel
328    for(int y=0; y<m_Image->height; y++)
329        {
330        for(int x=0; x<m_Image->width; x++)
331                {
332                        CvScalar sc;
333                       
334                        // for each channel
335                        for(int c=0; c<m_Image->nChannels; c++)
336                        {
337                                unsigned char v=0;
338                                unsigned char o=cvGet2D(m_Image,y,x).val[c];
339                                unsigned char b=0;
340
341                                // loop through a 3x3 kernel
342                                for (int kx=-1; kx<=1; kx++)
343                                {
344                                        for (int ky=-1; ky<=1; ky++)
345                                        {
346                                                // don't compare with ourself
347                                                if (!(kx==0 && ky==0))
348                                                {
349                                                        // threshold
350                                                        if (o>SafeGet2D(y+ky,x+kx,c))
351                                                        {
352                                                                // bit magic
353                                                                v|=(1<<b);
354                                                        }
355                                                        b++;
356                                                }
357                                        }
358                                }
359                                sc.val[c]=v;
360                        }
361                        cvSet2D(newimage,y,x,sc);
362                }
363        }
364       
365        cvReleaseImage(&m_Image);
366        m_Image=newimage;
367}
368
369unsigned int *Image::Hist(int channel)
370{
371        assert(channel<m_Image->nChannels);
372        assert(m_Image->depth == 8);
373       
374        unsigned int *h=new unsigned int[256];
375
376        for(int i=0; i<256; i++)
377        {
378                h[i]=0;
379        }
380
381    // for each pixel
382    for(int y=0; y<m_Image->height; y++)
383        {
384        for(int x=0; x<m_Image->width; x++)
385                {
386                        h[(unsigned char)cvGet2D(m_Image,y,x).val[channel]]++;
387                }
388        }
389       
390        return h;
391}
392
393Vector<float> Image::ToFloatVector()
394{
395        Vector<float> v(m_Image->width*m_Image->height*m_Image->nChannels);
396    // for each pixel
397        unsigned int pos=0;
398    for(int y=0; y<m_Image->height; y++)
399        {
400        for(int x=0; x<m_Image->width; x++)
401                {
402                        for (int c=0; c<m_Image->nChannels; c++)
403                        {
404                                v[pos++]=cvGet2D(m_Image,y,x).val[c]/256.0f;
405                        }
406                }
407        }
408        return v;
409}
410
411void Image::Save(const string &filename)
412{
413        cvSaveImage(filename.c_str(),m_Image);
414}
415
Note: See TracBrowser for help on using the repository browser.