Skip to content

Commit 68492c4

Browse files
committed
Merge branch 4.x
2 parents 5af8624 + 9163f86 commit 68492c4

File tree

278 files changed

+38652
-1638
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

278 files changed

+38652
-1638
lines changed

modules/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ $ cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules -D BUILD_opencv_<r
4242

4343
- **julia**: Julia language wrappers with samples and tests.
4444

45-
- **line_descriptor**: Line Segment Extract and Match -- Methods of extracting, describing and latching line segments using binary descriptors.
45+
- **line_descriptor**: Line Segment Extract and Match -- Methods of extracting, describing and matching line segments using binary descriptors.
4646

4747
- **matlab**: Matlab Interface -- OpenCV Matlab Mex wrapper code generator for certain opencv core modules.
4848

modules/alphamat/src/cm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void lle(my_vector_of_vectors_t& indm, my_vector_of_vectors_t& samples, float ep
9090
Mat ptDotN(20, 1, DataType<float>::type), imd(20, 1, DataType<float>::type);
9191
Mat Cones(20, 1, DataType<float>::type), Cinv(20, 1, DataType<float>::type);
9292
float alpha, beta, lagrangeMult;
93-
Cones += 1;
93+
Cones = 1;
9494

9595
C = 0;
9696
rhs = 1;

modules/aruco/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
set(the_description "ArUco Marker Detection")
2-
ocv_define_module(aruco opencv_core opencv_imgproc opencv_3d opencv_calib WRAP python java objc)
2+
ocv_define_module(aruco opencv_core opencv_imgproc opencv_3d opencv_calib WRAP python java objc js)

modules/aruco/src/aruco.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -308,34 +308,36 @@ static void _filterTooCloseCandidates(const vector< vector< Point2f > > &candida
308308
vector< vector< Point > > smallerContours;
309309

310310
// save possible candidates
311-
for( unsigned int i = 0; i < groupedCandidates.size(); i++ ) {
312-
int smallerIdx = groupedCandidates[i][0];
313-
int biggerIdx = -1;
311+
for(unsigned int i = 0; i < groupedCandidates.size(); i++) {
312+
unsigned int smallerIdx = groupedCandidates[i][0];
313+
unsigned int biggerIdx = smallerIdx;
314+
double smallerArea = contourArea(candidatesIn[smallerIdx]);
315+
double biggerArea = smallerArea;
314316

315317
// evaluate group elements
316-
for( unsigned int j = 1; j < groupedCandidates[i].size(); j++ ) {
317-
size_t currPerim = contoursIn[ groupedCandidates[i][j] ].size();
318+
for(unsigned int j = 1; j < groupedCandidates[i].size(); j++) {
319+
unsigned int currIdx = groupedCandidates[i][j];
320+
double currArea = contourArea(candidatesIn[currIdx]);
318321

319322
// check if current contour is bigger
320-
if ( biggerIdx < 0 )
321-
biggerIdx = groupedCandidates[i][j];
322-
else if(currPerim >= contoursIn[ biggerIdx ].size())
323-
biggerIdx = groupedCandidates[i][j];
323+
if(currArea >= biggerArea) {
324+
biggerIdx = currIdx;
325+
biggerArea = currArea;
326+
}
324327

325328
// check if current contour is smaller
326-
if(currPerim < contoursIn[ smallerIdx ].size() && detectInvertedMarker)
327-
smallerIdx = groupedCandidates[i][j];
329+
if(currArea < smallerArea && detectInvertedMarker) {
330+
smallerIdx = currIdx;
331+
smallerArea = currArea;
332+
}
328333
}
329-
// add contours und candidates
330-
if(biggerIdx > -1){
331334

332-
biggerCandidates.push_back(candidatesIn[biggerIdx]);
333-
biggerContours.push_back(contoursIn[biggerIdx]);
334-
335-
if( detectInvertedMarker ){
336-
smallerCandidates.push_back(alignContourOrder(candidatesIn[biggerIdx][0], candidatesIn[smallerIdx]));
337-
smallerContours.push_back(contoursIn[smallerIdx]);
338-
}
335+
// add contours and candidates
336+
biggerCandidates.push_back(candidatesIn[biggerIdx]);
337+
biggerContours.push_back(contoursIn[biggerIdx]);
338+
if(detectInvertedMarker) {
339+
smallerCandidates.push_back(alignContourOrder(candidatesIn[biggerIdx][0], candidatesIn[smallerIdx]));
340+
smallerContours.push_back(contoursIn[smallerIdx]);
339341
}
340342
}
341343
// to preserve the structure :: candidateSet< defaultCandidates, whiteCandidates >
@@ -564,7 +566,7 @@ static uint8_t _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArr
564566
Mat onlyBits =
565567
candidateBits.rowRange(params->markerBorderBits,
566568
candidateBits.rows - params->markerBorderBits)
567-
.colRange(params->markerBorderBits, candidateBits.rows - params->markerBorderBits);
569+
.colRange(params->markerBorderBits, candidateBits.cols - params->markerBorderBits);
568570

569571
// try to indentify the marker
570572
if(!dictionary->identify(onlyBits, idx, rotation, params->errorCorrectionRate))
@@ -806,6 +808,7 @@ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Poi
806808

807809
// saves extra group into corresponding
808810
if( !cntPts[4].empty() ){
811+
CV_CheckLT(group, 4, "FIXIT: avoiding infinite loop: implementation should be revised: https://github.com/opencv/opencv_contrib/issues/2738");
809812
for( unsigned int i=0; i < cntPts[4].size() ; i++ )
810813
cntPts[group].push_back(cntPts[4].at(i));
811814
cntPts[4].clear();

modules/aruco/src/charuco.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ static int _selectAndRefineChessboardCorners(InputArray _allCorners, InputArray
305305
if(_image.type() == CV_8UC3)
306306
cvtColor(_image, grey, COLOR_BGR2GRAY);
307307
else
308-
_image.copyTo(grey);
308+
grey = _image.getMat();
309309

310310
const Ptr<DetectorParameters> params = DetectorParameters::create(); // use default params for corner refinement
311311

@@ -725,7 +725,7 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
725725
if(_image.type() == CV_8UC3)
726726
cvtColor(_image, grey, COLOR_BGR2GRAY);
727727
else
728-
_image.copyTo(grey);
728+
grey = _image.getMat();
729729

730730
// for each of the detected markers, try to find a diamond
731731
for(unsigned int i = 0; i < _markerIds.total(); i++) {

modules/ccalib/src/omnidir.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ void cv::omnidir::undistortPoints( InputArray distorted, OutputArray undistorted
331331
Vec3d Xs = Xw / cv::norm(Xw);
332332

333333
// reproject to camera plane
334-
Vec3d ppu = Vec3d(Xs[0]/(Xs[2]+_xi), Xs[1]/(Xs[2]+_xi), 1.0);
334+
Vec3d ppu = Vec3d(Xs[0]/Xs[2], Xs[1]/Xs[2], 1.0);
335335
if (undistorted.depth() == CV_32F)
336336
{
337337
dstf[i] = Vec2f((float)ppu[0], (float)ppu[1]);
@@ -2223,7 +2223,7 @@ void cv::omnidir::stereoRectify(InputArray R, InputArray T, OutputArray R1, Outp
22232223
e1.copyTo(_R1.row(0));
22242224
e2.copyTo(_R1.row(1));
22252225
e3.copyTo(_R1.row(2));
2226-
_R2 = R21 * _R1;
2226+
_R2 = _R1 * R21;
22272227

22282228
}
22292229

modules/cudaarithm/include/opencv2/cudaarithm.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,31 @@ threshold types are not supported.
358358
*/
359359
CV_EXPORTS_W double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type, Stream& stream = Stream::Null());
360360

361+
/** @brief Checks if array elements lie between two scalars.
362+
363+
The function checks the range as follows:
364+
- For every element of a single-channel input array:
365+
\f[\texttt{dst} (I)= \texttt{lowerb}_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb}_0\f]
366+
- For two-channel arrays:
367+
\f[\texttt{dst} (I)= \texttt{lowerb}_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb}_0 \land \texttt{lowerb}_1 \leq \texttt{src} (I)_1 \leq \texttt{upperb}_1\f]
368+
- and so forth.
369+
370+
That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the
371+
specified 1D, 2D, 3D, ... box and 0 otherwise.
372+
373+
Note that unlike the CPU inRange, this does NOT accept an array for lowerb or
374+
upperb, only a cv::Scalar.
375+
376+
@param src first input array.
377+
@param lowerb inclusive lower boundary cv::Scalar.
378+
@param upperb inclusive upper boundary cv::Scalar.
379+
@param dst output array of the same size as src and CV_8U type.
380+
@param stream Stream for the asynchronous version.
381+
382+
@sa cv::inRange
383+
*/
384+
CV_EXPORTS_W void inRange(InputArray src, const Scalar& lowerb, const Scalar& upperb, OutputArray dst, Stream& stream = Stream::Null());
385+
361386
/** @brief Computes magnitudes of complex matrix elements.
362387
363388
@param xy Source complex matrix in the interleaved format ( CV_32FC2 ).

modules/cudaarithm/misc/python/test/test_cudaarithm.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,5 +174,24 @@ def test_convolution(self):
174174
self.assertTrue(np.allclose(cuMatDst.download(),
175175
cv.filter2D(npMat,-1,kernel,anchor=(-1,-1))[iS[0]:iE[0]+1,iS[1]:iE[1]+1]))
176176

177+
def test_inrange(self):
178+
npMat = (np.random.random((128, 128, 3)) * 255).astype(np.float32)
179+
180+
bound1 = np.random.random((4,)) * 255
181+
bound2 = np.random.random((4,)) * 255
182+
lowerb = np.minimum(bound1, bound2).tolist()
183+
upperb = np.maximum(bound1, bound2).tolist()
184+
185+
cuMat = cv.cuda_GpuMat()
186+
cuMat.upload(npMat)
187+
188+
self.assertTrue((cv.cuda.inRange(cuMat, lowerb, upperb).download() ==
189+
cv.inRange(npMat, np.array(lowerb), np.array(upperb))).all())
190+
191+
cuMatDst = cv.cuda_GpuMat(cuMat.size(), cv.CV_8UC1)
192+
cv.cuda.inRange(cuMat, lowerb, upperb, cuMatDst)
193+
self.assertTrue((cuMatDst.download() ==
194+
cv.inRange(npMat, np.array(lowerb), np.array(upperb))).all())
195+
177196
if __name__ == '__main__':
178-
NewOpenCVTests.bootstrap()
197+
NewOpenCVTests.bootstrap()

modules/cudaarithm/perf/perf_element_operations.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,4 +1501,41 @@ PERF_TEST_P(Sz_Depth_Op, Threshold,
15011501
}
15021502
}
15031503

1504+
//////////////////////////////////////////////////////////////////////
1505+
// InRange
1506+
1507+
PERF_TEST_P(Sz_Depth_Cn, InRange,
1508+
Combine(CUDA_TYPICAL_MAT_SIZES,
1509+
Values(CV_8U, CV_16U, CV_32F, CV_64F),
1510+
CUDA_CHANNELS_1_3_4))
1511+
{
1512+
const cv::Size size = GET_PARAM(0);
1513+
const int depth = GET_PARAM(1);
1514+
const int channels = GET_PARAM(2);
1515+
1516+
cv::Mat src(size, CV_MAKE_TYPE(depth, channels));
1517+
declare.in(src, WARMUP_RNG);
1518+
1519+
const cv::Scalar lowerb(10, 50, 100);
1520+
const cv::Scalar upperb(70, 85, 200);
1521+
1522+
if (PERF_RUN_CUDA())
1523+
{
1524+
const cv::cuda::GpuMat d_src(src);
1525+
cv::cuda::GpuMat dst;
1526+
1527+
TEST_CYCLE() cv::cuda::inRange(d_src, lowerb, upperb, dst);
1528+
1529+
CUDA_SANITY_CHECK(dst, 0);
1530+
}
1531+
else
1532+
{
1533+
cv::Mat dst;
1534+
1535+
TEST_CYCLE() cv::inRange(src, lowerb, upperb, dst);
1536+
1537+
CPU_SANITY_CHECK(dst);
1538+
}
1539+
}
1540+
15041541
}} // namespace

modules/cudaarithm/src/core.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ void cv::cuda::flip(InputArray _src, OutputArray _dst, int flipCode, Stream& str
163163

164164
_dst.create(src.size(), src.type());
165165
GpuMat dst = getOutputMat(_dst, src.size(), src.type(), stream);
166-
bool isInplace = (src.data == dst.data) || (src.refcount == dst.refcount);
166+
bool isInplace = (src.data == dst.data);
167167
bool isSizeOdd = (src.cols & 1) == 1 || (src.rows & 1) == 1;
168168
if (isInplace && isSizeOdd)
169169
CV_Error(Error::BadROISize, "In-place version of flip only accepts even width/height");
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
5+
#include "opencv2/opencv_modules.hpp"
6+
7+
#ifndef HAVE_OPENCV_CUDEV
8+
9+
#error "opencv_cudev is required"
10+
11+
#else
12+
13+
#include "opencv2/core/private.cuda.hpp"
14+
#include "opencv2/cudaarithm.hpp"
15+
#include "opencv2/cudev.hpp"
16+
17+
using namespace cv;
18+
using namespace cv::cuda;
19+
using namespace cv::cudev;
20+
21+
namespace {
22+
23+
template <typename T, int cn>
24+
void inRangeImpl(const GpuMat& src,
25+
const Scalar& lowerb,
26+
const Scalar& upperb,
27+
GpuMat& dst,
28+
Stream& stream) {
29+
gridTransformUnary(globPtr<typename MakeVec<T, cn>::type>(src),
30+
globPtr<uchar>(dst),
31+
InRangeFunc<T, cn>(lowerb, upperb),
32+
stream);
33+
}
34+
35+
} // namespace
36+
37+
void cv::cuda::inRange(InputArray _src,
38+
const Scalar& _lowerb,
39+
const Scalar& _upperb,
40+
OutputArray _dst,
41+
Stream& stream) {
42+
const GpuMat src = getInputMat(_src, stream);
43+
44+
typedef void (*func_t)(const GpuMat& src,
45+
const Scalar& lowerb,
46+
const Scalar& upperb,
47+
GpuMat& dst,
48+
Stream& stream);
49+
50+
// Note: We cannot support 16F with the current implementation because we
51+
// use a CUDA vector (e.g. int3) to store the bounds, and there is no CUDA
52+
// vector type for float16
53+
static constexpr const int MAX_CHANNELS = 4;
54+
static constexpr const int NUM_DEPTHS = CV_64F + 1;
55+
56+
static const std::array<std::array<func_t, NUM_DEPTHS>, MAX_CHANNELS>
57+
funcs = {std::array<func_t, NUM_DEPTHS>{inRangeImpl<uchar, 1>,
58+
inRangeImpl<schar, 1>,
59+
inRangeImpl<ushort, 1>,
60+
inRangeImpl<short, 1>,
61+
inRangeImpl<int, 1>,
62+
inRangeImpl<float, 1>,
63+
inRangeImpl<double, 1>},
64+
std::array<func_t, NUM_DEPTHS>{inRangeImpl<uchar, 2>,
65+
inRangeImpl<schar, 2>,
66+
inRangeImpl<ushort, 2>,
67+
inRangeImpl<short, 2>,
68+
inRangeImpl<int, 2>,
69+
inRangeImpl<float, 2>,
70+
inRangeImpl<double, 2>},
71+
std::array<func_t, NUM_DEPTHS>{inRangeImpl<uchar, 3>,
72+
inRangeImpl<schar, 3>,
73+
inRangeImpl<ushort, 3>,
74+
inRangeImpl<short, 3>,
75+
inRangeImpl<int, 3>,
76+
inRangeImpl<float, 3>,
77+
inRangeImpl<double, 3>},
78+
std::array<func_t, NUM_DEPTHS>{inRangeImpl<uchar, 4>,
79+
inRangeImpl<schar, 4>,
80+
inRangeImpl<ushort, 4>,
81+
inRangeImpl<short, 4>,
82+
inRangeImpl<int, 4>,
83+
inRangeImpl<float, 4>,
84+
inRangeImpl<double, 4>}};
85+
86+
CV_CheckLE(src.channels(), MAX_CHANNELS, "Src must have <= 4 channels");
87+
CV_CheckLE(src.depth(),
88+
CV_64F,
89+
"Src must have depth 8U, 8S, 16U, 16S, 32S, 32F, or 64F");
90+
91+
GpuMat dst = getOutputMat(_dst, src.size(), CV_8UC1, stream);
92+
93+
const func_t func = funcs.at(src.channels() - 1).at(src.depth());
94+
func(src, _lowerb, _upperb, dst, stream);
95+
96+
syncOutput(dst, _dst, stream);
97+
}
98+
99+
#endif

modules/cudaarithm/src/element_operations.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ void cv::cuda::addWeighted(InputArray, double, InputArray, double, double, Outpu
7777

7878
double cv::cuda::threshold(InputArray, OutputArray, double, double, int, Stream&) {throw_no_cuda(); return 0.0;}
7979

80+
void cv::cuda::inRange(InputArray, const Scalar&, const Scalar&, OutputArray, Stream&) { throw_no_cuda(); }
81+
8082
void cv::cuda::magnitude(InputArray, OutputArray, Stream&) { throw_no_cuda(); }
8183
void cv::cuda::magnitude(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); }
8284
void cv::cuda::magnitudeSqr(InputArray, OutputArray, Stream&) { throw_no_cuda(); }

0 commit comments

Comments
 (0)