From: Vadim Pisarevsky Date: Sat, 19 Jan 2013 20:58:51 +0000 (+0400) Subject: removed rarely used fixed_size parameter from AutoBuffer type, added optional AutoBuf... X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~4037^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c197a46e7eee1362db189a6828bde1dca3344b9e;p=platform%2Fupstream%2Fopencv.git removed rarely used fixed_size parameter from AutoBuffer type, added optional AutoBuffer* but to cvarrToMat in order to speedup CvSeq->Mat conversion; finished conversion of convex hull and related functions to C++ --- diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 7afe332..806d9ee 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -109,6 +109,8 @@ template class CV_EXPORTS MatIterator_; template class CV_EXPORTS MatConstIterator_; template class CV_EXPORTS MatCommaInitializer_; +template class CV_EXPORTS AutoBuffer; + CV_EXPORTS string format( const char* fmt, ... ); CV_EXPORTS string tempfile( const char* suffix CV_DEFAULT(0)); @@ -2061,7 +2063,8 @@ CV_EXPORTS void swap(Mat& a, Mat& b); //! converts array (CvMat or IplImage) to cv::Mat CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false, - bool allowND=true, int coiMode=0); + bool allowND=true, int coiMode=0, + AutoBuffer* buf=0); //! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it. CV_EXPORTS void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1); //! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage @@ -3081,7 +3084,7 @@ public: \code void my_func(const cv::Mat& m) { - cv::AutoBuffer buf; // create automatic buffer containing 1000 floats + cv::AutoBuffer buf; // create automatic buffer containing 1000 floats buf.allocate(m.rows); // if m.rows <= 1000, the pre-allocated buffer is used, // otherwise the buffer of "m.rows" floats will be allocated @@ -3090,16 +3093,22 @@ public: } \endcode */ -template class CV_EXPORTS AutoBuffer +template class CV_EXPORTS AutoBuffer { public: typedef _Tp value_type; - enum { buffer_padding = (int)((16 + sizeof(_Tp) - 1)/sizeof(_Tp)) }; + enum { fixed_size = 1024/sizeof(_Tp)+8, buffer_padding = (int)((16 + sizeof(_Tp) - 1)/sizeof(_Tp)) }; //! the default contructor AutoBuffer(); //! constructor taking the real buffer size AutoBuffer(size_t _size); + + //! the copy constructor + AutoBuffer(const AutoBuffer<_Tp>& buf); + //! the assignment operator + AutoBuffer<_Tp>& operator = (const AutoBuffer<_Tp>& buf); + //! destructor. calls deallocate() ~AutoBuffer(); @@ -4318,7 +4327,6 @@ public: int index; }; - class CV_EXPORTS Algorithm; class CV_EXPORTS AlgorithmInfo; struct CV_EXPORTS AlgorithmInfoData; diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index c1928b7..af89b5b 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -2534,23 +2534,46 @@ inline Point LineIterator::pos() const /////////////////////////////// AutoBuffer //////////////////////////////////////// -template inline AutoBuffer<_Tp, fixed_size>::AutoBuffer() +template inline AutoBuffer<_Tp>::AutoBuffer() { ptr = buf; sz = fixed_size; } -template inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size) +template inline AutoBuffer<_Tp>::AutoBuffer(size_t _size) { ptr = buf; sz = fixed_size; allocate(_size); } -template inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer() +template +inline AutoBuffer<_Tp>::AutoBuffer(const AutoBuffer<_Tp>& abuf ) +{ + ptr = buf; + sz = fixed_size; + allocate(abuf.size); + for( size_t i = 0; i < sz; i++ ) + ptr[i] = abuf.ptr[i]; +} + +template +inline AutoBuffer<_Tp>& AutoBuffer<_Tp>::operator = (const AutoBuffer<_Tp>& abuf ) +{ + if( this != &abuf ) + { + deallocate(); + allocate(abuf.size); + for( size_t i = 0; i < sz; i++ ) + ptr[i] = abuf.ptr[i]; + } + return *this; +} + +template inline AutoBuffer<_Tp>::~AutoBuffer() { deallocate(); } -template inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size) +template inline void AutoBuffer<_Tp>::allocate(size_t _size) { if(_size <= sz) { @@ -2565,17 +2588,17 @@ template inline void AutoBuffer<_Tp, fixed_size } } -template inline void AutoBuffer<_Tp, fixed_size>::deallocate() +template inline void AutoBuffer<_Tp>::deallocate() { if( ptr != buf ) { delete[] ptr; ptr = buf; - sz = 0; + sz = fixed_size; } } -template inline void AutoBuffer<_Tp, fixed_size>::resize(size_t _size) +template inline void AutoBuffer<_Tp>::resize(size_t _size) { if(_size <= sz) { @@ -2598,13 +2621,13 @@ template inline void AutoBuffer<_Tp, fixed_size delete[] prevptr; } -template inline size_t AutoBuffer<_Tp, fixed_size>::size() const +template inline size_t AutoBuffer<_Tp>::size() const { return sz; } -template inline AutoBuffer<_Tp, fixed_size>::operator _Tp* () +template inline AutoBuffer<_Tp>::operator _Tp* () { return ptr; } -template inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const +template inline AutoBuffer<_Tp>::operator const _Tp* () const { return ptr; } diff --git a/modules/core/src/convert.cpp b/modules/core/src/convert.cpp index 0ba066e..439d4c1 100644 --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@ -1314,7 +1314,7 @@ cvMixChannels( const CvArr** src, int src_count, CvArr** dst, int dst_count, const int* from_to, int pair_count ) { - cv::AutoBuffer buf(src_count + dst_count); + cv::AutoBuffer buf(src_count + dst_count); int i; for( i = 0; i < src_count; i++ ) diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 3b80d5a..4be71d4 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -669,7 +669,7 @@ void Mat::push_back(const Mat& elems) Mat cvarrToMat(const CvArr* arr, bool copyData, - bool /*allowND*/, int coiMode) + bool /*allowND*/, int coiMode, AutoBuffer* abuf ) { if( !arr ) return Mat(); @@ -687,10 +687,21 @@ Mat cvarrToMat(const CvArr* arr, bool copyData, if( CV_IS_SEQ(arr) ) { CvSeq* seq = (CvSeq*)arr; - CV_Assert(seq->total > 0 && CV_ELEM_SIZE(seq->flags) == seq->elem_size); + int total = seq->total, type = CV_MAT_TYPE(seq->flags), esz = seq->elem_size; + if( total == 0 ) + return Mat(); + CV_Assert(total > 0 && CV_ELEM_SIZE(seq->flags) == esz); if(!copyData && seq->first->next == seq->first) - return Mat(seq->total, 1, CV_MAT_TYPE(seq->flags), seq->first->data); - Mat buf(seq->total, 1, CV_MAT_TYPE(seq->flags)); + return Mat(total, 1, type, seq->first->data); + if( abuf ) + { + abuf->allocate(((size_t)total*esz + sizeof(double)-1)/sizeof(double)); + double* bufdata = *abuf; + cvCvtSeqToArray(seq, bufdata, CV_WHOLE_SEQ); + return Mat(total, 1, type, bufdata); + } + + Mat buf(total, 1, type); cvCvtSeqToArray(seq, buf.data, CV_WHOLE_SEQ); return buf; } diff --git a/modules/gpu/src/matrix_reductions.cpp b/modules/gpu/src/matrix_reductions.cpp index 4295644..97c92be 100644 --- a/modules/gpu/src/matrix_reductions.cpp +++ b/modules/gpu/src/matrix_reductions.cpp @@ -92,7 +92,7 @@ namespace } void download(double** hptrs) { - AutoBuffer hbuf(count); + AutoBuffer hbuf(count); cudaSafeCall( cudaMemcpy((void*)hbuf, pdev, count * sizeof(double), cudaMemcpyDeviceToHost) ); for (int i = 0; i < count; ++i) *hptrs[i] = hbuf[i]; diff --git a/modules/highgui/src/grfmt_pxm.cpp b/modules/highgui/src/grfmt_pxm.cpp index f73bbb1..57b222e 100644 --- a/modules/highgui/src/grfmt_pxm.cpp +++ b/modules/highgui/src/grfmt_pxm.cpp @@ -202,9 +202,9 @@ bool PxMDecoder::readData( Mat& img ) if( m_offset < 0 || !m_strm.isOpened()) return false; - AutoBuffer _src(src_pitch + 32); + AutoBuffer _src(src_pitch + 32); uchar* src = _src; - AutoBuffer _gray_palette; + AutoBuffer _gray_palette; uchar* gray_palette = _gray_palette; // create LUT for converting colors diff --git a/modules/highgui/src/grfmt_tiff.cpp b/modules/highgui/src/grfmt_tiff.cpp index d2321ce..7da9320 100644 --- a/modules/highgui/src/grfmt_tiff.cpp +++ b/modules/highgui/src/grfmt_tiff.cpp @@ -469,7 +469,7 @@ bool TiffEncoder::writeLibTiff( const Mat& img, const vector& /*params*/) // row buffer, because TIFFWriteScanline modifies the original data! size_t scanlineSize = TIFFScanlineSize(pTiffHandle); - AutoBuffer _buffer(scanlineSize+32); + AutoBuffer _buffer(scanlineSize+32); uchar* buffer = _buffer; if (!buffer) { @@ -577,9 +577,9 @@ bool TiffEncoder::write( const Mat& img, const vector& /*params*/) #endif*/ int directoryOffset = 0; - AutoBuffer stripOffsets(stripCount); - AutoBuffer stripCounts(stripCount); - AutoBuffer _buffer(fileStep+32); + AutoBuffer stripOffsets(stripCount); + AutoBuffer stripCounts(stripCount); + AutoBuffer _buffer(fileStep+32); uchar* buffer = _buffer; int stripOffsetsOffset = 0; int stripCountsOffset = 0; diff --git a/modules/imgproc/src/convhull.cpp b/modules/imgproc/src/convhull.cpp index a067638..7b2c3d0 100644 --- a/modules/imgproc/src/convhull.cpp +++ b/modules/imgproc/src/convhull.cpp @@ -43,459 +43,6 @@ #include #if 0 -static int -icvSklansky_32s( CvPoint** array, int start, int end, int* stack, int nsign, int sign2 ) -{ - int incr = end > start ? 1 : -1; - /* prepare first triangle */ - int pprev = start, pcur = pprev + incr, pnext = pcur + incr; - int stacksize = 3; - - if( start == end || - (array[start]->x == array[end]->x && - array[start]->y == array[end]->y) ) - { - stack[0] = start; - return 1; - } - - stack[0] = pprev; - stack[1] = pcur; - stack[2] = pnext; - - end += incr; /* make end = afterend */ - - while( pnext != end ) - { - /* check the angle p1,p2,p3 */ - int cury = array[pcur]->y; - int nexty = array[pnext]->y; - int by = nexty - cury; - - if( CV_SIGN(by) != nsign ) - { - int ax = array[pcur]->x - array[pprev]->x; - int bx = array[pnext]->x - array[pcur]->x; - int ay = cury - array[pprev]->y; - int convexity = ay*bx - ax*by;/* if >0 then convex angle */ - - if( CV_SIGN(convexity) == sign2 && (ax != 0 || ay != 0) ) - { - pprev = pcur; - pcur = pnext; - pnext += incr; - stack[stacksize] = pnext; - stacksize++; - } - else - { - if( pprev == start ) - { - pcur = pnext; - stack[1] = pcur; - pnext += incr; - stack[2] = pnext; - } - else - { - stack[stacksize-2] = pnext; - pcur = pprev; - pprev = stack[stacksize-4]; - stacksize--; - } - } - } - else - { - pnext += incr; - stack[stacksize-1] = pnext; - } - } - - return --stacksize; -} - -static int -icvSklansky_32f( CvPoint2D32f** array, int start, int end, int* stack, int nsign, int sign2 ) -{ - int incr = end > start ? 1 : -1; - /* prepare first triangle */ - int pprev = start, pcur = pprev + incr, pnext = pcur + incr; - int stacksize = 3; - - if( start == end || - (array[start]->x == array[end]->x && - array[start]->y == array[end]->y) ) - { - stack[0] = start; - return 1; - } - - stack[0] = pprev; - stack[1] = pcur; - stack[2] = pnext; - - end += incr; /* make end = afterend */ - - while( pnext != end ) - { - /* check the angle p1,p2,p3 */ - float cury = array[pcur]->y; - float nexty = array[pnext]->y; - float by = nexty - cury; - - if( CV_SIGN( by ) != nsign ) - { - float ax = array[pcur]->x - array[pprev]->x; - float bx = array[pnext]->x - array[pcur]->x; - float ay = cury - array[pprev]->y; - float convexity = ay*bx - ax*by;/* if >0 then convex angle */ - - if( CV_SIGN( convexity ) == sign2 && (ax != 0 || ay != 0) ) - { - pprev = pcur; - pcur = pnext; - pnext += incr; - stack[stacksize] = pnext; - stacksize++; - } - else - { - if( pprev == start ) - { - pcur = pnext; - stack[1] = pcur; - pnext += incr; - stack[2] = pnext; - - } - else - { - stack[stacksize-2] = pnext; - pcur = pprev; - pprev = stack[stacksize-4]; - stacksize--; - } - } - } - else - { - pnext += incr; - stack[stacksize-1] = pnext; - } - } - - return --stacksize; -} - -typedef int (*sklansky_func)( CvPoint** points, int start, int end, - int* stack, int sign, int sign2 ); - -#define cmp_pts( pt1, pt2 ) \ - ((pt1)->x < (pt2)->x || ((pt1)->x <= (pt2)->x && (pt1)->y < (pt2)->y)) -static CV_IMPLEMENT_QSORT( icvSortPointsByPointers_32s, CvPoint*, cmp_pts ) -static CV_IMPLEMENT_QSORT( icvSortPointsByPointers_32f, CvPoint2D32f*, cmp_pts ) - -static void -icvCalcAndWritePtIndices( CvPoint** pointer, int* stack, int start, int end, - CvSeq* ptseq, CvSeqWriter* writer ) -{ - int i, incr = start < end ? 1 : -1; - int idx, first_idx = ptseq->first->start_index; - - for( i = start; i != end; i += incr ) - { - CvPoint* ptr = (CvPoint*)pointer[stack[i]]; - CvSeqBlock* block = ptseq->first; - while( (unsigned)(idx = (int)(ptr - (CvPoint*)block->data)) >= (unsigned)block->count ) - { - block = block->next; - if( block == ptseq->first ) - CV_Error( CV_StsError, "Internal error" ); - } - idx += block->start_index - first_idx; - CV_WRITE_SEQ_ELEM( idx, *writer ); - } -} - - -CV_IMPL CvSeq* -cvConvexHull2( const CvArr* array, void* hull_storage, - int orientation, int return_points ) -{ - union { CvContour* c; CvSeq* s; } hull; - cv::AutoBuffer _pointer; - CvPoint** pointer; - CvPoint2D32f** pointerf = 0; - cv::AutoBuffer _stack; - int* stack; - - hull.s = 0; - - CvMat* mat = 0; - CvSeqReader reader; - CvSeqWriter writer; - CvContour contour_header; - union { CvContour c; CvSeq s; } hull_header; - CvSeqBlock block, hullblock; - CvSeq* ptseq = 0; - CvSeq* hullseq = 0; - int is_float; - int* t_stack; - int t_count; - int i, miny_ind = 0, maxy_ind = 0, total; - int hulltype; - int stop_idx; - sklansky_func sklansky; - - if( CV_IS_SEQ( array )) - { - ptseq = (CvSeq*)array; - if( !CV_IS_SEQ_POINT_SET( ptseq )) - CV_Error( CV_StsBadArg, "Unsupported sequence type" ); - if( hull_storage == 0 ) - hull_storage = ptseq->storage; - } - else - { - ptseq = cvPointSeqFromMat( CV_SEQ_KIND_GENERIC, array, &contour_header, &block ); - } - - if( CV_IS_STORAGE( hull_storage )) - { - if( return_points ) - { - hullseq = cvCreateSeq( - CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE(ptseq)| - CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX, - sizeof(CvContour), sizeof(CvPoint),(CvMemStorage*)hull_storage ); - } - else - { - hullseq = cvCreateSeq( - CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_PPOINT| - CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX, - sizeof(CvContour), sizeof(CvPoint*), (CvMemStorage*)hull_storage ); - } - } - else - { - if( !CV_IS_MAT( hull_storage )) - CV_Error(CV_StsBadArg, "Destination must be valid memory storage or matrix"); - - mat = (CvMat*)hull_storage; - - if( (mat->cols != 1 && mat->rows != 1) || !CV_IS_MAT_CONT(mat->type)) - CV_Error( CV_StsBadArg, - "The hull matrix should be continuous and have a single row or a single column" ); - - if( mat->cols + mat->rows - 1 < ptseq->total ) - CV_Error( CV_StsBadSize, "The hull matrix size might be not enough to fit the hull" ); - - if( CV_MAT_TYPE(mat->type) != CV_SEQ_ELTYPE(ptseq) && - CV_MAT_TYPE(mat->type) != CV_32SC1 ) - CV_Error( CV_StsUnsupportedFormat, - "The hull matrix must have the same type as input or 32sC1 (integers)" ); - - hullseq = cvMakeSeqHeaderForArray( - CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED, - sizeof(contour_header), CV_ELEM_SIZE(mat->type), mat->data.ptr, - mat->cols + mat->rows - 1, &hull_header.s, &hullblock ); - - cvClearSeq( hullseq ); - } - - total = ptseq->total; - if( total == 0 ) - { - if( mat ) - CV_Error( CV_StsBadSize, - "Point sequence can not be empty if the output is matrix" ); - return hull.s; - } - - cvStartAppendToSeq( hullseq, &writer ); - - is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2; - hulltype = CV_SEQ_ELTYPE(hullseq); - sklansky = !is_float ? (sklansky_func)icvSklansky_32s : - (sklansky_func)icvSklansky_32f; - - _pointer.allocate( ptseq->total ); - _stack.allocate( ptseq->total + 2); - pointer = _pointer; - pointerf = (CvPoint2D32f**)pointer; - stack = _stack; - - cvStartReadSeq( ptseq, &reader ); - - for( i = 0; i < total; i++ ) - { - pointer[i] = (CvPoint*)reader.ptr; - CV_NEXT_SEQ_ELEM( ptseq->elem_size, reader ); - } - - // sort the point set by x-coordinate, find min and max y - if( !is_float ) - { - icvSortPointsByPointers_32s( pointer, total, 0 ); - for( i = 1; i < total; i++ ) - { - int y = pointer[i]->y; - if( pointer[miny_ind]->y > y ) - miny_ind = i; - if( pointer[maxy_ind]->y < y ) - maxy_ind = i; - } - } - else - { - icvSortPointsByPointers_32f( pointerf, total, 0 ); - for( i = 1; i < total; i++ ) - { - float y = pointerf[i]->y; - if( pointerf[miny_ind]->y > y ) - miny_ind = i; - if( pointerf[maxy_ind]->y < y ) - maxy_ind = i; - } - } - - if( pointer[0]->x == pointer[total-1]->x && - pointer[0]->y == pointer[total-1]->y ) - { - if( hulltype == CV_SEQ_ELTYPE_PPOINT ) - { - CV_WRITE_SEQ_ELEM( pointer[0], writer ); - } - else if( hulltype == CV_SEQ_ELTYPE_INDEX ) - { - int index = 0; - CV_WRITE_SEQ_ELEM( index, writer ); - } - else - { - CvPoint pt = pointer[0][0]; - CV_WRITE_SEQ_ELEM( pt, writer ); - } - goto finish_hull; - } - - /*upper half */ - { - int *tl_stack = stack; - int tl_count = sklansky( pointer, 0, maxy_ind, tl_stack, -1, 1 ); - int *tr_stack = tl_stack + tl_count; - int tr_count = sklansky( pointer, ptseq->total - 1, maxy_ind, tr_stack, -1, -1 ); - - /* gather upper part of convex hull to output */ - if( orientation == CV_COUNTER_CLOCKWISE ) - { - CV_SWAP( tl_stack, tr_stack, t_stack ); - CV_SWAP( tl_count, tr_count, t_count ); - } - - if( hulltype == CV_SEQ_ELTYPE_PPOINT ) - { - for( i = 0; i < tl_count - 1; i++ ) - CV_WRITE_SEQ_ELEM( pointer[tl_stack[i]], writer ); - - for( i = tr_count - 1; i > 0; i-- ) - CV_WRITE_SEQ_ELEM( pointer[tr_stack[i]], writer ); - } - else if( hulltype == CV_SEQ_ELTYPE_INDEX ) - { - icvCalcAndWritePtIndices( pointer, tl_stack, 0, tl_count-1, ptseq, &writer ); - icvCalcAndWritePtIndices( pointer, tr_stack, tr_count-1, 0, ptseq, &writer ); - } - else - { - for( i = 0; i < tl_count - 1; i++ ) - CV_WRITE_SEQ_ELEM( pointer[tl_stack[i]][0], writer ); - - for( i = tr_count - 1; i > 0; i-- ) - CV_WRITE_SEQ_ELEM( pointer[tr_stack[i]][0], writer ); - } - stop_idx = tr_count > 2 ? tr_stack[1] : tl_count > 2 ? tl_stack[tl_count - 2] : -1; - } - - /* lower half */ - { - int *bl_stack = stack; - int bl_count = sklansky( pointer, 0, miny_ind, bl_stack, 1, -1 ); - int *br_stack = stack + bl_count; - int br_count = sklansky( pointer, ptseq->total - 1, miny_ind, br_stack, 1, 1 ); - - if( orientation != CV_COUNTER_CLOCKWISE ) - { - CV_SWAP( bl_stack, br_stack, t_stack ); - CV_SWAP( bl_count, br_count, t_count ); - } - - if( stop_idx >= 0 ) - { - int check_idx = bl_count > 2 ? bl_stack[1] : - bl_count + br_count > 2 ? br_stack[2-bl_count] : -1; - if( check_idx == stop_idx || (check_idx >= 0 && - pointer[check_idx]->x == pointer[stop_idx]->x && - pointer[check_idx]->y == pointer[stop_idx]->y) ) - { - /* if all the points lie on the same line, then - the bottom part of the convex hull is the mirrored top part - (except the exteme points).*/ - bl_count = MIN( bl_count, 2 ); - br_count = MIN( br_count, 2 ); - } - } - - if( hulltype == CV_SEQ_ELTYPE_PPOINT ) - { - for( i = 0; i < bl_count - 1; i++ ) - CV_WRITE_SEQ_ELEM( pointer[bl_stack[i]], writer ); - - for( i = br_count - 1; i > 0; i-- ) - CV_WRITE_SEQ_ELEM( pointer[br_stack[i]], writer ); - } - else if( hulltype == CV_SEQ_ELTYPE_INDEX ) - { - icvCalcAndWritePtIndices( pointer, bl_stack, 0, bl_count-1, ptseq, &writer ); - icvCalcAndWritePtIndices( pointer, br_stack, br_count-1, 0, ptseq, &writer ); - } - else - { - for( i = 0; i < bl_count - 1; i++ ) - CV_WRITE_SEQ_ELEM( pointer[bl_stack[i]][0], writer ); - - for( i = br_count - 1; i > 0; i-- ) - CV_WRITE_SEQ_ELEM( pointer[br_stack[i]][0], writer ); - } - } - -finish_hull: - cvEndWriteSeq( &writer ); - - if( mat ) - { - if( mat->rows > mat->cols ) - mat->rows = hullseq->total; - else - mat->cols = hullseq->total; - } - else - { - hull.s = hullseq; - hull.c->rect = cvBoundingRect( ptseq, - ptseq->header_size < (int)sizeof(CvContour) || - &ptseq->flags == &contour_header.flags ); - - /*if( ptseq != (CvSeq*)&contour_header ) - hullseq->v_prev = ptseq;*/ - } - - return hull.s; -} - - /* contour must be a simple polygon */ /* it must have more than 3 points */ CV_IMPL CvSeq* cvConvexityDefects( const CvArr* array, @@ -812,29 +359,7 @@ cvCheckContourConvexity( const CvArr* array ) return flag; } -void cv::convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool returnPoints ) -{ - Mat points = _points.getMat(); - int nelems = points.checkVector(2), depth = points.depth(); - CV_Assert(nelems >= 0 && (depth == CV_32F || depth == CV_32S)); - - if( nelems == 0 ) - { - _hull.release(); - return; - } - - returnPoints = !_hull.fixedType() ? returnPoints : _hull.type() != CV_32S; - Mat hull(nelems, 1, returnPoints ? CV_MAKETYPE(depth, 2) : CV_32S); - CvMat _cpoints = points, _chull = hull; - cvConvexHull2(&_cpoints, &_chull, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, returnPoints); - _hull.create(_chull.rows, 1, hull.type(), -1, true); - Mat dhull = _hull.getMat(), shull(dhull.size(), dhull.type(), hull.data); - shull.copyTo(dhull); - std::cout << "convex hull: " << dhull; -} - -#else +#endif namespace cv { @@ -920,57 +445,6 @@ struct CHullCmpPoints }; -void convexityDefects( InputArray _points, InputArray _hull, OutputArray _defects ) -{ - Mat points = _points.getMat(); - int ptnum = points.checkVector(2, CV_32S); - CV_Assert( ptnum > 3 ); - Mat hull = _hull.getMat(); - CV_Assert( hull.checkVector(1, CV_32S) > 2 ); - Ptr storage = cvCreateMemStorage(); - - CvMat c_points = points, c_hull = hull; - CvSeq* seq = cvConvexityDefects(&c_points, &c_hull, storage); - int i, n = seq->total; - - if( n == 0 ) - { - _defects.release(); - return; - } - - _defects.create(n, 1, CV_32SC4); - Mat defects = _defects.getMat(); - - SeqIterator it = Seq(seq).begin(); - CvPoint* ptorg = (CvPoint*)points.data; - - for( i = 0; i < n; i++, ++it ) - { - CvConvexityDefect& d = *it; - int idx0 = (int)(d.start - ptorg); - int idx1 = (int)(d.end - ptorg); - int idx2 = (int)(d.depth_point - ptorg); - CV_Assert( 0 <= idx0 && idx0 < ptnum ); - CV_Assert( 0 <= idx1 && idx1 < ptnum ); - CV_Assert( 0 <= idx2 && idx2 < ptnum ); - CV_Assert( d.depth >= 0 ); - int idepth = cvRound(d.depth*256); - defects.at(i) = Vec4i(idx0, idx1, idx2, idepth); - } -} - - -bool isContourConvex( InputArray _contour ) -{ - Mat contour = _contour.getMat(); - CV_Assert(contour.checkVector(2) >= 0 && - (contour.depth() == CV_32F || contour.depth() == CV_32S)); - CvMat c = Mat(contour); - return cvCheckContourConvexity(&c) > 0; -} - - void convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool returnPoints ) { Mat points = _points.getMat(); @@ -1106,6 +580,134 @@ void convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool ret } } + +void convexityDefects( InputArray _points, InputArray _hull, OutputArray _defects ) +{ + Mat points = _points.getMat(); + int i, j = 0, index, npoints = points.checkVector(2, CV_32S); + CV_Assert( npoints >= 0 ); + + if( npoints <= 3 ) + { + _defects.release(); + return; + } + + Mat hull = _hull.getMat(); + int hpoints = hull.checkVector(1, CV_32S); + CV_Assert( hpoints > 2 ); + + const Point* ptr = (const Point*)points.data; + const int* hptr = hull.ptr(); + vector defects; + + // 1. recognize co-orientation of the contour and its hull + bool rev_orientation = ((hptr[1] > hptr[0]) + (hptr[2] > hptr[1]) + (hptr[0] > hptr[2])) != 2; + + // 2. cycle through points and hull, compute defects + int hcurr = hptr[rev_orientation ? 0 : hpoints-1]; + CV_Assert( 0 <= hcurr && hcurr < npoints ); + + for( i = 0; i < hpoints; i++ ) + { + int hnext = hptr[rev_orientation ? hpoints - i - 1 : i]; + CV_Assert( 0 <= hnext && hnext < npoints ); + + Point pt0 = ptr[hcurr], pt1 = ptr[hnext]; + double dx0 = pt1.x - pt0.x; + double dy0 = pt1.y - pt0.y; + double scale = dx0 == 0 && dy0 == 0 ? 0. : 1./sqrt(dx0*dx0 + dy0*dy0); + + int defect_deepest_point = -1; + double defect_depth = 0; + bool is_defect = false; + + for(;;) + { + // go through points to achieve next hull point + j++; + j &= j >= npoints ? 0 : -1; + if( j == hnext ) + break; + + // compute distance from current point to hull edge + double dx = ptr[j].x - pt0.x; + double dy = ptr[j].y - pt0.y; + double dist = fabs(-dy0*dx + dx0*dy) * scale; + + if( dist > defect_depth ) + { + defect_depth = dist; + defect_deepest_point = j; + is_defect = true; + } + } + + if( is_defect ) + { + int idepth = cvRound(defect_depth*256); + defects.push_back(Vec4i(hcurr, hnext, defect_deepest_point, idepth)); + } + + hcurr = hnext; + } + + Mat(defects).copyTo(_defects); +} + + +template +static bool isContourConvex_( const Point_<_Tp>* p, int n ) +{ + Point_<_Tp> prev_pt = p[(n-2+n) % n]; + Point_<_Tp> cur_pt = p[n-1]; + + _Tp dx0 = cur_pt.x - prev_pt.x; + _Tp dy0 = cur_pt.y - prev_pt.y; + int orientation = 0; + + for( int i = 0; i < n-1; i++ ) + { + _Tp dxdy0, dydx0; + _Tp dx, dy; + + prev_pt = cur_pt; + cur_pt = p[i]; + + dx = cur_pt.x - prev_pt.x; + dy = cur_pt.y - prev_pt.y; + dxdy0 = dx * dy0; + dydx0 = dy * dx0; + + // find orientation + // orient = -dy0 * dx + dx0 * dy; + // orientation |= (orient > 0) ? 1 : 2; + orientation |= (dydx0 > dxdy0) ? 1 : ((dydx0 < dxdy0) ? 2 : 3); + if( orientation == 3 ) + return false; + + dx0 = dx; + dy0 = dy; + } + + return true; +} + + +bool isContourConvex( InputArray _contour ) +{ + Mat contour = _contour.getMat(); + int total = contour.checkVector(2), depth = contour.depth(); + CV_Assert(total >= 0 && (depth == CV_32F || depth == CV_32S)); + + if( total == 0 ) + return false; + + return depth == CV_32S ? + isContourConvex_((const Point*)contour.data, total ) : + isContourConvex_((const Point2f*)contour.data, total ); +} + } CV_IMPL CvSeq* @@ -1187,12 +789,9 @@ cvConvexHull2( const CvArr* array, void* hull_storage, return hull.s; } - cv::AutoBuffer _ptbuf(total); - cv::Point* ptbuf = _ptbuf; + cv::AutoBuffer _ptbuf; cv::Mat h0; - - cvCvtSeqToArray(ptseq, ptbuf); - cv::convexHull(cv::Mat(total, 1, CV_SEQ_ELTYPE(ptseq), ptbuf), h0, + cv::convexHull(cv::cvarrToMat(ptseq, false, false, 0, &_ptbuf), h0, orientation == CV_CLOCKWISE, CV_MAT_CN(hulltype) == 2); if( hulltype == CV_SEQ_ELTYPE_PPOINT ) @@ -1433,11 +1032,6 @@ CV_IMPL CvSeq* cvConvexityDefects( const CvArr* array, CV_IMPL int cvCheckContourConvexity( const CvArr* array ) { - int flag = -1; - - int i; - int orientation = 0; - CvSeqReader reader; CvContour contour_header; CvSeqBlock block; CvSeq* contour = (CvSeq*)array; @@ -1450,99 +1044,15 @@ cvCheckContourConvexity( const CvArr* array ) } else { - contour = cvPointSeqFromMat(CV_SEQ_KIND_CURVE|CV_SEQ_FLAG_CLOSED, array, &contour_header, &block ); + contour = cvPointSeqFromMat(CV_SEQ_KIND_CURVE| + CV_SEQ_FLAG_CLOSED, array, &contour_header, &block ); } if( contour->total == 0 ) return -1; - cvStartReadSeq( contour, &reader, 0 ); - flag = 1; - - if( CV_SEQ_ELTYPE( contour ) == CV_32SC2 ) - { - CvPoint *prev_pt = (CvPoint*)reader.prev_elem; - CvPoint *cur_pt = (CvPoint*)reader.ptr; - - int dx0 = cur_pt->x - prev_pt->x; - int dy0 = cur_pt->y - prev_pt->y; - - for( i = 0; i < contour->total; i++ ) - { - int dxdy0, dydx0; - int dx, dy; - - /*int orient; */ - CV_NEXT_SEQ_ELEM( sizeof(CvPoint), reader ); - prev_pt = cur_pt; - cur_pt = (CvPoint *) reader.ptr; - - dx = cur_pt->x - prev_pt->x; - dy = cur_pt->y - prev_pt->y; - dxdy0 = dx * dy0; - dydx0 = dy * dx0; - - /* find orientation */ - /* orient = -dy0 * dx + dx0 * dy; - orientation |= (orient > 0) ? 1 : 2; - */ - orientation |= (dydx0 > dxdy0) ? 1 : ((dydx0 < dxdy0) ? 2 : 3); - - if( orientation == 3 ) - { - flag = 0; - break; - } - - dx0 = dx; - dy0 = dy; - } - } - else - { - CV_Assert( CV_SEQ_ELTYPE(contour) == CV_32FC2 ); - - CvPoint2D32f *prev_pt = (CvPoint2D32f*)reader.prev_elem; - CvPoint2D32f *cur_pt = (CvPoint2D32f*)reader.ptr; - - float dx0 = cur_pt->x - prev_pt->x; - float dy0 = cur_pt->y - prev_pt->y; - - for( i = 0; i < contour->total; i++ ) - { - float dxdy0, dydx0; - float dx, dy; - - /*int orient; */ - CV_NEXT_SEQ_ELEM( sizeof(CvPoint2D32f), reader ); - prev_pt = cur_pt; - cur_pt = (CvPoint2D32f*) reader.ptr; - - dx = cur_pt->x - prev_pt->x; - dy = cur_pt->y - prev_pt->y; - dxdy0 = dx * dy0; - dydx0 = dy * dx0; - - /* find orientation */ - /* orient = -dy0 * dx + dx0 * dy; - orientation |= (orient > 0) ? 1 : 2; - */ - orientation |= (dydx0 > dxdy0) ? 1 : ((dydx0 < dxdy0) ? 2 : 3); - - if( orientation == 3 ) - { - flag = 0; - break; - } - - dx0 = dx; - dy0 = dy; - } - } - - return flag; + cv::AutoBuffer _buf; + return cv::isContourConvex(cv::cvarrToMat(contour, false, false, 0, &_buf)) ? 1 : 0; } -#endif - /* End of file. */ diff --git a/modules/video/src/optflowgf.cpp b/modules/video/src/optflowgf.cpp index 0f63bb4..650e242 100644 --- a/modules/video/src/optflowgf.cpp +++ b/modules/video/src/optflowgf.cpp @@ -395,8 +395,8 @@ FarnebackUpdateFlow_GaussianBlur( const Mat& _R0, const Mat& _R1, double sigma = m*0.3, s = 1; AutoBuffer _vsum((width+m*2+2)*5 + 16), _hsum(width*5 + 16); - AutoBuffer _kernel((m+1)*5 + 16); - AutoBuffer _srow(m*2+1); + AutoBuffer _kernel((m+1)*5 + 16); + AutoBuffer _srow(m*2+1); float *vsum = alignPtr((float*)_vsum + (m+1)*5, 16), *hsum = alignPtr((float*)_hsum, 16); float* kernel = (float*)_kernel; const float** srow = (const float**)&_srow[0];