source: foam/trunk/experiments/src/ImageUtils.cpp @ 79

Revision 79, 5.5 KB checked in by dave, 11 years ago (diff)

made an image class

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