这么做的目的是为了在c和cpp中互相调用函数命名一致,否则会出现链接错误。
/*****************************************************************************
* ImageUtils
* Handy utility functions for dealing with images in OpenCV (desktop or Android).
* The most recent version of this will always be available from "http://shervinemami.info/openCV.html"
******************************************************************************
* by Shervin Emami, 5th Dec 2012 ([email protected])
* http://www.shervinemami.info/
******************************************************************************
* Ch1 of the book "Mastering OpenCV with Practical Computer Vision Projects"
* Copyright Packt Publishing 2012.
* http://www.packtpub.com/cool-projects-with-opencv/book
*****************************************************************************/
#ifndef IMAGEUTILS_0_7_H_
#define IMAGEUTILS_0_7_H_
// OpenCV
#include
//#include
#include
#ifdef USE_HIGHGUI
#include
#endif
#include
#if defined WIN32 || defined _WIN32
#include // For _kbhit() on Windows
#include // For mkdir(path) on Windows
#define snprintf sprintf_s // Visual Studio on Windows comes with sprintf_s() instead of snprintf()
#else
#include // For getchar() on Linux
#include // For kbhit() on Linux
#include
#include
#include // For mkdir(path, options) on Linux
#endif
#include
#include
#include // for printing streams in C++
//#include // for variable-length args in C
//#include // for printing floats in C++
//#include // 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
#ifdef __ANDROID__
// For Android debug logging to logcat:
#include
#define LOG(fmt, args...) (__android_log_print(ANDROID_LOG_INFO, "........", fmt, ## args))
#else
// 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
#endif
#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_ */