/** Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
* All rights reserved.
* This file is part of the VLFeat library and is made available under
* the terms of the BSD license (see the COPYING file).*/
#define MSER_DRIVER_VERSION 0.2
#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION#include"stb_image.h"
/*ref:https://github.com/nothings/stb/blob/master/stb_image.h */
#define TJE_IMPLEMENTATION#include"tiny_jpeg.h"
/*ref:https://github.com/serge-rgb/TinyJPEG/blob/master/tiny_jpeg.h */#include#include
/*计时*/#include
#if defined(__APPLE__)#include
#elif defined(_WIN32)
#define WIN32_LEAN_AND_MEAN#include
#else /* __linux */#include#ifndef CLOCK_MONOTONIC/*_RAW*/
#define CLOCK_MONOTONIC CLOCK_REALTIME
#endif
#endif
staticuint64_t nanotimer()
{static int ever = 0;#if defined(__APPLE__)
staticmach_timebase_info_data_t frequency;if (!ever)
{if (mach_timebase_info(&frequency) !=KERN_SUCCESS)
{return(0);
}
ever= 1;
}return;#elif defined(_WIN32)
staticLARGE_INTEGER frequency;if (!ever)
{
QueryPerformanceFrequency(&frequency);
ever= 1;
}
LARGE_INTEGER t;
QueryPerformanceCounter(&t);return((t.QuadPart * (uint64_t) 1e9) /frequency.QuadPart);#else /* __linux */
structtimespec t;if (!ever)
{if (clock_gettime(CLOCK_MONOTONIC, &spec) != 0)
{return(0);
}
ever= 1;
}
clock_gettime(CLOCK_MONOTONIC,&spec);return((t.tv_sec * (uint64_t) 1e9) +t.tv_nsec);#endif}static doublenow()
{static uint64_t epoch = 0;if (!epoch)
{
epoch=nanotimer();
}return((nanotimer() - epoch) /1e9);
};double calcElapsed(double start, doubleend)
{double took = -start;return(took +end);
}
unsignedchar* loadImage(const char * filename, int * width, int * height, int *depth)
{
unsignedchar *output = stbi_load(filename, width, height, depth, 1);*depth = 1;return(output);
}bool saveJpeg(const char * filename, int width, int height, int depth, unsigned char*bits)
{if (!tje_encode_to_file(filename, width, height, depth, true, bits))
{
fprintf(stderr,"saveJPEG fail.\n");return(false);
}return(true);
}/** @brief Maximum value
**
** Maximum value of the integer type ::unsigned char.
**/
#define MSER_PIX_MAXVAL 256
/** @brief MSER Filter
**
** The MSER filter computes the Maximally Stable Extremal Regions of
** an image.
**
** @sa @ref mser
**/typedefstruct_MserFilt MserFilt;/** @brief MSER filter statistics*/typedefstruct_MserStats MserStats;/** @brief MSER filter statistics definition*/
struct_MserStats
{int num_extremal; /**< number of extremal regions*/
int num_unstable; /**< number of unstable extremal regions*/
int num_abs_unstable; /**< number of regions that failed the absolute stability test*/
int num_too_big; /**< number of regions that failed the maximum size test*/
int num_too_small; /**< number of regions that failed the minimum size test*/
int num_duplicates; /**< number of regions that failed the duplicate test*/};/** @name Construction and Destruction
** @{
**/MserFilt* mser_new(int ndims, int const*dims);void mser_delete(MserFilt *f);/** @}*/
/** @name Processing
** @{
**/
void mser_process(MserFilt *f,
unsignedchar const *im);void mser_ell_fit(MserFilt *f);/** @}*/
/** @name Retrieving data
** @{
**/unsignedint mser_get_regions_num(MserFilt const *f);
unsignedint const* mser_get_regions(MserFilt const *f);float const* mser_get_ell(MserFilt const *f);
unsignedint mser_get_ell_num(MserFilt const *f);
unsignedint mser_get_ell_dof(MserFilt const *f);
MserStatsconst* mser_get_stats(MserFilt const *f);/** @}*/
/** @name Retrieving parameters
** @{
**/unsignedchar mser_get_delta(MserFilt const *f);float mser_get_min_area(MserFilt const *f);float mser_get_max_area(MserFilt const *f);float mser_get_max_variation(MserFilt const *f);float mser_get_min_diversity(MserFilt const *f);/** @}*/
/** @name Setting parameters
** @{
**/
void mser_set_delta(MserFilt *f, unsigned charx);void mser_set_min_area(MserFilt *f, floatx);void mser_set_max_area(MserFilt *f, floatx);void mser_set_max_variation(MserFilt *f, floatx);void mser_set_min_diversity(MserFilt *f, floatx);/** @}*/
/*====================================================================
* INLINE DEFINITIONS
* ==================================================================*/
/** @internal
** @brief MSER accumulator data type
**
** This is a large integer type. It should be large enough to contain
** a number equal to the area (volume) of the image by the image
** width by the image height (for instance, if the image is a square
** of side 256, the maximum value is 256 x 256 x 256).
**/typedeffloatmser_acc;/** @internal @brief Basic region flag: null region*/#ifdef COMPILER_MSC#define MSER_VOID_NODE ( (1ui64 << 32) - 1)
#else
#define MSER_VOID_NODE ( (1ULL << 32) - 1)
#endif
/*-----------------------------------------------------------------*/
/** @internal
** @brief MSER: basic region (declaration)
**
** Extremal regions and maximally stable extremal regions are
** instances of image regions.
**
** There is an image region for each pixel of the image. Each region
** is represented by an instance of this structure. Regions are
** stored into an array in pixel order.
**
** Regions are arranged into a forest. MserReg::parent points to
** the parent node, or to the node itself if the node is a root.
** MserReg::parent is the index of the node in the node array
** (which therefore is also the index of the corresponding
** pixel). MserReg::height is the distance of the fartest leaf. If
** the node itself is a leaf, then MserReg::height is zero.
**
** MserReg::area is the area of the image region corresponding to
** this node.
**
** MserReg::region is the extremal region identifier. Not all
** regions are extremal regions however; if the region is NOT
** extremal, this field is set to ....
**/
struct_MserReg
{
unsignedint parent; /**< points to the parent region.*/unsignedint shortcut; /**< points to a region closer to a root.*/unsignedint height; /**< region height in the forest.*/unsignedint area; /**< area of the region.*/};/** @internal @brief MSER: basic region*/typedefstruct_MserReg MserReg;/*-----------------------------------------------------------------*/
/** @internal
** @brief MSER: extremal region (declaration)
**
** Extremal regions (ER) are extracted from the region forest. Each
** region is represented by an instance of this structure. The
** structures are stored into an array, in arbitrary order.
**
** ER are arranged into a tree. @a parent points to the parent ER, or
** to itself if the ER is the root.
**
** An instance of the structure represents the extremal region of the
** level set of intensity MserExtrReg::value and containing the
** pixel MserExtReg::index.
**
** MserExtrReg::area is the area of the extremal region and
** MserExtrReg::area_top is the area of the extremal region
** containing this region in the level set of intensity
** MserExtrReg::area + @c delta.
**
** MserExtrReg::variation is the relative area variation @c
** (area_top-area)/area.
**
** MserExtrReg::max_stable is a flag signaling whether this extremal
** region is also maximally stable.
**/
struct_