-
Notifications
You must be signed in to change notification settings - Fork 1
/
ImageUtils.h
executable file
·365 lines (292 loc) · 20.9 KB
/
ImageUtils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/*****************************************************************************
* Face Recognition using Eigenfaces or Fisherfaces
******************************************************************************
* by Shervin Emami, 5th Dec 2012
* http://www.shervinemami.info/openCV.html
******************************************************************************
* Ch8 of the book "Mastering OpenCV with Practical Computer Vision Projects"
* Copyright Packt Publishing 2012.
* http://www.packtpub.com/cool-projects-with-opencv/book
*****************************************************************************/
/*
* ImageUtils
* Handy utility functions for dealing with images in OpenCV (desktop or Android).
* by Shervin Emami (shervin.emami@gmail.com), 27th May 2012.
* The most recent version of this will always be available from "http://shervinemami.info/openCV.html"
*/
#ifndef IMAGEUTILS_0_7_H_
#define IMAGEUTILS_0_7_H_
// OpenCV
#include <cv.h>
//#include <cvaux.h>
#include <cxcore.h>
#ifdef USE_HIGHGUI
#include <highgui.h>
#endif
#include <stdio.h>
#if defined WIN32 || defined _WIN32
#include <conio.h> // For _kbhit() on Windows
#include <direct.h> // For mkdir(path) on Windows
#define snprintf sprintf_s // Visual Studio on Windows comes with sprintf_s() instead of snprintf()
#else
#include <stdio.h> // For getchar() on Linux
#include <termios.h> // For kbhit() on Linux
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h> // For mkdir(path, options) on Linux
#endif
#include <vector>
#include <string>
#include <iostream> // for printing streams in C++
//#include <stdarg.h> // for variable-length args in C
//#include <sstream> // for printing floats in C++
//#include <fstream> // for opening files in C++
// These functions will print using the LOG() function, using the same format as printf(). If you want it to be printed using a different
// function (such as for Android logcat output), then define LOG as your output function, otherwise it will use printf() by default.
#ifndef LOG
// For stdout debug logging, with a new-line character on the end:
#ifndef _MSC_VER
// Compiles on GCC but not MSVC:
#define LOG(fmt, args...) do {printf(fmt, ## args); printf("\n"); fflush(stdout);} while (0)
// #define LOG printf
#else
#define LOG printf
#endif
//// For Android debug logging to logcat:
//#include <android/log.h>
//#define LOG(fmt, args...) (__android_log_print(ANDROID_LOG_INFO, "........", fmt, ## args))
#endif
#ifdef __cplusplus
extern "C"
{
#endif
// Allow 'UCHAR' variables in both C and C++ code.
#ifndef UCHAR
typedef unsigned char UCHAR;
#endif
// Allow 'bool' variables in both C and C++ code.
#ifndef __cplusplus
typedef int bool;
#define true (1)
#define false (0)
#endif
// Allow default args in C++ code, but explicit args in C code.
#ifdef __cplusplus
#define DEFAULT(val) = val
#else
#define DEFAULT(val)
#endif
//------------------------------------------------------------------------------
// Timer functions
//------------------------------------------------------------------------------
// Record the execution time of some code, in milliseconds. By Shervin Emami, 27th May 2012.
// eg:
// DECLARE_TIMING(myTimer);
// ...
// START_TIMING(myTimer);
// printf("A slow calc = %f\n", pow(1.2, 3.4) );
// STOP_TIMING(myTimer);
// AVERAGE_TIMING(myTimer);
#define DECLARE_TIMING(s) int64 timeStart_##s; int64 timeDiff_##s; int64 timeTally_##s = 0; int64 countTally_##s = 0; double timeMin_##s = DBL_MAX; double timeMax_##s = 0; int64 timeEnd_##s;
#define START_TIMING(s) timeStart_##s = cvGetTickCount()
#define STOP_TIMING(s) do { timeEnd_##s = cvGetTickCount(); timeDiff_##s = (timeEnd_##s - timeStart_##s); timeTally_##s += timeDiff_##s; countTally_##s++; timeMin_##s = MIN(timeMin_##s, timeDiff_##s); timeMax_##s = MAX(timeMax_##s, timeDiff_##s); } while (0)
#define GET_TIMING(s) (double)(0.001 * ( (double)timeDiff_##s / (double)cvGetTickFrequency() ))
#define GET_MIN_TIMING(s) (double)(0.001 * ( (double)timeMin_##s / (double)cvGetTickFrequency() ))
#define GET_MAX_TIMING(s) (double)(0.001 * ( (double)timeMax_##s / (double)cvGetTickFrequency() ))
#define GET_AVERAGE_TIMING(s) (double)(countTally_##s ? 0.001 * ( (double)timeTally_##s / ((double)countTally_##s * cvGetTickFrequency()) ) : 0)
#define GET_TOTAL_TIMING(s) (double)(0.001 * ( (double)timeTally_##s / ((double)cvGetTickFrequency()) ))
#define GET_TIMING_COUNT(s) (int)(countTally_##s)
#define CLEAR_AVERAGE_TIMING(s) do { timeTally_##s = 0; countTally_##s = 0; } while (0)
#define SHOW_TIMING(s, msg) LOG("%s time:\t %dms\t (ave=%dms min=%dms max=%dms, across %d runs).", msg, cvRound(GET_TIMING(s)), cvRound(GET_AVERAGE_TIMING(s)), cvRound(GET_MIN_TIMING(s)), cvRound(GET_MAX_TIMING(s)), GET_TIMING_COUNT(s) )
#define SHOW_TOTAL_TIMING(s, msg) LOG("%s total:\t %dms\t (ave=%dms min=%dms max=%dms, across %d runs).", msg, cvRound(GET_TOTAL_TIMING(s)), cvRound(GET_AVERAGE_TIMING(s)), cvRound(GET_MIN_TIMING(s)), cvRound(GET_MAX_TIMING(s)), GET_TIMING_COUNT(s) )
#define AVERAGE_TIMING(s) SHOW_TIMING(s, #s)
#define TOTAL_TIMING(s) do { SHOW_TOTAL_TIMING(s, #s); CLEAR_AVERAGE_TIMING(s); } while (0)
// Convert a float number to an int by rounding to nearest int using a certain method.
// Replace the code with the fastest method detected by 'testTiming_FloatConversion()'.
inline int roundFloat(float f);
//------------------------------------------------------------------------------
// Graphing functions
//------------------------------------------------------------------------------
// Draw the graph of an array of floats into imageDst or a new image, between minV & maxV if given.
// Remember to free the newly created image if imageDst is not given.
IplImage* drawFloatGraph(const float *arraySrc, int nArrayLength, IplImage *imageDst DEFAULT(0), float minV DEFAULT(0.0), float maxV DEFAULT(0.0), int width DEFAULT(0), int height DEFAULT(0), char *graphLabel DEFAULT(0), bool showScale DEFAULT(true));
// Draw the graph of an array of ints into imageDst or a new image, between minV & maxV if given.
// Remember to free the newly created image if imageDst is not given.
IplImage* drawIntGraph(const int *arraySrc, int nArrayLength, IplImage *imageDst DEFAULT(0), int minV DEFAULT(0), int maxV DEFAULT(0), int width DEFAULT(0), int height DEFAULT(0), char *graphLabel DEFAULT(0), bool showScale DEFAULT(true));
// Draw the graph of an array of uchars into imageDst or a new image, between minV & maxV if given.
// Remember to free the newly created image if imageDst is not given.
IplImage* drawUCharGraph(const uchar *arraySrc, int nArrayLength, IplImage *imageDst DEFAULT(0), int minV DEFAULT(0), int maxV DEFAULT(0), int width DEFAULT(0), int height DEFAULT(0), char *graphLabel DEFAULT(0), bool showScale DEFAULT(true));
// Display a graph of the given float array.
// If background is provided, it will be drawn into, for combining multiple graphs using drawFloatGraph().
// Set delay_ms to 0 if you want to wait forever until a keypress, or set it to 1 if you want it to delay just 1 millisecond.
void showFloatGraph(const char *name, const float *arraySrc, int nArrayLength, int delay_ms DEFAULT(500), IplImage *background DEFAULT(0));
// Display a graph of the given int array.
// If background is provided, it will be drawn into, for combining multiple graphs using drawIntGraph().
// Set delay_ms to 0 if you want to wait forever until a keypress, or set it to 1 if you want it to delay just 1 millisecond.
void showIntGraph(const char *name, const int *arraySrc, int nArrayLength, int delay_ms DEFAULT(500), IplImage *background DEFAULT(0));
// Display a graph of the given unsigned char array.
// If background is provided, it will be drawn into, for combining multiple graphs using drawUCharGraph().
// Set delay_ms to 0 if you want to wait forever until a keypress, or set it to 1 if you want it to delay just 1 millisecond.
void showUCharGraph(const char *name, const uchar *arraySrc, int nArrayLength, int delay_ms DEFAULT(500), IplImage *background DEFAULT(0));
// Simple helper function to easily view an image, with an optional pause.
void showImage(const IplImage *img, int delay_ms DEFAULT(0), char *name DEFAULT(0));
// Call 'setGraphColor(0)' to reset the colors that will be used for graphs.
void setGraphColor(int index DEFAULT(0));
// Specify the exact color that the next graph should be drawn as.
void setCustomGraphColor(int R, int B, int G);
//------------------------------------------------------------------------------
// Color conversion functions
//------------------------------------------------------------------------------
// Return a new image that is always greyscale, whether the input image was RGB or Greyscale.
// Remember to free the returned image using cvReleaseImage() when finished.
IplImage* convertImageToGreyscale(const IplImage *imageSrc);
// Create an RGB image from the YIQ image using an approximation of NTSC conversion(ref: "YIQ" Wikipedia page).
// Remember to free the generated RGB image.
IplImage* convertImageYIQtoRGB(const IplImage *imageYIQ);
// Create a YIQ image from the RGB image using an approximation of NTSC conversion(ref: "YIQ" Wikipedia page).
// Remember to free the generated YIQ image.
IplImage* convertImageRGBtoYIQ(const IplImage *imageRGB);
// Create an RGB image from the HSV image using the full 8-bits, since OpenCV only allows Hues up to 180 instead of 255.
// ref: "http://cs.haifa.ac.il/hagit/courses/ist/Lectures/Demos/ColorApplet2/t_convert.html"
// Remember to free the generated RGB image.
IplImage* convertImageHSVtoRGB(const IplImage *imageHSV);
// Create a HSV image from the RGB image using the full 8-bits, since OpenCV only allows Hues up to 180 instead of 255.
// ref: "http://cs.haifa.ac.il/hagit/courses/ist/Lectures/Demos/ColorApplet2/t_convert.html"
// Remember to free the generated HSV image.
IplImage* convertImageRGBtoHSV(const IplImage *imageRGB);
// Do the color conversion of a single pixel, from RGB to HSV using Hue values between 0 to 255, whereas OpenCV only allows Hues up to 180 instead of 255.
// ref: "http://cs.haifa.ac.il/hagit/courses/ist/Lectures/Demos/ColorApplet2/t_convert.html"
inline void convertPixelRGBtoHSV_256(int bR, int bG, int bB, int &bH, int &bS, int &bV);
// Do the color conversion of a single pixel, from HSV to RGB using Hue values between 0 to 255, whereas OpenCV only allows Hues up to 180 instead of 255.
// ref: "http://cs.haifa.ac.il/hagit/courses/ist/Lectures/Demos/ColorApplet2/t_convert.html"
inline void convertPixelHSVtoRGB_256(int bH, int bS, int bV, int &bR, int &bG, int &bB);
// Do the color conversion of a single pixel, from RGB to HSV using Hue values between 0 to 179 just like OpenCV does, instead of Hues upto 255.
void convertPixelRGBtoHSV_180(int bR, int bG, int bB, int &bH, int &bS, int &bV);
// Do the color conversion of a single pixel, from HSV to RGB using Hue values between 0 to 179 just like OpenCV does, instead of Hues upto 255.
void convertPixelHSVtoRGB_180(int bH, int bS, int bV, int &bR, int &bG, int &bB);
//------------------------------------------------------------------------------
// 2D Point functions
//------------------------------------------------------------------------------
// Return (pointA + pointB).
CvPoint2D32f addPointF(const CvPoint2D32f pointA, const CvPoint2D32f pointB);
// Return (pointA - pointB).
CvPoint2D32f subtractPointF(const CvPoint2D32f pointA, const CvPoint2D32f pointB);
// Return (point * scale).
CvPoint2D32f scalePointF(const CvPoint2D32f point, float scale);
// Return the point scaled relative to the given origin.
CvPoint2D32f scalePointAroundPointF(const CvPoint2D32f point, const CvPoint2D32f origin, float scale);
// Return (p * s), to a maximum value of maxVal
float scaleValueF(float p, float s, float maxVal);
#define scaleValueFI(p, s, maxVal) scaleValueF(p, s, (float)maxVal)
// Return (p * s), to a maximum value of maxVal
int scaleValueI(int p, float s, int maxVal);
// Return the point rotated around its origin by angle (in degrees).
CvPoint2D32f rotatePointF(const CvPoint2D32f point, float angleDegrees);
// Return the point rotated around the given origin by angle (in degrees).
CvPoint2D32f rotatePointAroundPointF(const CvPoint2D32f point, const CvPoint2D32f origin, float angleDegrees);
// Calculate the distance between the 2 given (floating-point) points.
float findDistanceBetweenPointsF(const CvPoint2D32f p1, const CvPoint2D32f p2);
// Calculate the distance between the 2 given (integer) points.
float findDistanceBetweenPointsI(const CvPoint p1, const CvPoint p2);
// Calculate the angle between the 2 given integer points (in degrees).
float findAngleBetweenPointsF(const CvPoint2D32f p1, const CvPoint2D32f p2);
// Calculate the angle between the 2 given floating-point points (in degrees).
float findAngleBetweenPointsI(const CvPoint p1, const CvPoint p2);
// Draw a crossbar at the given position.
void drawCross(IplImage *img, const CvPoint pt, int radius, const CvScalar color );
// Print the label and then the rect to the console for easy debugging
void printPoint(const CvPoint pt, const char *label);
// Print the label and then the rect to the console for easy debugging
void printPointF(const CvPoint2D32f pt, const char *label);
//------------------------------------------------------------------------------
// Rectangle region functions
//------------------------------------------------------------------------------
// Enlarge or shrink the rectangle size & center by a given scale.
// If w & h are given, will make sure the rectangle stays within the bounds if it is enlarged too much.
// Note that for images, w should be (width-1) and h should be (height-1).
CvRect scaleRect(const CvRect rectIn, float scaleX, float scaleY, int w DEFAULT(0), int h DEFAULT(0));
// Enlarge or shrink the rectangle region by a given scale without moving its center, and possibly add a border around it.
// If w & h are given, will make sure the rectangle stays within the bounds if it is enlarged too much.
// Note that for images, w should be (width-1) and h should be (height-1).
CvRect scaleRectInPlace(const CvRect rectIn, float scaleX, float scaleY, float borderX DEFAULT(0.0f), float borderY DEFAULT(0.0f), int w DEFAULT(0), int h DEFAULT(0));
// Return a new rect that the same as rectA when shifted by (rectB.x, rectB.y).
CvRect offsetRect(const CvRect rectA, const CvRect rectB);
// Return a new rect that the same as rectA when shifted by (pt.x, pt.y).
CvRect offsetRectPt(const CvRect rectA, const CvPoint pt);
// Draw a rectangle around the given object. (Use CV_RGB(255,0,0) for red color)
void drawRect(IplImage *img, const CvRect rect, const CvScalar color DEFAULT(CV_RGB(220,0,0)));
// Draw a filled rectangle around the given object.
void drawRectFilled(IplImage *img, const CvRect rect, const CvScalar color DEFAULT(CV_RGB(220,0,0)));
// Print the label and then the rectangle information to the console for easy debugging
void printRect(const CvRect rect, const char *label DEFAULT(0));
// Make sure the given rectangle is completely within the given image dimensions.
CvRect cropRect(const CvRect rectIn, int w, int h);
//------------------------------------------------------------------------------
// Image transforming functions
//------------------------------------------------------------------------------
// Returns a new image that is a cropped version of the original image.
// Remember to free the new image later.
IplImage* cropImage(const IplImage *img, const CvRect region);
// Creates a new image copy that is of a desired size. The aspect ratio will be kept constant if desired, by cropping the desired region.
// Remember to free the new image later.
IplImage* resizeImage(const IplImage *origImg, int newWidth, int newHeight, bool keepAspectRatio);
// Rotate the image clockwise and possibly scale the image. Use 'mapRotatedImagePoint()' to map pixels from the src to dst image.
IplImage *rotateImage(const IplImage *src, float angleDegrees, float scale DEFAULT(1.0f));
// Get the position of a pixel in the image after the rotateImage() operation.
CvPoint2D32f mapRotatedImagePoint(const CvPoint2D32f pointOrig, const IplImage *image, float angleRadians, float scale DEFAULT(1.0f));
//------------------------------------------------------------------------------
// Image utility functions
//------------------------------------------------------------------------------
// Paste multiple images next to each other as a single image, for saving or displaying.
// Remember to free the returned image.
// Sample usage: cvSaveImage("out.png", combineImages(2, img1, img2) );
// Modified by Shervin from the cvShowManyImages() function on the OpenCVWiki by Parameswaran.
// 'combineImagesResized()' will resize all images to 300x300, whereas 'combineImages()' doesn't resize the images at all.
IplImage* combineImagesResized(int nArgs, ...);
IplImage* combineImages(int nArgs, ...);
// Do Bilateral Filtering to smooth the image noise but preserve the edges.
// A smoothness of 5 is very little filtering, and 100 is very high filtering.
// Remember to free the returned image.
IplImage* smoothImageBilateral(const IplImage *src, float smoothness DEFAULT(30));
// Blend color images 'image1' and 'image2' using an 8-bit alpha-blending mask channel.
// Equivalent to this operation on each pixel: imageOut = image1 * (1-(imageAlphaMask/255)) + image2 * (imageAlphaMask/255)
// So if a pixel in imageAlphMask is 0, then that pixel in imageOut will be image1, or if imageAlphaMask is 255 then imageOut is image2,
// or if imageAlphaMask was 200 then imageOut would be: image1 * 0.78 + image2 * 0.22
// Returns a new image, so remember to call 'cvReleaseImage()' on the result.
IplImage* blendImage(const IplImage* image1, const IplImage* image2, const IplImage* imageAlphaMask);
// Get an 8-bit equivalent of the 32-bit Float Matrix.
// Returns a new image, so remember to call 'cvReleaseImage()' on the result.
IplImage* convertMatrixToUcharImage(const CvMat *srcMat);
// Get a normal 8-bit uchar image equivalent of the 32-bit float greyscale image.
// Returns a new image, so remember to call 'cvReleaseImage()' on the result.
IplImage* convertFloatImageToUcharImage(const IplImage *srcImg);
// Save the given image to a JPG or BMP file, even if its format isn't an 8-bit image, such as a 32bit image.
int saveImage(const char *filename, const IplImage *image);
// Store a greyscale floating-point CvMat image into a BMP/JPG/GIF/PNG image,
// since cvSaveImage() can only handle 8bit images (not 32bit float images).
void saveFloatMat(const char *filename, const CvMat *src);
// Store a greyscale floating-point CvMat image into a BMP/JPG/GIF/PNG image,
// since cvSaveImage() can only handle 8bit images (not 32bit float images).
void saveFloatImage(const char *filename, const IplImage *srcImg);
// Draw some text onto an image using printf() format.
void drawText(IplImage *img, CvPoint position, CvScalar color, char *fmt, ...);
// Print the label and then some text info about the IplImage properties, to LOG() for easy debugging.
void printImageInfo(const IplImage *image_tile, const char *label DEFAULT(0));
// Print the pixel values of the IplImage, to LOG() for easy debugging. maxElements of 0 will print all the data.
void printImagePixels(const IplImage *image, const char *label DEFAULT(0), int maxElements DEFAULT(300));
// Print the label and then contents of a cv::Mat from the C++ interface (using "LOG()") for easy debugging.
void printMat(const cv::Mat M, const char *label DEFAULT(0), int maxElements DEFAULT(300));
// Print the label and then contents of the Matrix (using "LOG()") for easy debugging. maxElements of 0 will print all the data.
void printMatrix(const CvMat *M, const char *label DEFAULT(0), int maxElements DEFAULT(300));
// Print the label and info of a cv::Mat from the C++ interface (using "LOG()") for easy debugging.
void printMatInfo(const cv::Mat M, const char *label DEFAULT(0));
// Print the x & y coords of the given point. If 'label' is supplied, prints that first, and also prints a newline character on the end.
void printPoint32f(const CvPoint2D32f pt, const char *label DEFAULT(0));
// Print the start & end coords of the given line. If 'label' is supplied, prints that first, and also prints a newline character on the end.
void printLine(const CvPoint ptA, const CvPoint ptB, const char *label DEFAULT(0));
// Just for debugging float images & matrices.
void printDataRange(const CvArr *src, const char *msg);
#if defined (__cplusplus)
}
#endif
#endif /* IMAGEUTILS_H_ */