Skip to content

Commit 8ae597d

Browse files
committed
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
2 parents 934ce3b + b32180b commit 8ae597d

File tree

4 files changed

+70
-183
lines changed

4 files changed

+70
-183
lines changed

modules/bgsegm/samples/bgfg.cpp

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ using namespace cv;
88
using namespace cv::bgsegm;
99

1010
const String about =
11-
"\nA program demonstrating the use and capabilities of different background subtraction algrorithms\n"
11+
"\nA program demonstrating the use and capabilities of different background subtraction algorithms\n"
1212
"Using OpenCV version " + String(CV_VERSION) +
13-
"\nPress q or ESC to exit\n";
13+
"\n\nPress 'c' to change the algorithm"
14+
"\nPress 'm' to toggle showing only foreground mask or ghost effect"
15+
"\nPress 'n' to change number of threads"
16+
"\nPress SPACE to toggle wait delay of imshow"
17+
"\nPress 'q' or ESC to exit\n";
1418

15-
const String keys =
16-
"{help h usage ? | | print this message }"
17-
"{vid | | path to a video file }"
18-
"{algo | GMG | name of the algorithm (GMG, CNT, KNN, MOG, MOG2) }"
19-
;
19+
const String algos[7] = { "GMG", "CNT", "KNN", "MOG", "MOG2", "GSOC", "LSBP" };
2020

