diff --git a/modules/photo/perf/perf_inpaint.cpp b/modules/photo/perf/perf_inpaint.cpp index 4ebf86d582..972770234f 100644 --- a/modules/photo/perf/perf_inpaint.cpp +++ b/modules/photo/perf/perf_inpaint.cpp @@ -6,6 +6,7 @@ namespace opencv_test CV_ENUM(InpaintingMethod, INPAINT_NS, INPAINT_TELEA) typedef tuple InpaintArea_InpaintingMethod_t; typedef perf::TestBaseWithParam InpaintArea_InpaintingMethod; +typedef perf::TestBaseWithParam Perf_InpaintingMethod; PERF_TEST_P(InpaintArea_InpaintingMethod, inpaint, @@ -34,4 +35,26 @@ PERF_TEST_P(InpaintArea_InpaintingMethod, inpaint, SANITY_CHECK(inpaintedArea); } +PERF_TEST_P(Perf_InpaintingMethod, inpaintDots, InpaintingMethod::all()) +{ + Mat src = imread(getDataPath("gpu/hog/road.png")); + + int inpaintingMethod = GetParam(); + + Mat mask(src.size(), CV_8UC1, Scalar(0)); + Mat result(src.size(), src.type()); + + for (int i = 0; i < src.size().height; i += 16) { + for (int j = 0; j < src.size().width; j += 16) { + mask.at(i, j) = 255; + } + } + + declare.in(src, mask).out(result).time(120); + + TEST_CYCLE() inpaint(src, mask, result, 10.0, inpaintingMethod); + + SANITY_CHECK_NOTHING(); +} + } // namespace diff --git a/modules/photo/src/inpaint.cpp b/modules/photo/src/inpaint.cpp index b436168212..05d2d49dca 100644 --- a/modules/photo/src/inpaint.cpp +++ b/modules/photo/src/inpaint.cpp @@ -45,6 +45,8 @@ // // */ +#include + #include "precomp.hpp" #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/photo/legacy/constants_c.h" @@ -71,8 +73,16 @@ typedef struct CvHeapElem { float T; int i,j; - struct CvHeapElem* prev; - struct CvHeapElem* next; + int order; // to keep insertion order + + bool operator > (const CvHeapElem& rhs) const { + if (T > rhs.T) { + return true; + } else if (T < rhs.T) { + return false; + } + return order > rhs.order; + } } CvHeapElem; @@ -84,42 +94,10 @@ private: CvPriorityQueueFloat& operator=(const CvPriorityQueueFloat &); // assign disabled protected: - CvHeapElem *mem,*empty,*head,*tail; - int num,in; + std::priority_queue,std::greater > queue; + int next_order; public: - bool Init( const CvMat* f ) - { - int i,j; - for( i = num = 0; i < f->rows; i++ ) - { - for( j = 0; j < f->cols; j++ ) - num += CV_MAT_ELEM(*f,uchar,i,j)!=0; - } - if (num<=0) return false; - mem = (CvHeapElem*)cvAlloc((num+2)*sizeof(CvHeapElem)); - if (mem==NULL) return false; - - head = mem; - head->i = head->j = -1; - head->prev = NULL; - head->next = mem+1; - head->T = -FLT_MAX; - empty = mem+1; - for (i=1; i<=num; i++) { - mem[i].prev = mem+i-1; - mem[i].next = mem+i+1; - mem[i].i = -1; - mem[i].T = FLT_MAX; - } - tail = mem+i; - tail->i = tail->j = -1; - tail->prev = mem+i-1; - tail->next = NULL; - tail->T = FLT_MAX; - return true; - } - bool Add(const CvMat* f) { int i,j; for (i=0; irows; i++) { @@ -133,71 +111,33 @@ public: } bool Push(int i, int j, float T) { - CvHeapElem *tmp=empty,*add=empty; - if (empty==tail) return false; - while (tmp->prev->T>T) tmp = tmp->prev; - if (tmp!=empty) { - add->prev->next = add->next; - add->next->prev = add->prev; - empty = add->next; - add->prev = tmp->prev; - add->next = tmp; - add->prev->next = add; - add->next->prev = add; - } else { - empty = empty->next; - } - add->i = i; - add->j = j; - add->T = T; - in++; - // printf("push i %3d j %3d T %12.4e in %4d\n",i,j,T,in); + queue.push({T, i, j, next_order}); + ++next_order; return true; } bool Pop(int *i, int *j) { - CvHeapElem *tmp=head->next; - if (empty==tmp) return false; - *i = tmp->i; - *j = tmp->j; - tmp->prev->next = tmp->next; - tmp->next->prev = tmp->prev; - tmp->prev = empty->prev; - tmp->next = empty; - tmp->prev->next = tmp; - tmp->next->prev = tmp; - empty = tmp; - in--; - // printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in); + if (queue.empty()) { + return false; + } + *i = queue.top().i; + *j = queue.top().j; + queue.pop(); return true; } bool Pop(int *i, int *j, float *T) { - CvHeapElem *tmp=head->next; - if (empty==tmp) return false; - *i = tmp->i; - *j = tmp->j; - *T = tmp->T; - tmp->prev->next = tmp->next; - tmp->next->prev = tmp->prev; - tmp->prev = empty->prev; - tmp->next = empty; - tmp->prev->next = tmp; - tmp->next->prev = tmp; - empty = tmp; - in--; - // printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in); + if (queue.empty()) { + return false; + } + *i = queue.top().i; + *j = queue.top().j; + *T = queue.top().T; + queue.pop(); return true; } - CvPriorityQueueFloat(void) { - num=in=0; - mem=empty=head=tail=NULL; - } - - ~CvPriorityQueueFloat(void) - { - cvFree( &mem ); + CvPriorityQueueFloat(void) : queue(), next_order() { } }; @@ -786,8 +726,6 @@ icvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_ cvSet(t,cvScalar(1.0e6f,0,0,0)); cv::dilate(cv::cvarrToMat(mask), cv::cvarrToMat(band), el_cross, cv::Point(1, 1)); Heap=cv::makePtr(); - if (!Heap->Init(band)) - return; cvSub(band,mask,band,NULL); SET_BORDER1_C1(band,uchar,0); if (!Heap->Add(band)) @@ -803,8 +741,6 @@ icvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_ cv::dilate(cv::cvarrToMat(mask), cv::cvarrToMat(out), el_range); cvSub(out,mask,out,NULL); Out=cv::makePtr(); - if (!Out->Init(out)) - return; if (!Out->Add(band)) return; cvSub(out,band,out,NULL);