Explanation
===========
-Here we talk only about XML and YAML file inputs. Your output (and its respective input) file may have only one of these extensions and the structure coming from this. They are two kinds of data structures you may serialize: *mappings* (like the STL map) and *element sequence* (like the STL vector>. The difference between these is that in a map every element has a unique name through what you may access it. For sequences you need to go through them to query a specific item.
+Here we talk only about XML and YAML file inputs. Your output (and its respective input) file may have only one of these extensions and the structure coming from this. They are two kinds of data structures you may serialize: *mappings* (like the STL map) and *element sequence* (like the STL vector). The difference between these is that in a map every element has a unique name through what you may access it. For sequences you need to go through them to query a specific item.
-1. **XML\\YAML File Open and Close.** Before you write any content to such file you need to open it and at the end to close it. The XML\YAML data structure in OpenCV is :xmlymlpers:`FileStorage <filestorage>`. To specify that this structure to which file binds on your hard drive you can use either its constructor or the *open()* function of this:
+1. **XML/YAML File Open and Close.** Before you write any content to such file you need to open it and at the end to close it. The XML/YAML data structure in OpenCV is :xmlymlpers:`FileStorage <filestorage>`. To specify that this structure to which file binds on your hard drive you can use either its constructor or the *open()* function of this:
.. code-block:: cpp
string filename = "I.xml";
FileStorage fs(filename, FileStorage::WRITE);
- \\...
+ //...
fs.open(filename, FileStorage::READ);
Either one of this you use the second argument is a constant specifying the type of operations you'll be able to on them: WRITE, READ or APPEND. The extension specified in the file name also determinates the output format that will be used. The output may be even compressed if you specify an extension such as *.xml.gz*.
fs["iterationNr"] >> itNr;
itNr = (int) fs["iterationNr"];
-#. **Input\\Output of OpenCV Data structures.** Well these behave exactly just as the basic C++ types:
+#. **Input/Output of OpenCV Data structures.** Well these behave exactly just as the basic C++ types:
.. code-block:: cpp
fs["R"] >> R; // Read cv::Mat
fs["T"] >> T;
-#. **Input\\Output of vectors (arrays) and associative maps.** As I mentioned beforehand we can output maps and sequences (array, vector) too. Again we first print the name of the variable and then we have to specify if our output is either a sequence or map.
+#. **Input/Output of vectors (arrays) and associative maps.** As I mentioned beforehand, we can output maps and sequences (array, vector) too. Again we first print the name of the variable and then we have to specify if our output is either a sequence or map.
For sequence before the first element print the "[" character and after the last one the "]" character:
For instance, *CV_8UC3* means we use unsigned char types that are 8 bit long and each pixel has three of these to form the three channels. This are predefined for up to four channel numbers. The :basicstructures:`Scalar <scalar>` is four element short vector. Specify this and you can initialize all matrix points with a custom value. If you need more you can create the type with the upper macro, setting the channel number in parenthesis as you can see below.
- + Use C\\C++ arrays and initialize via constructor
+ + Use C/C++ arrays and initialize via constructor
.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp
:language: cpp
# endif
# define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR)
+#define IPP_ALIGN 32 // required for AVX optimization
+
#define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)
static inline IppiSize ippiSize(int width, int height)
using std::tr1::make_tuple;
using std::tr1::get;
-#define MAT_TYPES_DFT CV_32FC1, CV_64FC1
-#define MAT_SIZES_DFT sz1080p, sz2K
-#define TEST_MATS_DFT testing::Combine(testing::Values(MAT_SIZES_DFT), testing::Values(MAT_TYPES_DFT))
+#define MAT_TYPES_DFT CV_32FC1, CV_32FC2, CV_64FC1
+#define MAT_SIZES_DFT cv::Size(320, 480), cv::Size(800, 600), cv::Size(1280, 1024), sz1080p, sz2K
+CV_ENUM(FlagsType, 0, DFT_INVERSE, DFT_SCALE, DFT_COMPLEX_OUTPUT, DFT_ROWS, DFT_INVERSE|DFT_COMPLEX_OUTPUT)
+#define TEST_MATS_DFT testing::Combine(testing::Values(MAT_SIZES_DFT), testing::Values(MAT_TYPES_DFT), FlagsType::all())
-PERF_TEST_P(Size_MatType, dft, TEST_MATS_DFT)
+typedef std::tr1::tuple<Size, MatType, FlagsType> Size_MatType_FlagsType_t;
+typedef perf::TestBaseWithParam<Size_MatType_FlagsType_t> Size_MatType_FlagsType;
+
+PERF_TEST_P(Size_MatType_FlagsType, dft, TEST_MATS_DFT)
{
Size sz = get<0>(GetParam());
int type = get<1>(GetParam());
+ int flags = get<2>(GetParam());
Mat src(sz, type);
Mat dst(sz, type);
declare.in(src, WARMUP_RNG).time(60);
- TEST_CYCLE() dft(src, dst);
+ TEST_CYCLE() dft(src, dst, flags);
SANITY_CHECK(dst, 1e-5, ERROR_RELATIVE);
-}
+}
\ No newline at end of file
static bool ocl_LUT(InputArray _src, InputArray _lut, OutputArray _dst)
{
- int dtype = _dst.type(), lcn = _lut.channels(), dcn = CV_MAT_CN(dtype), ddepth = CV_MAT_DEPTH(dtype);
+ int lcn = _lut.channels(), dcn = _src.channels(), ddepth = _lut.depth();
UMat src = _src.getUMat(), lut = _lut.getUMat();
- _dst.create(src.size(), dtype);
+ _dst.create(src.size(), CV_MAKETYPE(ddepth, dcn));
UMat dst = _dst.getUMat();
ocl::Kernel k("LUT", ocl::core::lut_oclsrc,
#endif
+#if defined(HAVE_IPP) && !defined(HAVE_IPP_ICV_ONLY)
+namespace ipp {
+
+#if 0 // there are no performance benefits (PR #2653)
+class IppLUTParallelBody_LUTC1 : public ParallelLoopBody
+{
+public:
+ bool* ok;
+ const Mat& src_;
+ const Mat& lut_;
+ Mat& dst_;
+
+ typedef IppStatus (*IppFn)(const Ipp8u* pSrc, int srcStep, void* pDst, int dstStep,
+ IppiSize roiSize, const void* pTable, int nBitSize);
+ IppFn fn;
+
+ int width;
+
+ IppLUTParallelBody_LUTC1(const Mat& src, const Mat& lut, Mat& dst, bool* _ok)
+ : ok(_ok), src_(src), lut_(lut), dst_(dst)
+ {
+ width = dst.cols * dst.channels();
+
+ size_t elemSize1 = CV_ELEM_SIZE1(dst.depth());
+
+ fn =
+ elemSize1 == 1 ? (IppFn)ippiLUTPalette_8u_C1R :
+ elemSize1 == 4 ? (IppFn)ippiLUTPalette_8u32u_C1R :
+ NULL;
+
+ *ok = (fn != NULL);
+ }
+
+ void operator()( const cv::Range& range ) const
+ {
+ if (!*ok)
+ return;
+
+ const int row0 = range.start;
+ const int row1 = range.end;
+
+ Mat src = src_.rowRange(row0, row1);
+ Mat dst = dst_.rowRange(row0, row1);
+
+ IppiSize sz = { width, dst.rows };
+
+ CV_DbgAssert(fn != NULL);
+ if (fn(src.data, (int)src.step[0], dst.data, (int)dst.step[0], sz, lut_.data, 8) < 0)
+ {
+ setIppErrorStatus();
+ *ok = false;
+ }
+ }
+private:
+ IppLUTParallelBody_LUTC1(const IppLUTParallelBody_LUTC1&);
+ IppLUTParallelBody_LUTC1& operator=(const IppLUTParallelBody_LUTC1&);
+};
+#endif
+
+class IppLUTParallelBody_LUTCN : public ParallelLoopBody
+{
+public:
+ bool *ok;
+ const Mat& src_;
+ const Mat& lut_;
+ Mat& dst_;
+
+ int lutcn;
+
+ uchar* lutBuffer;
+ uchar* lutTable[4];
+
+ IppLUTParallelBody_LUTCN(const Mat& src, const Mat& lut, Mat& dst, bool* _ok)
+ : ok(_ok), src_(src), lut_(lut), dst_(dst), lutBuffer(NULL)
+ {
+ lutcn = lut.channels();
+ IppiSize sz256 = {256, 1};
+
+ size_t elemSize1 = dst.elemSize1();
+ CV_DbgAssert(elemSize1 == 1);
+ lutBuffer = (uchar*)ippMalloc(256 * (int)elemSize1 * 4);
+ lutTable[0] = lutBuffer + 0;
+ lutTable[1] = lutBuffer + 1 * 256 * elemSize1;
+ lutTable[2] = lutBuffer + 2 * 256 * elemSize1;
+ lutTable[3] = lutBuffer + 3 * 256 * elemSize1;
+
+ CV_DbgAssert(lutcn == 3 || lutcn == 4);
+ if (lutcn == 3)
+ {
+ IppStatus status = ippiCopy_8u_C3P3R(lut.data, (int)lut.step[0], lutTable, (int)lut.step[0], sz256);
+ if (status < 0)
+ {
+ setIppErrorStatus();
+ return;
+ }
+ }
+ else if (lutcn == 4)
+ {
+ IppStatus status = ippiCopy_8u_C4P4R(lut.data, (int)lut.step[0], lutTable, (int)lut.step[0], sz256);
+ if (status < 0)
+ {
+ setIppErrorStatus();
+ return;
+ }
+ }
+
+ *ok = true;
+ }
+
+ ~IppLUTParallelBody_LUTCN()
+ {
+ if (lutBuffer != NULL)
+ ippFree(lutBuffer);
+ lutBuffer = NULL;
+ lutTable[0] = NULL;
+ }
+
+ void operator()( const cv::Range& range ) const
+ {
+ if (!*ok)
+ return;
+
+ const int row0 = range.start;
+ const int row1 = range.end;
+
+ Mat src = src_.rowRange(row0, row1);
+ Mat dst = dst_.rowRange(row0, row1);
+
+ if (lutcn == 3)
+ {
+ if (ippiLUTPalette_8u_C3R(
+ src.data, (int)src.step[0], dst.data, (int)dst.step[0],
+ ippiSize(dst.size()), lutTable, 8) >= 0)
+ return;
+ }
+ else if (lutcn == 4)
+ {
+ if (ippiLUTPalette_8u_C4R(
+ src.data, (int)src.step[0], dst.data, (int)dst.step[0],
+ ippiSize(dst.size()), lutTable, 8) >= 0)
+ return;
+ }
+ setIppErrorStatus();
+ *ok = false;
+ }
+private:
+ IppLUTParallelBody_LUTCN(const IppLUTParallelBody_LUTCN&);
+ IppLUTParallelBody_LUTCN& operator=(const IppLUTParallelBody_LUTCN&);
+};
+} // namespace ipp
+#endif // IPP
+
+class LUTParallelBody : public ParallelLoopBody
+{
+public:
+ bool* ok;
+ const Mat& src_;
+ const Mat& lut_;
+ Mat& dst_;
+
+ LUTFunc func;
+
+ LUTParallelBody(const Mat& src, const Mat& lut, Mat& dst, bool* _ok)
+ : ok(_ok), src_(src), lut_(lut), dst_(dst)
+ {
+ func = lutTab[lut.depth()];
+ *ok = (func != NULL);
+ }
+
+ void operator()( const cv::Range& range ) const
+ {
+ CV_DbgAssert(*ok);
+
+ const int row0 = range.start;
+ const int row1 = range.end;
+
+ Mat src = src_.rowRange(row0, row1);
+ Mat dst = dst_.rowRange(row0, row1);
+
+ int cn = src.channels();
+ int lutcn = lut_.channels();
+
+ const Mat* arrays[] = {&src, &dst, 0};
+ uchar* ptrs[2];
+ NAryMatIterator it(arrays, ptrs);
+ int len = (int)it.size;
+
+ for( size_t i = 0; i < it.nplanes; i++, ++it )
+ func(ptrs[0], lut_.data, ptrs[1], len, cn, lutcn);
+ }
+private:
+ LUTParallelBody(const LUTParallelBody&);
+ LUTParallelBody& operator=(const LUTParallelBody&);
+};
+
}
void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst )
_dst.create(src.dims, src.size, CV_MAKETYPE(_lut.depth(), cn));
Mat dst = _dst.getMat();
+ if (_src.dims() <= 2)
+ {
+ bool ok = false;
+ Ptr<ParallelLoopBody> body;
+#if defined(HAVE_IPP) && !defined(HAVE_IPP_ICV_ONLY)
+ size_t elemSize1 = CV_ELEM_SIZE1(dst.depth());
+#if 0 // there are no performance benefits (PR #2653)
+ if (lutcn == 1)
+ {
+ ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTC1(src, lut, dst, &ok);
+ body.reset(p);
+ }
+ else
+#endif
+ if ((lutcn == 3 || lutcn == 4) && elemSize1 == 1)
+ {
+ ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTCN(src, lut, dst, &ok);
+ body.reset(p);
+ }
+#endif
+ if (body == NULL || ok == false)
+ {
+ ok = false;
+ ParallelLoopBody* p = new LUTParallelBody(src, lut, dst, &ok);
+ body.reset(p);
+ }
+ if (body != NULL && ok)
+ {
+ Range all(0, dst.rows);
+ if (dst.total()>>18)
+ parallel_for_(all, *body, (double)std::max((size_t)1, dst.total()>>16));
+ else
+ (*body)(all);
+ if (ok)
+ return;
+ }
+ }
+
LUTFunc func = lutTab[lut.depth()];
CV_Assert( func != 0 );
typedef IppStatus (CV_STDCALL* IppDFTInitFunc)(int, int, IppHintAlgorithm, void*, uchar*);
#endif
+namespace cv
+{
+#if defined USE_IPP_DFT && !defined HAVE_IPP_ICV_ONLY
+
+typedef IppStatus (CV_STDCALL* ippiDFT_C_Func)(const Ipp32fc*, int, Ipp32fc*, int, const IppiDFTSpec_C_32fc*, Ipp8u*);
+typedef IppStatus (CV_STDCALL* ippiDFT_R_Func)(const Ipp32f* , int, Ipp32f* , int, const IppiDFTSpec_R_32f* , Ipp8u*);
+
+template <typename Dft>
+class Dft_C_IPPLoop_Invoker : public ParallelLoopBody
+{
+public:
+
+ Dft_C_IPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dft& _ippidft, int _norm_flag, bool *_ok) :
+ ParallelLoopBody(), src(_src), dst(_dst), ippidft(_ippidft), norm_flag(_norm_flag), ok(_ok)
+ {
+ *ok = true;
+ }
+
+ virtual void operator()(const Range& range) const
+ {
+ IppStatus status;
+ Ipp8u* pBuffer = 0;
+ Ipp8u* pMemInit= 0;
+ int sizeBuffer=0;
+ int sizeSpec=0;
+ int sizeInit=0;
+
+ IppiSize srcRoiSize = {src.cols, 1};
+
+ status = ippiDFTGetSize_C_32fc(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
+ if ( status < 0 )
+ {
+ *ok = false;
+ return;
+ }
+
+ IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)ippMalloc( sizeSpec );
+
+ if ( sizeInit > 0 )
+ pMemInit = (Ipp8u*)ippMalloc( sizeInit );
+
+ if ( sizeBuffer > 0 )
+ pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
+
+ status = ippiDFTInit_C_32fc( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
+
+ if ( sizeInit > 0 )
+ ippFree( pMemInit );
+
+ if ( status < 0 )
+ {
+ ippFree( pDFTSpec );
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+ *ok = false;
+ return;
+ }
+
+ for( int i = range.start; i < range.end; ++i)
+ if(!ippidft((Ipp32fc*)(src.data+i*src.step), (int)src.step,(Ipp32fc*)(dst.data+i*dst.step), (int)dst.step, pDFTSpec, (Ipp8u*)pBuffer))
+ {
+ *ok = false;
+ }
+
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+
+ ippFree( pDFTSpec );
+ }
+
+private:
+ const Mat& src;
+ Mat& dst;
+ const Dft& ippidft;
+ int norm_flag;
+ bool *ok;
+
+ const Dft_C_IPPLoop_Invoker& operator= (const Dft_C_IPPLoop_Invoker&);
+};
+
+template <typename Dft>
+class Dft_R_IPPLoop_Invoker : public ParallelLoopBody
+{
+public:
+
+ Dft_R_IPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dft& _ippidft, int _norm_flag, bool *_ok) :
+ ParallelLoopBody(), src(_src), dst(_dst), ippidft(_ippidft), norm_flag(_norm_flag), ok(_ok)
+ {
+ *ok = true;
+ }
+
+ virtual void operator()(const Range& range) const
+ {
+ IppStatus status;
+ Ipp8u* pBuffer = 0;
+ Ipp8u* pMemInit= 0;
+ int sizeBuffer=0;
+ int sizeSpec=0;
+ int sizeInit=0;
+
+ IppiSize srcRoiSize = {src.cols, 1};
+
+ status = ippiDFTGetSize_R_32f(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
+ if ( status < 0 )
+ {
+ *ok = false;
+ return;
+ }
+
+ IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)ippMalloc( sizeSpec );
+
+ if ( sizeInit > 0 )
+ pMemInit = (Ipp8u*)ippMalloc( sizeInit );
+
+ if ( sizeBuffer > 0 )
+ pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
+
+ status = ippiDFTInit_R_32f( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
+
+ if ( sizeInit > 0 )
+ ippFree( pMemInit );
+
+ if ( status < 0 )
+ {
+ ippFree( pDFTSpec );
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+ *ok = false;
+ return;
+ }
+
+ for( int i = range.start; i < range.end; ++i)
+ if(!ippidft(src.ptr<float>(i), (int)src.step,dst.ptr<float>(i), (int)dst.step, pDFTSpec, (Ipp8u*)pBuffer))
+ {
+ *ok = false;
+ }
+
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+
+ ippFree( pDFTSpec );
+ }
+
+private:
+ const Mat& src;
+ Mat& dst;
+ const Dft& ippidft;
+ int norm_flag;
+ bool *ok;
+
+ const Dft_R_IPPLoop_Invoker& operator= (const Dft_R_IPPLoop_Invoker&);
+};
+
+template <typename Dft>
+bool Dft_C_IPPLoop(const Mat& src, Mat& dst, const Dft& ippidft, int norm_flag)
+{
+ bool ok;
+ parallel_for_(Range(0, src.rows), Dft_C_IPPLoop_Invoker<Dft>(src, dst, ippidft, norm_flag, &ok), src.total()/(double)(1<<16) );
+ return ok;
+}
+
+template <typename Dft>
+bool Dft_R_IPPLoop(const Mat& src, Mat& dst, const Dft& ippidft, int norm_flag)
+{
+ bool ok;
+ parallel_for_(Range(0, src.rows), Dft_R_IPPLoop_Invoker<Dft>(src, dst, ippidft, norm_flag, &ok), src.total()/(double)(1<<16) );
+ return ok;
+}
+
+struct IPPDFT_C_Functor
+{
+ IPPDFT_C_Functor(ippiDFT_C_Func _func) : func(_func){}
+
+ bool operator()(const Ipp32fc* src, int srcStep, Ipp32fc* dst, int dstStep, const IppiDFTSpec_C_32fc* pDFTSpec, Ipp8u* pBuffer) const
+ {
+ return func ? func(src, srcStep, dst, dstStep, pDFTSpec, pBuffer) >= 0 : false;
+ }
+private:
+ ippiDFT_C_Func func;
+};
+
+struct IPPDFT_R_Functor
+{
+ IPPDFT_R_Functor(ippiDFT_R_Func _func) : func(_func){}
+
+ bool operator()(const Ipp32f* src, int srcStep, Ipp32f* dst, int dstStep, const IppiDFTSpec_R_32f* pDFTSpec, Ipp8u* pBuffer) const
+ {
+ return func ? func(src, srcStep, dst, dstStep, pDFTSpec, pBuffer) >= 0 : false;
+ }
+private:
+ ippiDFT_R_Func func;
+};
+
+static bool ippi_DFT_C_32F(const Mat& src, Mat& dst, bool inv, int norm_flag)
+{
+ IppStatus status;
+ Ipp8u* pBuffer = 0;
+ Ipp8u* pMemInit= 0;
+ int sizeBuffer=0;
+ int sizeSpec=0;
+ int sizeInit=0;
+
+ IppiSize srcRoiSize = {src.cols, src.rows};
+
+ status = ippiDFTGetSize_C_32fc(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
+ if ( status < 0 )
+ return false;
+
+ IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)ippMalloc( sizeSpec );
+
+ if ( sizeInit > 0 )
+ pMemInit = (Ipp8u*)ippMalloc( sizeInit );
+
+ if ( sizeBuffer > 0 )
+ pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
+
+ status = ippiDFTInit_C_32fc( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
+
+ if ( sizeInit > 0 )
+ ippFree( pMemInit );
+
+ if ( status < 0 )
+ {
+ ippFree( pDFTSpec );
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+ return false;
+ }
+
+ if (!inv)
+ status = ippiDFTFwd_CToC_32fc_C1R( (Ipp32fc*)src.data, (int)src.step, (Ipp32fc*)dst.data, (int)dst.step, pDFTSpec, pBuffer );
+ else
+ status = ippiDFTInv_CToC_32fc_C1R( (Ipp32fc*)src.data, (int)src.step, (Ipp32fc*)dst.data, (int)dst.step, pDFTSpec, pBuffer );
+
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+
+ ippFree( pDFTSpec );
+
+ return status >= 0;
+ }
+
+static bool ippi_DFT_R_32F(const Mat& src, Mat& dst, bool inv, int norm_flag)
+{
+ IppStatus status;
+ Ipp8u* pBuffer = 0;
+ Ipp8u* pMemInit= 0;
+ int sizeBuffer=0;
+ int sizeSpec=0;
+ int sizeInit=0;
+
+ IppiSize srcRoiSize = {src.cols, src.rows};
+
+ status = ippiDFTGetSize_R_32f(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
+ if ( status < 0 )
+ return false;
+
+ IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)ippMalloc( sizeSpec );
+
+ if ( sizeInit > 0 )
+ pMemInit = (Ipp8u*)ippMalloc( sizeInit );
+
+ if ( sizeBuffer > 0 )
+ pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
+
+ status = ippiDFTInit_R_32f( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
+
+ if ( sizeInit > 0 )
+ ippFree( pMemInit );
+
+ if ( status < 0 )
+ {
+ ippFree( pDFTSpec );
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+ return false;
+ }
+
+ if (!inv)
+ status = ippiDFTFwd_RToPack_32f_C1R( src.ptr<float>(), (int)(src.step), dst.ptr<float>(), (int)dst.step, pDFTSpec, pBuffer );
+ else
+ status = ippiDFTInv_PackToR_32f_C1R( src.ptr<float>(), (int)src.step, dst.ptr<float>(), (int)dst.step, pDFTSpec, pBuffer );
+
+ if ( sizeBuffer > 0 )
+ ippFree( pBuffer );
+
+ ippFree( pDFTSpec );
+
+ return status >= 0;
+}
+
+#endif
+}
+
#ifdef HAVE_CLAMDFFT
namespace cv {
Mat dst = _dst.getMat();
+#if defined USE_IPP_DFT && !defined HAVE_IPP_ICV_ONLY
+
+ if ((src.depth() == CV_32F) && (src.total()>(int)(1<<6)))
+ if ((flags & DFT_ROWS) == 0)
+ {
+ if (!real_transform)
+ {
+ if (ippi_DFT_C_32F(src,dst, inv, ipp_norm_flag))
+ return;
+ setIppErrorStatus();
+ }
+ else if (inv || !(flags & DFT_COMPLEX_OUTPUT))
+ {
+ if (ippi_DFT_R_32F(src,dst, inv, ipp_norm_flag))
+ return;
+ setIppErrorStatus();
+ }
+ }
+ else
+ {
+ if (!real_transform)
+ {
+ ippiDFT_C_Func ippiFunc = inv ? (ippiDFT_C_Func)ippiDFTInv_CToC_32fc_C1R : (ippiDFT_C_Func)ippiDFTFwd_CToC_32fc_C1R;
+ if (Dft_C_IPPLoop(src,dst, IPPDFT_C_Functor(ippiFunc),ipp_norm_flag))
+ return;
+ setIppErrorStatus();
+ }
+ else if (inv || !(flags & DFT_COMPLEX_OUTPUT))
+ {
+ ippiDFT_R_Func ippiFunc = inv ? (ippiDFT_R_Func)ippiDFTInv_PackToR_32f_C1R : (ippiDFT_R_Func)ippiDFTFwd_RToPack_32f_C1R;
+ if (Dft_R_IPPLoop(src,dst, IPPDFT_R_Functor(ippiFunc),ipp_norm_flag))
+ return;
+ setIppErrorStatus();
+ }
+ }
+#endif
+
if( !real_transform )
elem_size = complex_elem_size;
The function ``imwrite`` saves the image to the specified file. The image format is chosen based on the ``filename`` extension (see
:ocv:func:`imread` for the list of extensions). Only 8-bit (or 16-bit unsigned (``CV_16U``) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with 'BGR' channel order) images can be saved using this function. If the format, depth or channel order is different, use
:ocv:func:`Mat::convertTo` , and
-:ocv:func:`cvtColor` to convert it before saving. Or, use the universal XML I/O functions to save the image to XML or YAML format.
+:ocv:func:`cvtColor` to convert it before saving. Or, use the universal :ocv:class:`FileStorage` I/O functions to save the image to XML or YAML format.
It is possible to store PNG images with an alpha channel using this function. To do this, create 8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535. The sample below shows how to create such a BGRA image and store to PNG file. It also demonstrates how to set custom compression parameters ::
virtual bool open( int index );
virtual void close();
virtual double getProperty(int);
- virtual bool setProperty(int, double) { return false; }
+ virtual bool setProperty(int, double);
virtual bool grabFrame();
virtual IplImage* retrieveFrame(int);
virtual int getCaptureDomain() { return CV_CAP_VFW; } // Return the type of the capture object: CV_CAP_VFW, etc...
HWND capWnd;
VIDEOHDR* hdr;
DWORD fourcc;
+ int width, height;
+ int widthSet, heightSet;
HIC hic;
IplImage* frame;
};
fourcc = 0;
hic = 0;
frame = 0;
+ width = height = -1;
+ widthSet = heightSet = 0;
}
void CvCaptureCAM_VFW::closeHIC()
memset( &caps, 0, sizeof(caps));
capDriverGetCaps( hWndC, &caps, sizeof(caps));
- ::MoveWindow( hWndC, 0, 0, 320, 240, TRUE );
+ CAPSTATUS status = {};
+ capGetStatus(hWndC, &status, sizeof(status));
+ ::SetWindowPos(hWndC, NULL, 0, 0, status.uiImageWidth, status.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE);
capSetUserData( hWndC, (size_t)this );
capSetCallbackOnFrame( hWndC, frameCallback );
CAPTUREPARMS p;
capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
- p.dwRequestMicroSecPerFrame = 66667/2;
+ p.dwRequestMicroSecPerFrame = 66667/2; // 30 FPS
capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
//capPreview( hWndC, 1 );
capPreviewScale(hWndC,FALSE);
capPreviewRate(hWndC,1);
+
+ // Get frame initial parameters.
+ const DWORD size = capGetVideoFormatSize(capWnd);
+ if( size > 0 )
+ {
+ unsigned char *pbi = new unsigned char[size];
+ if( pbi )
+ {
+ if( capGetVideoFormat(capWnd, pbi, size) == size )
+ {
+ BITMAPINFOHEADER& vfmt = ((BITMAPINFO*)pbi)->bmiHeader;
+ widthSet = vfmt.biWidth;
+ heightSet = vfmt.biHeight;
+ fourcc = vfmt.biCompression;
+ }
+ delete []pbi;
+ }
+ }
+ // And alternative way in case of failure.
+ if( widthSet == 0 || heightSet == 0 )
+ {
+ widthSet = status.uiImageWidth;
+ heightSet = status.uiImageHeight;
+ }
+
}
return capWnd != 0;
}
bool CvCaptureCAM_VFW::grabFrame()
{
if( capWnd )
- {
- SendMessage( capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 );
- return true;
- }
+ return capGrabFrameNoStop(capWnd) == TRUE;
+
return false;
}
BITMAPINFO vfmt;
memset( &vfmt, 0, sizeof(vfmt));
BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;
- int sz, prevWidth, prevHeight;
if( !capWnd )
return 0;
- sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
- prevWidth = frame ? frame->width : 0;
- prevHeight = frame ? frame->height : 0;
+ const DWORD sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
+ const int prevWidth = frame ? frame->width : 0;
+ const int prevHeight = frame ? frame->height : 0;
if( !hdr || hdr->lpData == 0 || sz == 0 )
return 0;
frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 );
}
- if( vfmt.bmiHeader.biCompression != BI_RGB ||
- vfmt.bmiHeader.biBitCount != 24 )
+ if( vfmt0.biCompression != BI_RGB ||
+ vfmt0.biBitCount != 24 )
{
BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );
switch( property_id )
{
case CV_CAP_PROP_FRAME_WIDTH:
- return frame ? frame->width : 0;
+ return widthSet;
case CV_CAP_PROP_FRAME_HEIGHT:
- return frame ? frame->height : 0;
+ return heightSet;
case CV_CAP_PROP_FOURCC:
return fourcc;
+ case CV_CAP_PROP_FPS:
+ {
+ CAPTUREPARMS params = {};
+ if( capCaptureGetSetup(capWnd, ¶ms, sizeof(params)) )
+ return 1e6 / params.dwRequestMicroSecPerFrame;
+ }
+ break;
+ default:
+ break;
}
return 0;
}
+bool CvCaptureCAM_VFW::setProperty(int property_id, double value)
+{
+ bool handledSize = false;
+
+ switch( property_id )
+ {
+ case CV_CAP_PROP_FRAME_WIDTH:
+ width = cvRound(value);
+ handledSize = true;
+ break;
+ case CV_CAP_PROP_FRAME_HEIGHT:
+ height = cvRound(value);
+ handledSize = true;
+ break;
+ case CV_CAP_PROP_FOURCC:
+ break;
+ case CV_CAP_PROP_FPS:
+ if( value > 0 )
+ {
+ CAPTUREPARMS params;
+ if( capCaptureGetSetup(capWnd, ¶ms, sizeof(params)) )
+ {
+ params.dwRequestMicroSecPerFrame = cvRound(1e6/value);
+ return capCaptureSetSetup(capWnd, ¶ms, sizeof(params)) == TRUE;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ( handledSize )
+ {
+ // If both width and height are set then change frame size.
+ if( width > 0 && height > 0 )
+ {
+ const DWORD size = capGetVideoFormatSize(capWnd);
+ if( size == 0 )
+ return false;
+
+ unsigned char *pbi = new unsigned char[size];
+ if( !pbi )
+ return false;
+
+ if( capGetVideoFormat(capWnd, pbi, size) != size )
+ {
+ delete []pbi;
+ return false;
+ }
+
+ BITMAPINFOHEADER& vfmt = ((BITMAPINFO*)pbi)->bmiHeader;
+ bool success = true;
+ if( width != vfmt.biWidth || height != vfmt.biHeight )
+ {
+ // Change frame size.
+ vfmt.biWidth = width;
+ vfmt.biHeight = height;
+ vfmt.biSizeImage = height * ((width * vfmt.biBitCount + 31) / 32) * 4;
+ vfmt.biCompression = BI_RGB;
+ success = capSetVideoFormat(capWnd, pbi, size) == TRUE;
+ }
+ if( success )
+ {
+ // Adjust capture window size.
+ CAPSTATUS status = {};
+ capGetStatus(capWnd, &status, sizeof(status));
+ ::SetWindowPos(capWnd, NULL, 0, 0, status.uiImageWidth, status.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE);
+ // Store frame size.
+ widthSet = width;
+ heightSet = height;
+ }
+ delete []pbi;
+ width = height = -1;
+
+ return success;
+ }
+
+ return true;
+ }
+
+ return false;
+}
CvCapture* cvCreateCameraCapture_VFW( int index )
{
default:
return false;
}
-
#undef IPP_MORPH_CASE
+
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8
+ return false; /// It disables false positive warning in GCC 4.8.2
+#endif
#endif
}
}
Size srcRoiSize = randomSize(1, MAX_VALUE), dstRoiSize;
// Make sure the width is a multiple of the requested value, and no more
- srcRoiSize.width &= ~((widthMultiple * 2) - 1);
- srcRoiSize.width += widthMultiple;
+ srcRoiSize.width += widthMultiple - 1 - (srcRoiSize.width - 1) % widthMultiple;
dstRoiSize.width = cvRound(srcRoiSize.width * fx);
dstRoiSize.height = cvRound(srcRoiSize.height * fy);
OCL_TEST_CYCLE() hog.detectMultiScale(src, found_locations);
std::sort(found_locations.begin(), found_locations.end(), RectLess());
- SANITY_CHECK(found_locations, 1 + DBL_EPSILON);
+ SANITY_CHECK(found_locations, 3);
}
}
(int) MOTION_AFFINE, (int) MOTION_HOMOGRAPHY)
)
{
-
- Mat inputImage = imread(getDataPath("cv/shared/fruits.png"),0);
- Mat img;
- resize(inputImage, img, Size(216,216));
+ Mat img = imread(getDataPath("cv/shared/fruits_ecc.png"),0);
Mat templateImage;
int transform_type = get<0>(GetParam());