2121
static Ptr<BackgroundSubtractor> createBGSubtractorByName(const String& algoName)
2222
{
@@ -31,42 +31,26 @@ static Ptr<BackgroundSubtractor> createBGSubtractorByName(const String& algoName
3131
algo = createBackgroundSubtractorMOG();
3232
else if(algoName == String("MOG2"))
3333
algo = createBackgroundSubtractorMOG2();
34+
else if(algoName == String("GSOC"))
35+
algo = createBackgroundSubtractorGSOC();
36+
else if(algoName == String("LSBP"))
37+
algo = createBackgroundSubtractorLSBP();
3438

3539
return algo;
3640
}
3741

3842
int main(int argc, char** argv)
3943
{
40-
CommandLineParser parser(argc, argv, keys);
44+
CommandLineParser parser(argc, argv, "{@video | vtest.avi | path to a video file}");
4145
parser.about(about);
4246
parser.printMessage();
43-
if (parser.has("help"))
44-
{
45-
parser.printMessage();
46-
return 0;
47-
}
4847

49-
String videoPath = parser.get<String>("vid");
50-
String algoName = parser.get<String>("algo");
48+
String videoPath = samples::findFile(parser.get<String>(0),false);
5149

52-
if (!parser.check())
53-
{
54-
parser.printErrors();
55-
return 0;
56-
}
57-
58-
Ptr<BackgroundSubtractor> bgfs = createBGSubtractorByName(algoName);
59-
if (!bgfs)
60-
{
61-
std::cerr << "Failed to create " << algoName << " background subtractor" << std::endl;
62-
return -1;
63-
}
50+
Ptr<BackgroundSubtractor> bgfs = createBGSubtractorByName(algos[0]);
6451

6552
VideoCapture cap;
66-
if (argc > 1)
67-
cap.open(videoPath);
68-
else
69-
cap.open(0);
53+
cap.open(videoPath);
7054

7155
if (!cap.isOpened())
7256
{
@@ -76,24 +60,63 @@ int main(int argc, char** argv)
7660

7761
Mat frame, fgmask, segm;
7862

79-
namedWindow("FG Segmentation", WINDOW_NORMAL);
63+
int delay = 30;
64+
int algo_index = 0;
65+
int nthreads = getNumberOfCPUs();
66+
bool show_fgmask = false;
8067

8168
for (;;)
8269
{
8370
cap >> frame;
8471

8572
if (frame.empty())
86-
break;
73+
{
74+
cap.set(CAP_PROP_POS_FRAMES, 0);
75+
cap >> frame;
76+
}
8777

8878
bgfs->apply(frame, fgmask);
8979

90-
frame.convertTo(segm, CV_8U, 0.5);
91-
add(frame, Scalar(100, 100, 0), segm, fgmask);
80+
if (show_fgmask)
81+
segm = fgmask;
82+
else
83+
{
84+
frame.convertTo(segm, CV_8U, 0.5);
85+
add(frame, Scalar(100, 100, 0), segm, fgmask);
86+
}
87+
88+
putText(segm, algos[algo_index], Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(255, 0, 255), 2, LINE_AA);
89+
putText(segm, format("%d threads", nthreads), Point(10, 60), FONT_HERSHEY_PLAIN, 2.0, Scalar(255, 0, 255), 2, LINE_AA);
9290

9391
imshow("FG Segmentation", segm);
9492

95-
int c = waitKey(30);
96-
if (c == 'q' || c == 'Q' || (c & 255) == 27)
93+
int c = waitKey(delay);
94+
95+
if (c == ' ')
96+
delay = delay == 30 ? 1 : 30;
97+
98+
if (c == 'c' || c == 'C')
99+
{
100+
algo_index++;
101+
if ( algo_index > 6 )
102+
algo_index = 0;
103+
104+
bgfs = createBGSubtractorByName(algos[algo_index]);
105+
}
106+
107+
if (c == 'n' || c == 'N')
108+
{
109+
nthreads++;
110+
if ( nthreads > 8 )
111+
nthreads = 1;
112+
113+
setNumThreads(nthreads);
114+
}
115+
116+
if (c == 'm' || c == 'M')
117+
show_fgmask = !show_fgmask;
118+
119+
if (c == 'q' || c == 'Q' || c == 27)
97120
break;
98121
}
99122

modules/text/include/opencv2/text/erfilter.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ enum erGrouping_Modes {
284284
finds the branches corresponding to text groups by traversing this dendrogram with a stopping rule
285285
that combines the output of a rotation invariant text group classifier and a probabilistic measure
286286
for hierarchical clustering validity assessment.
287+
288+
@note This mode is not supported due NFA code removal ( https://github.com/opencv/opencv_contrib/issues/2235 )
287289
*/
288290
ERGROUPING_ORIENTATION_ANY
289291
};

modules/text/src/erfilter.cpp

Lines changed: 6 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
#endif
5959
#endif
6060

61+
#if defined(_MSC_VER)
62+
# pragma warning(disable:4702) // unreachable code
63+
#endif
64+
6165
namespace cv
6266
{
6367
namespace text
@@ -1319,150 +1323,6 @@ void computeNMChannels(InputArray _src, CV_OUT OutputArrayOfArrays _channels, in
13191323
/* -------------------------------- ER Grouping Algorithm -----------------------------*/
13201324
/* ------------------------------------------------------------------------------------*/
13211325

1322-
1323-
/* NFA approximation functions */
1324-
1325-
// ln(10)
1326-
#ifndef M_LN10
1327-
#define M_LN10 2.30258509299404568401799145468436421
1328-
#endif
1329-
// Doubles relative error factor
1330-
#define RELATIVE_ERROR_FACTOR 100.0
1331-
1332-
// Compare doubles by relative error.
1333-
static int double_equal(double a, double b)
1334-
{
1335-
double abs_diff,aa,bb,abs_max;
1336-
1337-
/* trivial case */
1338-
if( a == b ) return true;
1339-
1340-
abs_diff = fabs(a-b);
1341-
aa = fabs(a);
1342-
bb = fabs(b);
1343-
abs_max = aa > bb ? aa : bb;
1344-
1345-
/* DBL_MIN is the smallest normalized number, thus, the smallest
1346-
number whose relative error is bounded by DBL_EPSILON. For
1347-
smaller numbers, the same quantization steps as for DBL_MIN
1348-
are used. Then, for smaller numbers, a meaningful "relative"
1349-
error should be computed by dividing the difference by DBL_MIN. */
1350-
if( abs_max < DBL_MIN ) abs_max = DBL_MIN;
1351-
1352-
/* equal if relative error <= factor x eps */
1353-
return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * DBL_EPSILON);
1354-
}
1355-
1356-
1357-
/*
1358-
Computes the natural logarithm of the absolute value of
1359-
the gamma function of x using the Lanczos approximation.
1360-
See http://www.rskey.org/gamma.htm
1361-
*/
1362-
static double log_gamma_lanczos(double x)
1363-
{
1364-
static double q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
1365-
8687.24529705, 1168.92649479, 83.8676043424,
1366-
2.50662827511 };
1367-
double a = (x+0.5) * log(x+5.5) - (x+5.5);
1368-
double b = 0.0;
1369-
int n;
1370-
1371-
for(n=0;n<7;n++)
1372-
{
1373-
a -= log( x + (double) n );
1374-
b += q[n] * pow( x, (double) n );
1375-
}
1376-
return a + log(b);
1377-
}
1378-
1379-
/*
1380-
Computes the natural logarithm of the absolute value of
1381-
the gamma function of x using Windschitl method.
1382-
See http://www.rskey.org/gamma.htm
1383-
*/
1384-
static double log_gamma_windschitl(double x)
1385-
{
1386-
return 0.918938533204673 + (x-0.5)*log(x) - x
1387-
+ 0.5*x*log( x*sinh(1/x) + 1/(810.0*pow(x,6.0)) );
1388-
}
1389-
1390-
/*
1391-
Computes the natural logarithm of the absolute value of
1392-
the gamma function of x. When x>15 use log_gamma_windschitl(),
1393-
otherwise use log_gamma_lanczos().
1394-
*/
1395-
#define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x))
1396-
1397-
// Size of the table to store already computed inverse values.
1398-
#define TABSIZE 100000
1399-
1400-
/*
1401-
Computes -log10(NFA).
1402-
NFA stands for Number of False Alarms:
1403-
*/
1404-
static double NFA(int n, int k, double p, double logNT)
1405-
{
1406-
static double inv[TABSIZE]; /* table to keep computed inverse values */
1407-
double tolerance = 0.1; /* an error of 10% in the result is accepted */
1408-
double log1term,term,bin_term,mult_term,bin_tail,err,p_term;
1409-
int i;
1410-
1411-
if (p<=0)
1412-
p = std::numeric_limits<double>::min();
1413-
if (p>=1)
1414-
p = 1 - std::numeric_limits<double>::epsilon();
1415-
1416-
/* check parameters */
1417-
if( n<0 || k<0 || k>n || p<=0.0 || p>=1.0 )
1418-
{
1419-
CV_Error(Error::StsBadArg, "erGrouping wrong n, k or p values in NFA call!");
1420-
}
1421-
1422-
/* trivial cases */
1423-
if( n==0 || k==0 ) return -logNT;
1424-
if( n==k ) return -logNT - (double) n * log10(p);
1425-
1426-
/* probability term */
1427-
p_term = p / (1.0-p);
1428-
1429-
/* compute the first term of the series */
1430-
log1term = log_gamma( (double) n + 1.0 ) - log_gamma( (double) k + 1.0 )
1431-
- log_gamma( (double) (n-k) + 1.0 )
1432-
+ (double) k * log(p) + (double) (n-k) * log(1.0-p);
1433-
term = exp(log1term);
1434-
1435-
/* in some cases no more computations are needed */
1436-
if( double_equal(term,0.0) ) /* the first term is almost zero */
1437-
{
1438-
if( (double) k > (double) n * p ) /* at begin or end of the tail? */
1439-
return -log1term / M_LN10 - logNT; /* end: use just the first term */
1440-
else
1441-
return -logNT; /* begin: the tail is roughly 1 */
1442-
}
1443-
1444-
/* compute more terms if needed */
1445-
bin_tail = term;
1446-
for(i=k+1;i<=n;i++)
1447-
{
1448-
bin_term = (double) (n-i+1) * ( i<TABSIZE ?
1449-
( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (double) i ) ) :
1450-
1.0 / (double) i );
1451-
1452-
mult_term = bin_term * p_term;
1453-
term *= mult_term;
1454-
bin_tail += term;
1455-
if(bin_term<1.0)
1456-
{
1457-
err = term * ( ( 1.0 - pow( mult_term, (double) (n-i+1) ) ) /
1458-
(1.0-mult_term) - 1.0 );
1459-
if( err < tolerance * fabs(-log10(bin_tail)-logNT) * bin_tail ) break;
1460-
}
1461-
}
1462-
return -log10(bin_tail) - logNT;
1463-
}
1464-
1465-
14661326
// Minibox : smallest enclosing box of a set of n points in d dimensions
14671327

14681328
class Minibox {
@@ -2480,8 +2340,8 @@ void MaxMeaningfulClustering::build_merge_info(double *Z, double *X, int N, int
24802340

24812341
int MaxMeaningfulClustering::nfa(float sigma, int k, int N)
24822342
{
2483-
// use an approximation for the nfa calculations (faster)
2484-
return -1*(int)NFA( N, k, (double) sigma, 0);
2343+
CV_UNUSED(sigma); CV_UNUSED(k); CV_UNUSED(N);
2344+
CV_Error(Error::StsNotImplemented, "text: NFA computation code has been removed due license conflict. Details: https://github.com/opencv/opencv_contrib/issues/2235");
24852345
}
24862346

24872347

modules/text/test/test_detection.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ TEST_P(Detection, sample)
3737

3838
std::string imageName = GET_PARAM(0);
3939
bool anyDirection = GET_PARAM(1);
40+
if (anyDirection)
41+
throw SkipTestException("ERGROUPING_ORIENTATION_ANY mode is not supported");
4042
std::cout << "Image: " << imageName << std::endl;
4143
std::cout << "Orientation: " << (anyDirection ? "any" : "horiz") << std::endl;
4244
Mat src = cv::imread(findDataFile(imageName));

0 commit comments

Comments
 (0)