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

Revision 85, 6.9 KB checked in by dave, 11 years ago (diff)

started writing the LDA classifier

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