source: foam/trunk/simple-faceident/src/ImageUtils.cpp @ 76

Revision 76, 5.3 KB checked in by dave, 12 years ago (diff)

changed file format to xml, experimental multiple image/face matching, better makefile

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>
20using namespace std;
21
22/////////////////////////////////////////////////////////////
23// deep copy a sub image
24
25IplImage* SubImage(IplImage *image, CvRect roi)
26{
27        IplImage *result;
28        cvSetImageROI(image,roi);
29        result = cvCreateImage( cvSize(roi.width, roi.height), image->depth, image->nChannels );
30        cvCopy(image,result);
31        cvResetImageROI(image);
32        return result;
33}
34
35/////////////////////////////////////////////////////////////
36// safe accessor, which returns 0 if out of range
37
38unsigned char SafeGet2D(const IplImage *image, int y, int x, int c)
39{
40        CvSize size = cvGetSize(image);
41        if (x<0 || x>=size.width || y<0 || y>=size.height)
42        {
43                return 0;
44        }
45       
46        return cvGet2D(image,y,x).val[c];
47}
48
49/////////////////////////////////////////////////////////////
50// paste an image over the top of another
51
52void BlitImage(const IplImage *srcimage, IplImage *dstimage, CvPoint pos)
53{
54        CvSize size = cvGetSize(srcimage);
55        CvSize dstsize = cvGetSize(dstimage);
56       
57        for(int y=0; y<size.height; y++)
58        {
59        for(int x=0; x<size.width; x++)
60                {
61                        if (x+pos.x>0 && x+pos.x<dstsize.width &&
62                                y+pos.y>0 && y+pos.y<dstsize.height)
63                        {
64                cvSet2D(dstimage,y+pos.y,x+pos.x,cvGet2D(srcimage,y,x));
65                        }
66                }
67        }
68}
69
70/////////////////////////////////////////////////////////////
71// subtract the mean (RGB)
72
73void SubMean(IplImage *image)
74{
75        CvSize size = cvGetSize(image);
76
77        float r=0;
78        float g=0;
79        float b=0;
80
81        float s=size.width*size.height;
82
83    for(int y=0; y<size.height; y++)
84        {
85        for(int x=0; x<size.width; x++)
86                {
87            r+=cvGet2D(image,y,x).val[0]/256.0f;
88            g+=cvGet2D(image,y,x).val[1]/256.0f;
89            b+=cvGet2D(image,y,x).val[2]/256.0f;
90                }
91        }
92       
93        r/=s;
94        g/=s;
95        b/=s;
96               
97        for(int y=0; y<size.height; y++)
98        {
99        for(int x=0; x<size.width; x++)
100                {
101            cvSet2D(image,y,x,cvScalar(127+(cvGet2D(image,y,x).val[0] - r*256.0f),
102                                                                           127+(cvGet2D(image,y,x).val[1] - g*256.0f),
103                                                                           127+(cvGet2D(image,y,x).val[2] - b*256.0f)));
104                }
105        }
106}
107
108/////////////////////////////////////////////////////////////
109// return a diff metric between two images (works in RGB)
110
111float Diff(const IplImage *imagea, const IplImage *imageb)
112{
113        CvSize sizea = cvGetSize(imagea);
114        CvSize sizeb = cvGetSize(imageb);
115       
116        assert(sizea.width == sizeb.width);
117        assert(sizea.height == sizeb.height);
118       
119        float ret=0;
120
121    for(int y=0; y<sizea.height; y++)
122        {
123        for(int x=0; x<sizea.width; x++)
124                {
125            ret+=fabs((cvGet2D(imagea,y,x).val[0]/256.0f)-(cvGet2D(imageb,y,x).val[0]/256.0f));
126            ret+=fabs((cvGet2D(imagea,y,x).val[1]/256.0f)-(cvGet2D(imageb,y,x).val[1]/256.0f));
127            ret+=fabs((cvGet2D(imagea,y,x).val[2]/256.0f)-(cvGet2D(imageb,y,x).val[2]/256.0f));
128                }
129        }
130        ret/=sizea.width*sizea.height*3;
131        return ret;
132}
133
134
135
136/////////////////////////////////////////////////////////////
137// return a local binary patterns image of the src image
138
139
140void LBPImage(const IplImage *srcimage, IplImage *dstimage)
141{
142        CvSize srcsize = cvGetSize(srcimage);
143        CvSize dstsize = cvGetSize(dstimage);
144       
145        assert(srcsize.width == dstsize.width);
146        assert(srcsize.height == dstsize.height);
147        assert(srcimage->nChannels == dstimage->nChannels);
148
149    // for each pixel
150    for(int y=0; y<srcsize.height; y++)
151        {
152        for(int x=0; x<srcsize.width; x++)
153                {
154                        CvScalar sc;
155                       
156                        // for each channel
157                        for(int c=0; c<dstimage->nChannels; c++)
158                        {
159                                unsigned char v=0;
160                                unsigned char o=cvGet2D(srcimage,y,x).val[c];
161                                unsigned char b=0;
162
163                                // loop through a 3x3 kernel
164                                for (int kx=-1; kx<=1; kx++)
165                                {
166                                        for (int ky=-1; ky<=1; ky++)
167                                        {
168                                                // don't compare with ourself
169                                                if (!(kx==0 && ky==0))
170                                                {
171                                                        // threshold
172                                                        if (o>SafeGet2D(srcimage,y+ky,x+kx,c))
173                                                        {
174                                                                // bit magic
175                                                                v|=(1<<b);
176                                                        }
177                                                        b++;
178                                                }
179                                        }
180                                }
181                                sc.val[c]=v;
182                        }
183                        cvSet2D(dstimage,y,x,sc);
184                }
185        }
186}
187
188/////////////////////////////////////////////////////////////
189// calculate a histogram
190
191unsigned int *HistMono8Bit(const IplImage *image)
192{
193        assert(image->nChannels == 1);
194        assert(image->depth == 8);
195        CvSize size = cvGetSize(image);
196
197        unsigned int *h=new unsigned int[256];
198
199        for(int i=0; i<256; i++)
200        {
201                h[i]=0;
202        }
203
204    // for each pixel
205    for(int y=0; y<size.height; y++)
206        {
207        for(int x=0; x<size.width; x++)
208                {
209                        h[(unsigned char)cvGet2D(image,y,x).val[0]]++;
210                }
211        }
212       
213        return h;
214}
215
216/////////////////////////////////////////////////////////////
217// draw a histogram
218
219void DrawHistogram8(int x, int y, float scale, CvScalar colour, unsigned int *h, IplImage *img)
220{
221        for(int i=0; i<256; i++)
222        {
223                cvLine(img, cvPoint(x+i,y),cvPoint(x+i,y+h[i]*-scale), colour);
224        }
225}
Note: See TracBrowser for help on using the repository browser.