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

Revision 93, 8.0 KB checked in by dave, 10 years ago (diff)

more moving around things

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::GRAY2RGB()
176{
177        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3);
178    cvCvtColor(m_Image, newimage, CV_GRAY2RGB);
179        return Image(newimage);
180}
181
182Image Image::RGB2GRAY()
183{
184        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 1);
185    cvCvtColor(m_Image, newimage, CV_RGB2GRAY);
186        return Image(newimage);
187}
188
189Image Image::BayerGB2RGB()
190{
191        IplImage *newimage = cvCreateImage(cvGetSize(m_Image), 8, 3);
192    cvCvtColor(m_Image, newimage, CV_BayerGB2RGB);
193        return Image(newimage);
194}
195
196Image Image::Scale(int w, int h)
197{
198        IplImage *newimage = cvCreateImage(cvSize(w,h), m_Image->depth, m_Image->nChannels);
199        cvResize( m_Image, newimage, CV_INTER_LINEAR );
200        return Image(newimage);
201}
202
203void Image::Blit(const Image &image, int px, int py)
204{       
205        for(int y=0; y<image.m_Image->height; y++)
206        {
207        for(int x=0; x<image.m_Image->width; x++)
208                {
209                        if (x+px>0 && x+px<m_Image->width &&
210                                y+py>0 && y+py<m_Image->height)
211                        {
212                if (image.m_Image->nChannels==1)
213                                {
214                                        CvScalar v;
215                                        v.val[0]=cvGet2D(image.m_Image,y,x).val[0];
216                                        v.val[1]=cvGet2D(image.m_Image,y,x).val[0];
217                                        v.val[2]=cvGet2D(image.m_Image,y,x).val[0];
218                        cvSet2D(m_Image,y+py,x+px,v);
219                                }
220                                else
221                                {
222                                        cvSet2D(m_Image,y+py,x+px,cvGet2D(image.m_Image,y,x));
223                                }
224                        }
225                }
226        }
227}
228
229void Image::SubMean()
230{       
231        // get the mean of each channel
232        CvScalar v;
233        for (int c=0; c<m_Image->nChannels; c++)
234        {
235                v.val[c]=0;
236        }
237
238        float s=m_Image->width*m_Image->height;
239
240    for(int y=0; y<m_Image->height; y++)
241        {
242        for(int x=0; x<m_Image->width; x++)
243                {
244                        for (int c=0; c<m_Image->nChannels; c++)
245                        {
246                                v.val[c]+=cvGet2D(m_Image,y,x).val[c]/256.0f;
247                        }
248                }
249        }
250       
251        for (int c=0; c<m_Image->nChannels; c++)
252        {
253                v.val[c]/=s;
254        }
255       
256        // now subtract it from each pixel
257        for(int y=0; y<m_Image->height; y++)
258        {
259        for(int x=0; x<m_Image->width; x++)
260                {
261                        for (int c=0; c<m_Image->nChannels; c++)
262                        {
263                                // force the average to be 127
264                                v.val[c]=127+(cvGet2D(m_Image,y,x).val[c] - v.val[c]*256.0f);
265                        }
266               
267            cvSet2D(m_Image,y,x,v);
268                }
269        }
270}
271
272float Image::SSD(Image &other)
273{
274        assert(other.m_Image->width == m_Image->width);
275        assert(other.m_Image->height == m_Image->height);
276       
277        float ret=0;
278        float dif=0;
279       
280    for(int y=0; y<m_Image->height; y++)
281        {
282        for(int x=0; x<m_Image->width; x++)
283                {
284                        for (int c=0; c<m_Image->nChannels; c++)
285                        {
286                                dif = (cvGet2D(m_Image,y,x).val[c]/256.0f) -
287                                      (cvGet2D(other.m_Image,y,x).val[c]/256.0f);
288                ret+=dif*dif;
289            }
290                }
291        }
292       
293        // not sure strictly whether the difference should be
294        // invariant to the number of pixels, but it helps
295        ret/=m_Image->width*m_Image->height*m_Image->nChannels;
296       
297        return ret;
298}
299
300void Image::LBP()
301{
302        IplImage *newimage;
303        newimage = cvCreateImage(cvGetSize(m_Image), m_Image->depth, m_Image->nChannels);
304               
305    // for each pixel
306    for(int y=0; y<m_Image->height; y++)
307        {
308        for(int x=0; x<m_Image->width; x++)
309                {
310                        CvScalar sc;
311                       
312                        // for each channel
313                        for(int c=0; c<m_Image->nChannels; c++)
314                        {
315                                unsigned char v=0;
316                                unsigned char o=cvGet2D(m_Image,y,x).val[c];
317                                unsigned char b=0;
318
319                                // loop through a 3x3 kernel
320                                for (int kx=-1; kx<=1; kx++)
321                                {
322                                        for (int ky=-1; ky<=1; ky++)
323                                        {
324                                                // don't compare with ourself
325                                                if (!(kx==0 && ky==0))
326                                                {
327                                                        // threshold
328                                                        if (o>SafeGet2D(y+ky,x+kx,c))
329                                                        {
330                                                                // bit magic
331                                                                v|=(1<<b);
332                                                        }
333                                                        b++;
334                                                }
335                                        }
336                                }
337                                sc.val[c]=v;
338                        }
339                        cvSet2D(newimage,y,x,sc);
340                }
341        }
342       
343        cvReleaseImage(&m_Image);
344        m_Image=newimage;
345}
346
347unsigned int *Image::Hist(int channel)
348{
349        assert(channel<m_Image->nChannels);
350        assert(m_Image->depth == 8);
351       
352        unsigned int *h=new unsigned int[256];
353
354        for(int i=0; i<256; i++)
355        {
356                h[i]=0;
357        }
358
359    // for each pixel
360    for(int y=0; y<m_Image->height; y++)
361        {
362        for(int x=0; x<m_Image->width; x++)
363                {
364                        h[(unsigned char)cvGet2D(m_Image,y,x).val[channel]]++;
365                }
366        }
367       
368        return h;
369}
370
371Vector<float> Image::ToFloatVector()
372{
373        Vector<float> v(m_Image->width*m_Image->height*m_Image->nChannels);
374    // for each pixel
375        unsigned int pos=0;
376    for(int y=0; y<m_Image->height; y++)
377        {
378        for(int x=0; x<m_Image->width; x++)
379                {
380                        for (int c=0; c<m_Image->nChannels; c++)
381                        {
382                                v[pos++]=cvGet2D(m_Image,y,x).val[c]/256.0f;
383                        }
384                }
385        }
386        return v;
387}
Note: See TracBrowser for help on using the repository browser.