- Timestamp:
- 05/08/2009 02:06:23 PM (12 years ago)
- Location:
- foam/trunk/experiments/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
foam/trunk/experiments/src/ImageUtils.cpp
r72 r79 18 18 19 19 #include <iostream> 20 #include "highgui.h" 21 20 22 using namespace std; 21 23 22 ///////////////////////////////////////////////////////////// 23 // deep copy a sub image 24 25 IplImage* 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 ///////////////////////////////////////////////////////////// 24 Image::Image(int w, int h, int d, int c) 25 { 26 cvCreateImage(cvSize(w, h), d, c); 27 } 28 29 Image::Image(const string &filename) 30 { 31 m_Image=cvLoadImage(filename.c_str()); 32 } 33 34 Image::Image(const Image *other) 35 { 36 m_Image=cvCloneImage(other->m_Image); 37 } 38 39 Image::~Image() 40 { 41 cvReleaseImage(&m_Image); 42 } 43 36 44 // safe accessor, which returns 0 if out of range 37 38 unsigned char SafeGet2D(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) 45 unsigned char Image::SafeGet2D(int y, int x, int c) 46 { 47 if (x<0 || x>=m_Image->width || y<0 || y>=m_Image->height) 42 48 { 43 49 return 0; 44 50 } 45 51 46 return cvGet2D(image,y,x).val[c]; 47 } 48 49 ///////////////////////////////////////////////////////////// 50 // paste an image over the top of another 51 52 void BlitImage(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 73 void 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; 52 return cvGet2D(m_Image,y,x).val[c]; 53 } 54 55 void Image::PrintInfo() 56 { 57 cerr<<m_Image->width<<"x"<<m_Image->height<<"x"<<m_Image->nChannels 58 <<" @ "<<m_Image->depth<<" bpp"<<endl; 59 } 60 61 void 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 76 void 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 84 void 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 92 void 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 100 void 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 108 void 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 123 void 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 } 96 160 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 111 float Diff(IplImage *imagea, 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); 161 cvSet2D(m_Image,y,x,v); 162 } 163 } 164 } 165 166 float Image::SSD(Image &other) 167 { 168 assert(other.m_Image->width == m_Image->width); 169 assert(other.m_Image->height == m_Image->height); 118 170 119 171 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; 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 131 191 return ret; 132 192 } 133 193 134 135 136 ///////////////////////////////////////////////////////////// 137 // return a local binary patterns image of the src image 138 139 140 void LBPImage(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 194 void Image::LBP() 195 { 196 IplImage *newimage; 197 newimage = cvCreateImage(cvGetSize(m_Image), m_Image->depth, m_Image->nChannels); 198 149 199 // for each pixel 150 for(int y=0; y< srcsize.height; y++)151 { 152 for(int x=0; x< srcsize.width; x++)200 for(int y=0; y<m_Image->height; y++) 201 { 202 for(int x=0; x<m_Image->width; x++) 153 203 { 154 204 CvScalar sc; 155 205 156 206 // for each channel 157 for(int c=0; c< dstimage->nChannels; c++)207 for(int c=0; c<m_Image->nChannels; c++) 158 208 { 159 209 unsigned char v=0; 160 unsigned char o=cvGet2D( srcimage,y,x).val[c];210 unsigned char o=cvGet2D(m_Image,y,x).val[c]; 161 211 unsigned char b=0; 162 212 … … 170 220 { 171 221 // threshold 172 if (o>SafeGet2D( srcimage,y+ky,x+kx,c))222 if (o>SafeGet2D(y+ky,x+kx,c)) 173 223 { 174 224 // bit magic … … 181 231 sc.val[c]=v; 182 232 } 183 cvSet2D(dstimage,y,x,sc); 184 } 185 } 186 } 187 188 ///////////////////////////////////////////////////////////// 189 // calculate a histogram 190 191 unsigned int *HistMono8Bit(IplImage *image) 192 { 193 assert(image->nChannels == 1); 194 assert(image->depth == 8); 195 CvSize size = cvGetSize(image); 196 233 cvSet2D(newimage,y,x,sc); 234 } 235 } 236 237 cvReleaseImage(&m_Image); 238 m_Image=newimage; 239 } 240 241 unsigned int *Image::Hist(int channel) 242 { 243 assert(channel<m_Image->nChannels); 244 assert(m_Image->depth == 8); 245 197 246 unsigned int *h=new unsigned int[256]; 198 247 … … 203 252 204 253 // 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]]++; 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]]++; 210 260 } 211 261 } … … 214 264 } 215 265 216 /////////////////////////////////////////////////////////////217 // draw a histogram218 219 void 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 } -
foam/trunk/experiments/src/ImageUtils.h
r72 r79 16 16 17 17 #include "cv.h" 18 #include "highgui.h"18 #include <string> 19 19 20 #ifndef IMAGE _UTILS21 #define IMAGE _UTILS20 #ifndef IMAGE 21 #define IMAGE 22 22 23 // I need to sort this out before it grows too much... 23 class Image 24 { 25 public: 26 Image(int w, int h, int d, int c); 27 Image(const std::string &filename); 28 Image(const Image *other); 29 ~Image(); 24 30 25 IplImage* SubImage(IplImage *image, CvRect roi); 26 void BlitImage(IplImage *srcimage, IplImage *dstimage, CvPoint pos); 27 void SubMean(IplImage *image); 28 float Diff(IplImage *imagea, IplImage *imageb); 29 void LBPImage(IplImage *srcimage, IplImage *dstimage); 30 unsigned int *HistMono8Bit(IplImage *image); 31 void PrintInfo(); 32 33 void Crop(int x, int y, int w, int h); 34 void Scale(int w, int h); 31 35 32 void DrawHistogram8(int x, int y, float scale, CvScalar colour, unsigned int *h, IplImage *img); 36 // Paste an image into this one 37 void Blit(const Image &image, CvPoint pos); 38 39 // Return a sum of squared differences, for giving a similarity metric 40 float SSD(Image &other); 41 42 // Subtract the mean - this is useful for accounting for global lighting changes 43 void SubMean(); 44 45 // Convert the image into a local binary patterns image 46 void LBP(); 47 48 // Convert to different colour spaces 49 void GRAY2RGB(); 50 void RGB2GRAY(); 51 void BayerGB2RGB(); 52 53 // Calculate a histogram for a given channel 54 unsigned int *Hist(int channel); 55 56 IplImage *m_Image; 57 58 private: 59 unsigned char SafeGet2D(int y, int x, int c); 60 }; 33 61 34 62 #endif -
foam/trunk/experiments/src/main.cpp
r72 r79 150 150 {{255,0,255}} 151 151 }; 152 152 /* 153 153 void lpbhist(int x, int y, IplImage* img, IplImage* mainimg) 154 154 { … … 164 164 cvReleaseImage( &gray ); 165 165 } 166 166 */ 167 167 void detect_and_draw( IplImage* img ) 168 168 { … … 178 178 cvEqualizeHist( small_img, small_img ); 179 179 cvClearMemStorage( storage ); 180 180 181 Image im("bayer.pgm"); 182 im.Crop(300,300,320,240); 183 im.RGB2GRAY(); 184 //im.PrintInfo(); 185 im.BayerGB2RGB(); 186 cvShowImage( "result", im.m_Image ); 187 188 /* 181 189 IplImage *li = cvLoadImage("test3-0.png"); 182 190 lpbhist(0, 0, li, gray); … … 190 198 lpbhist(200, 0, li, gray); 191 199 cvReleaseImage( &li ); 192 193 cvShowImage( "result", gray ); 200 */ 194 201 cvReleaseImage( &gray ); 195 202 cvReleaseImage( &small_img );
Note: See TracChangeset
for help on using the changeset viewer.