diff --git a/modules/calib3d/src/chessboard.cpp b/modules/calib3d/src/chessboard.cpp index b4a8d9dd50..5855c3f255 100644 --- a/modules/calib3d/src/chessboard.cpp +++ b/modules/calib3d/src/chessboard.cpp @@ -2169,7 +2169,7 @@ cv::Point2f &Chessboard::Board::getCorner(int _row,int _col) } ++count; row_start = row_start->bottom; - }while(_row); + }while(row_start); } CV_Error(Error::StsInternal,"cannot find corner"); // return *top_left->top_left; // never reached diff --git a/modules/calib3d/src/usac/utils.cpp b/modules/calib3d/src/usac/utils.cpp index 52bc456588..47e78cb559 100644 --- a/modules/calib3d/src/usac/utils.cpp +++ b/modules/calib3d/src/usac/utils.cpp @@ -388,12 +388,12 @@ void Utils::densitySort (const Mat &points, int knn, Mat &sorted_points, std::ve sorted_mask[i] = i; // get neighbors - FlannNeighborhoodGraph &graph = *FlannNeighborhoodGraph::create(points, points_size, knn, + cv::Ptr graph = FlannNeighborhoodGraph::create(points, points_size, knn, true /*get distances */, 6, 1); std::vector sum_knn_distances (points_size, 0); for (int p = 0; p < points_size; p++) { - const std::vector &dists = graph.getNeighborsDistances(p); + const std::vector &dists = graph->getNeighborsDistances(p); for (int k = 0; k < knn; k++) sum_knn_distances[p] += dists[k]; } @@ -789,4 +789,4 @@ Ptr GridNeighborhoodGraph::create(const Mat &points, return makePtr(points, points_size, cell_size_x_img1_, cell_size_y_img1_, cell_size_x_img2_, cell_size_y_img2_, max_neighbors); } -}} \ No newline at end of file +}} diff --git a/modules/calib3d/test/test_fundam.cpp b/modules/calib3d/test/test_fundam.cpp index 2a7af54a12..ab987ffcea 100644 --- a/modules/calib3d/test/test_fundam.cpp +++ b/modules/calib3d/test/test_fundam.cpp @@ -621,9 +621,9 @@ void CV_RodriguesTest::get_test_array_types_and_sizes( } -double CV_RodriguesTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int j ) +double CV_RodriguesTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) { - return j == 4 ? 1e-2 : 1e-2; + return 1e-2; } diff --git a/modules/imgcodecs/src/grfmt_exr.cpp b/modules/imgcodecs/src/grfmt_exr.cpp index f1d4126e16..1a5d7397d9 100644 --- a/modules/imgcodecs/src/grfmt_exr.cpp +++ b/modules/imgcodecs/src/grfmt_exr.cpp @@ -151,9 +151,6 @@ bool ExrDecoder::readHeader() m_file = new InputFile( m_filename.c_str() ); - if( !m_file ) // probably paranoid - return false; - m_datawindow = m_file->header().dataWindow(); m_width = m_datawindow.max.x - m_datawindow.min.x + 1; m_height = m_datawindow.max.y - m_datawindow.min.y + 1; diff --git a/modules/imgproc/src/approx.cpp b/modules/imgproc/src/approx.cpp index 433ca669d5..14a6c743e9 100644 --- a/modules/imgproc/src/approx.cpp +++ b/modules/imgproc/src/approx.cpp @@ -793,16 +793,13 @@ cvApproxPoly( const void* array, int header_size, { CvSeq *contour = 0; - switch (method) + if( parameter < 0 ) + CV_Error( cv::Error::StsOutOfRange, "Accuracy must be non-negative" ); + + CV_Assert( CV_SEQ_ELTYPE(src_seq) == CV_32SC2 || + CV_SEQ_ELTYPE(src_seq) == CV_32FC2 ); + { - case CV_POLY_APPROX_DP: - if( parameter < 0 ) - CV_Error( cv::Error::StsOutOfRange, "Accuracy must be non-negative" ); - - CV_Assert( CV_SEQ_ELTYPE(src_seq) == CV_32SC2 || - CV_SEQ_ELTYPE(src_seq) == CV_32FC2 ); - - { int npoints = src_seq->total, nout = 0; _buf.allocate(npoints*2); cv::Point *src = _buf.data(), *dst = src + npoints; @@ -817,17 +814,13 @@ cvApproxPoly( const void* array, int header_size, nout = cv::approxPolyDP_(src, npoints, dst, closed, parameter, stack); else if( CV_SEQ_ELTYPE(src_seq) == CV_32FC2 ) nout = cv::approxPolyDP_((cv::Point2f*)src, npoints, - (cv::Point2f*)dst, closed, parameter, stack); + (cv::Point2f*)dst, closed, parameter, stack); else CV_Error( cv::Error::StsUnsupportedFormat, "" ); contour = cvCreateSeq( src_seq->flags, header_size, - src_seq->elem_size, storage ); + src_seq->elem_size, storage ); cvSeqPushMulti(contour, dst, nout); - } - break; - default: - CV_Error( cv::Error::StsBadArg, "Invalid approximation method" ); } CV_Assert( contour ); diff --git a/modules/imgproc/test/test_filter.cpp b/modules/imgproc/test/test_filter.cpp index 46164aed21..2920b71e8a 100644 --- a/modules/imgproc/test/test_filter.cpp +++ b/modules/imgproc/test/test_filter.cpp @@ -1374,7 +1374,7 @@ test_cornerEigenValsVecs( const Mat& src, Mat& eigenv, Mat& ocv_eigenv, int block_size, int _aperture_size, int mode ) { int i, j; - int aperture_size = _aperture_size < 0 ? 3 : _aperture_size; + int aperture_size = _aperture_size <= 0 ? 3 : _aperture_size; Point anchor( aperture_size/2, aperture_size/2 ); CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 ); diff --git a/modules/imgproc/test/test_goodfeaturetotrack.cpp b/modules/imgproc/test/test_goodfeaturetotrack.cpp index d6204c0404..38e9a4bd5f 100644 --- a/modules/imgproc/test/test_goodfeaturetotrack.cpp +++ b/modules/imgproc/test/test_goodfeaturetotrack.cpp @@ -509,7 +509,8 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx ) EXPECT_LE(e, eps); // never true ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); - for(int i = 0; i < (int)std::min((unsigned int)(cornersQuality.size()), (unsigned int)(cornersQuality.size())); i++) { + int min_size = (int)std::min(cornersQuality.size(), RefcornersQuality.size()); + for(int i = 0; i < min_size; i++) { if (std::abs(cornersQuality[i] - RefcornersQuality[i]) > eps * std::max(cornersQuality[i], RefcornersQuality[i])) printf("i = %i Quality %2.6f Quality ref %2.6f\n", i, cornersQuality[i], RefcornersQuality[i]); } diff --git a/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.cpp b/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.cpp index 96b7fe517e..41e6852609 100644 --- a/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.cpp +++ b/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.cpp @@ -18,6 +18,7 @@ #include "../../precomp.hpp" #include "apriltag_quad_thresh.hpp" +#include "unionfind.hpp" //#define APRIL_DEBUG #ifdef APRIL_DEBUG @@ -93,7 +94,7 @@ void ptsort_(struct pt *pts, int sz) // a merge sort with temp storage. // Use stack storage if it's not too big. - cv::AutoBuffer _tmp_stack(sz); + AutoBuffer _tmp_stack(sz); memcpy(_tmp_stack.data(), pts, sizeof(struct pt) * sz); int asz = sz/2; @@ -571,31 +572,6 @@ int quad_segment_agg(int sz, struct line_fit_pt *lfps, int indices[4]){ return 1; } -#define DO_UNIONFIND(dx, dy) if (im.data[y*s + dy*s + x + dx] == v) unionfind_connect(uf, y*w + x, y*w + dy*w + x + dx); -static void do_unionfind_line(unionfind_t *uf, Mat &im, int w, int s, int y){ - CV_Assert(y+1 < im.rows); - CV_Assert(!im.empty()); - - for (int x = 1; x < w - 1; x++) { - uint8_t v = im.data[y*s + x]; - - if (v == 127) - continue; - - // (dx,dy) pairs for 8 connectivity: - // (REFERENCE) (1, 0) - // (-1, 1) (0, 1) (1, 1) - // - DO_UNIONFIND(1, 0); - DO_UNIONFIND(0, 1); - if (v == 255) { - DO_UNIONFIND(-1, 1); - DO_UNIONFIND(1, 1); - } - } -} -#undef DO_UNIONFIND - /** * return 1 if the quad looks okay, 0 if it should be discarded * quad @@ -1309,11 +1285,11 @@ zarray_t *apriltag_quad_thresh(const DetectorParameters ¶meters, const Mat & //////////////////////////////////////////////////////// // step 2. find connected components. - unionfind_t *uf = unionfind_create(w * h); + UnionFind uf(w * h); // TODO PARALLELIZE for (int y = 0; y < h - 1; y++) { - do_unionfind_line(uf, thold, w, ts, y); + uf.do_line(thold, w, ts, y); } // XXX sizing?? @@ -1329,7 +1305,7 @@ zarray_t *apriltag_quad_thresh(const DetectorParameters ¶meters, const Mat & continue; // XXX don't query this until we know we need it? - uint64_t rep0 = unionfind_get_representative(uf, y*w + x); + uint64_t rep0 = uf.get_representative(y*w + x); // whenever we find two adjacent pixels such that one is // white and the other black, we add the point half-way @@ -1356,7 +1332,7 @@ zarray_t *apriltag_quad_thresh(const DetectorParameters ¶meters, const Mat & uint8_t v1 = thold.data[y*ts + dy*ts + x + dx]; \ \ if (v0 + v1 == 255) { \ - uint64_t rep1 = unionfind_get_representative(uf, y*w + dy*w + x + dx); \ + uint64_t rep1 = uf.get_representative(y*w + dy*w + x + dx); \ uint64_t clusterid; \ if (rep0 < rep1) \ clusterid = (rep1 << 32) + rep0; \ @@ -1405,9 +1381,9 @@ uint32_t *colors = (uint32_t*) calloc(w*h, sizeof(*colors)); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { - uint32_t v = unionfind_get_representative(uf, y*w+x); + uint32_t v = uf.get_representative(y*w+x); - if (unionfind_get_set_size(uf, v) < parameters->aprilTagMinClusterPixels) + if (uf.get_set_size(v) < parameters->aprilTagMinClusterPixels) continue; uint32_t color = colors[v]; @@ -1533,8 +1509,6 @@ for (int i = 0; i < _zarray_size(quads); i++) { imwrite("2.5 debug_lines.pnm", out); #endif - unionfind_destroy(uf); - for (int i = 0; i < _zarray_size(clusters); i++) { zarray_t *cluster; _zarray_get(clusters, i, &cluster); diff --git a/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.hpp b/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.hpp index bc1334a12d..aede1bbe0e 100644 --- a/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.hpp +++ b/modules/objdetect/src/aruco/apriltag/apriltag_quad_thresh.hpp @@ -19,7 +19,6 @@ #ifndef _OPENCV_APRIL_QUAD_THRESH_HPP_ #define _OPENCV_APRIL_QUAD_THRESH_HPP_ -#include "unionfind.hpp" #include "zmaxheap.hpp" #include "zarray.hpp" diff --git a/modules/objdetect/src/aruco/apriltag/unionfind.hpp b/modules/objdetect/src/aruco/apriltag/unionfind.hpp index 6ecc58a407..f7a2d6a55c 100644 --- a/modules/objdetect/src/aruco/apriltag/unionfind.hpp +++ b/modules/objdetect/src/aruco/apriltag/unionfind.hpp @@ -17,115 +17,115 @@ namespace cv { namespace aruco { -typedef struct unionfind unionfind_t; -struct unionfind{ +struct UnionFind { + UnionFind(uint32_t _maxid) + { + maxid = _maxid; + data.resize(maxid+1); + for (unsigned int i = 0; i <= maxid; i++) { + data[i].size = 1; + data[i].parent = i; + } + }; + + inline uint32_t get_representative(uint32_t id) { + uint32_t root = id; + + // chase down the root + while (data[root].parent != root) { + root = data[root].parent; + } + + // go back and collapse the tree. + // + // XXX: on some of our workloads that have very shallow trees + // (e.g. image segmentation), we are actually faster not doing + // this... + while (data[id].parent != root) { + uint32_t tmp = data[id].parent; + data[id].parent = root; + id = tmp; + } + + return root; + } + + inline uint32_t get_set_size(uint32_t id) { + uint32_t repid = get_representative(id); + return data[repid].size; + } + + inline uint32_t connect(uint32_t aid, uint32_t bid) { + uint32_t aroot = get_representative(aid); + uint32_t broot = get_representative(bid); + + if (aroot == broot) + return aroot; + + // we don't perform "union by rank", but we perform a similar + // operation (but probably without the same asymptotic guarantee): + // We join trees based on the number of *elements* (as opposed to + // rank) contained within each tree. I.e., we use size as a proxy + // for rank. In my testing, it's often *faster* to use size than + // rank, perhaps because the rank of the tree isn't that critical + // if there are very few nodes in it. + uint32_t asize = data[aroot].size; + uint32_t bsize = data[broot].size; + + // optimization idea: We could shortcut some or all of the tree + // that is grafted onto the other tree. Pro: those nodes were just + // read and so are probably in cache. Con: it might end up being + // wasted effort -- the tree might be grafted onto another tree in + // a moment! + if (asize > bsize) { + data[broot].parent = aroot; + data[aroot].size += bsize; + return aroot; + } else { + data[aroot].parent = broot; + data[broot].size += asize; + return broot; + } + } + + #define DO_UNIONFIND(dx, dy) if (im.data[y*s + dy*s + x + dx] == v) connect(y*w + x, y*w + dy*w + x + dx); + void do_line(Mat &im, int w, int s, int y) { + CV_Assert(y+1 < im.rows); + CV_Assert(!im.empty()); + + for (int x = 1; x < w - 1; x++) { + uint8_t v = im.data[y*s + x]; + + if (v == 127) + continue; + + // (dx,dy) pairs for 8 connectivity: + // (REFERENCE) (1, 0) + // (-1, 1) (0, 1) (1, 1) + // + DO_UNIONFIND(1, 0); + DO_UNIONFIND(0, 1); + if (v == 255) { + DO_UNIONFIND(-1, 1); + DO_UNIONFIND(1, 1); + } + } + } + #undef DO_UNIONFIND + + struct ufrec { + // the parent of this node. If a node's parent is its own index, + // then it is a root. + uint32_t parent; + + // for the root of a connected component, the number of components + // connected to it. For intermediate values, it's not meaningful. + uint32_t size; + }; + uint32_t maxid; - struct ufrec *data; + std::vector data; }; -struct ufrec{ - // the parent of this node. If a node's parent is its own index, - // then it is a root. - uint32_t parent; - - // for the root of a connected component, the number of components - // connected to it. For intermediate values, it's not meaningful. - uint32_t size; -}; - -static inline unionfind_t *unionfind_create(uint32_t maxid){ - unionfind_t *uf = (unionfind_t*) calloc(1, sizeof(unionfind_t)); - uf->maxid = maxid; - uf->data = (struct ufrec*) malloc((maxid+1) * sizeof(struct ufrec)); - for (unsigned int i = 0; i <= maxid; i++) { - uf->data[i].size = 1; - uf->data[i].parent = i; - } - return uf; -} - -static inline void unionfind_destroy(unionfind_t *uf){ - free(uf->data); - free(uf); -} - -/* -static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id) -{ - // base case: a node is its own parent - if (uf->data[id].parent == id) - return id; - - // otherwise, recurse - uint32_t root = unionfind_get_representative(uf, uf->data[id].parent); - - // short circuit the path. [XXX This write prevents tail recursion] - uf->data[id].parent = root; - - return root; -} - */ - -// this one seems to be every-so-slightly faster than the recursive -// version above. -static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id){ - uint32_t root = id; - - // chase down the root - while (uf->data[root].parent != root) { - root = uf->data[root].parent; - } - - // go back and collapse the tree. - // - // XXX: on some of our workloads that have very shallow trees - // (e.g. image segmentation), we are actually faster not doing - // this... - while (uf->data[id].parent != root) { - uint32_t tmp = uf->data[id].parent; - uf->data[id].parent = root; - id = tmp; - } - - return root; -} - -static inline uint32_t unionfind_get_set_size(unionfind_t *uf, uint32_t id){ - uint32_t repid = unionfind_get_representative(uf, id); - return uf->data[repid].size; -} - -static inline uint32_t unionfind_connect(unionfind_t *uf, uint32_t aid, uint32_t bid){ - uint32_t aroot = unionfind_get_representative(uf, aid); - uint32_t broot = unionfind_get_representative(uf, bid); - - if (aroot == broot) - return aroot; - - // we don't perform "union by rank", but we perform a similar - // operation (but probably without the same asymptotic guarantee): - // We join trees based on the number of *elements* (as opposed to - // rank) contained within each tree. I.e., we use size as a proxy - // for rank. In my testing, it's often *faster* to use size than - // rank, perhaps because the rank of the tree isn't that critical - // if there are very few nodes in it. - uint32_t asize = uf->data[aroot].size; - uint32_t bsize = uf->data[broot].size; - - // optimization idea: We could shortcut some or all of the tree - // that is grafted onto the other tree. Pro: those nodes were just - // read and so are probably in cache. Con: it might end up being - // wasted effort -- the tree might be grafted onto another tree in - // a moment! - if (asize > bsize) { - uf->data[broot].parent = aroot; - uf->data[aroot].size += bsize; - return aroot; - } else { - uf->data[aroot].parent = broot; - uf->data[broot].size += asize; - return broot; - } -} }} #endif diff --git a/modules/objdetect/src/aruco/apriltag/zmaxheap.cpp b/modules/objdetect/src/aruco/apriltag/zmaxheap.cpp index 5b0ac85dcb..5e7ca49063 100644 --- a/modules/objdetect/src/aruco/apriltag/zmaxheap.cpp +++ b/modules/objdetect/src/aruco/apriltag/zmaxheap.cpp @@ -84,7 +84,6 @@ void zmaxheap_destroy(zmaxheap_t *heap) { free(heap->values); free(heap->data); - memset(heap, 0, sizeof(zmaxheap_t)); free(heap); } diff --git a/modules/objdetect/src/precomp.hpp b/modules/objdetect/src/precomp.hpp index 63ca440076..82ecec2751 100644 --- a/modules/objdetect/src/precomp.hpp +++ b/modules/objdetect/src/precomp.hpp @@ -43,6 +43,7 @@ #ifndef __OPENCV_PRECOMP_H__ #define __OPENCV_PRECOMP_H__ +#include "opencv2/core.hpp" #include "opencv2/objdetect.hpp" #include "opencv2/objdetect/barcode.hpp" #include "opencv2/imgproc.hpp" diff --git a/modules/ts/src/ocl_test.cpp b/modules/ts/src/ocl_test.cpp index 07fb1cdc4a..cc584a7390 100644 --- a/modules/ts/src/ocl_test.cpp +++ b/modules/ts/src/ocl_test.cpp @@ -104,7 +104,6 @@ double TestUtils::checkRectSimilarity(const Size & sz, std::vector& ob1, s { cv::Mat cpu_result_roi(cpu_result, *r); cpu_result_roi.setTo(1); - cpu_result.copyTo(cpu_result); } int cpu_area = cv::countNonZero(cpu_result > 0); @@ -114,7 +113,6 @@ double TestUtils::checkRectSimilarity(const Size & sz, std::vector& ob1, s { cv::Mat gpu_result_roi(gpu_result, *r2); gpu_result_roi.setTo(1); - gpu_result.copyTo(gpu_result); } cv::Mat result_;