#add_extra_compiler_option(-Wcast-align)
#add_extra_compiler_option(-Wstrict-aliasing=2)
#add_extra_compiler_option(-Wshadow)
- add_extra_compiler_option(-Wno-unnamed-type-template-args)
+ #add_extra_compiler_option(-Wno-unnamed-type-template-args)
# The -Wno-long-long is required in 64bit systems when including sytem headers.
if(X86_64)
if(TBB_FOUND)
set(HAVE_TBB 1)
if(NOT ${TBB_INCLUDE_DIRS} STREQUAL "")
- include_directories(SYSTEM ${TBB_INCLUDE_DIRS})
+ ocv_include_directories(${TBB_INCLUDE_DIRS})
endif()
link_directories(${TBB_LIBRARY_DIRS})
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${TBB_LIBRARIES})
set(HAVE_TBB 1)
if(NOT "${TBB_INCLUDE_DIRS}" STREQUAL "")
- include_directories(SYSTEM "${TBB_INCLUDE_DIRS}")
+ ocv_include_directories("${TBB_INCLUDE_DIRS}")
endif()
endif(TBB_INCLUDE_DIRS)
endif(NOT HAVE_TBB)
if("${__abs_dir}" MATCHES "^${OpenCV_SOURCE_DIR}" OR "${__abs_dir}" MATCHES "^${OpenCV_BINARY_DIR}")
list(APPEND __add_before "${dir}")
else()
- include_directories(AFTER "${dir}")
+ include_directories(AFTER SYSTEM "${dir}")
endif()
endforeach()
include_directories(BEFORE ${__add_before})
int found = 0;
CvCBQuad *quads = 0, **quad_group = 0;
CvCBCorner *corners = 0, **corner_group = 0;
-
+
try
{
int k = 0;
if( out_corner_count )
*out_corner_count = 0;
-
+
IplImage _img;
int check_chessboard_result;
- int quad_count = 0, group_idx = 0, i = 0, dilations = 0;
-
+ int quad_count = 0, group_idx = 0, dilations = 0;
+
img = cvGetMat( img, &stub );
//debug_img = img;
for( dilations = min_dilations; dilations <= max_dilations; dilations++ )
{
if (found)
- break; // already found it
-
+ break; // already found it
+
cvFree(&quads);
cvFree(&corners);
cvCopy(dbg_img, dbg1_img);
cvNamedWindow("all_quads", 1);
// copy corners to temp array
- for( i = 0; i < quad_count; i++ )
+ for(int i = 0; i < quad_count; i++ )
{
for (int k=0; k<4; k++)
{
cvCopy(dbg_img,dbg2_img);
cvNamedWindow("connected_group", 1);
// copy corners to temp array
- for( i = 0; i < quad_count; i++ )
+ for(int i = 0; i < quad_count; i++ )
{
if (quads[i].group_idx == group_idx)
for (int k=0; k<4; k++)
#endif
if (count == 0)
- continue; // haven't found inner quads
+ continue; // haven't found inner quads
// If count is more than it should be, this will remove those quads
float sum_dist = 0;
int total = 0;
- for( i = 0; i < n; i++ )
+ for(int i = 0; i < n; i++ )
{
int ni = 0;
float avgi = corner_group[i]->meanDist(&ni);
if( count > 0 || (out_corner_count && -count > *out_corner_count) )
{
// copy corners to output array
- for( i = 0; i < n; i++ )
+ for(int i = 0; i < n; i++ )
out_corners[i] = corner_group[i]->pt;
if( out_corner_count )
if( found )
found = icvCheckBoardMonotony( out_corners, pattern_size );
- // check that none of the found corners is too close to the image boundary
+ // check that none of the found corners is too close to the image boundary
if( found )
- {
- const int BORDER = 8;
- for( k = 0; k < pattern_size.width*pattern_size.height; k++ )
- {
- if( out_corners[k].x <= BORDER || out_corners[k].x > img->cols - BORDER ||
- out_corners[k].y <= BORDER || out_corners[k].y > img->rows - BORDER )
- break;
- }
-
- found = k == pattern_size.width*pattern_size.height;
- }
+ {
+ const int BORDER = 8;
+ for( k = 0; k < pattern_size.width*pattern_size.height; k++ )
+ {
+ if( out_corners[k].x <= BORDER || out_corners[k].x > img->cols - BORDER ||
+ out_corners[k].y <= BORDER || out_corners[k].y > img->rows - BORDER )
+ break;
+ }
+
+ found = k == pattern_size.width*pattern_size.height;
+ }
if( found && pattern_size.height % 2 == 0 && pattern_size.width % 2 == 0 )
{
double dy0 = out_corners[last_row].y - out_corners[0].y;
if( dy0 < 0 )
{
- int i, n = pattern_size.width*pattern_size.height;
- for( i = 0; i < n/2; i++ )
+ int n = pattern_size.width*pattern_size.height;
+ for(int i = 0; i < n/2; i++ )
{
CvPoint2D32f temp;
CV_SWAP(out_corners[i], out_corners[n-i-1], temp);
cvFree(&corner_group);
throw;
}
-
+
cvFree(&quads);
cvFree(&corners);
cvFree(&quad_group);
icvCheckBoardMonotony( CvPoint2D32f* corners, CvSize pattern_size )
{
int i, j, k;
-
+
for( k = 0; k < 2; k++ )
{
for( i = 0; i < (k == 0 ? pattern_size.height : pattern_size.width); i++ )
{
cv::Ptr<CvMemStorage> temp_storage = cvCreateChildMemStorage( storage );
CvSeq* stack = cvCreateSeq( 0, sizeof(*stack), sizeof(void*), temp_storage );
- int i;
// first find an interior quad
CvCBQuad *start = NULL;
- for (i=0; i<quad_count; i++)
+ for (int i=0; i<quad_count; i++)
{
if (quads[i]->count == 4)
{
case 1:
col += 2; break;
case 2:
- row += 2; break;
+ row += 2; break;
case 3:
col -= 2; break;
}
}
}
- for (i=col_min; i<=col_max; i++)
+ for (int i=col_min; i<=col_max; i++)
PRINTF("HIST[%d] = %d\n", i, col_hist[i]);
// analyze inner quad structure
// if there is an outer quad missing, fill it in
// first order all inner quads
int found = 0;
- for (i=0; i<quad_count; i++)
+ for (int i=0; i<quad_count; i++)
{
if (quads[i]->count == 4)
{ // ok, look at neighbors
case 1:
col += 2; break;
case 2:
- row += 2; break;
+ row += 2; break;
case 3:
col -= 2; break;
}
// final trimming of outer quads
- if (dcol == w && drow == h) // found correct inner quads
+ if (dcol == w && drow == h) // found correct inner quads
{
PRINTF("Inner bounds ok, check outer quads\n");
int rcount = quad_count;
if (quads[i]->neighbors[j] && quads[i]->neighbors[j]->ordered)
outer = true;
}
- if (!outer) // not an outer quad, eliminate
+ if (!outer) // not an outer quad, eliminate
{
PRINTF("Removing quad %d\n", i);
icvRemoveQuadFromGroup(quads,rcount,quads[i]);
quad->count += 1;
q->neighbors[j] = quad;
q->group_idx = quad->group_idx;
- q->count = 1; // number of neighbors
+ q->count = 1; // number of neighbors
q->ordered = false;
q->edge_len = quad->edge_len;
int width = 0, height = 0;
int hist[5] = {0,0,0,0,0};
CvCBCorner* first = 0, *first2 = 0, *right, *cur, *below, *c;
-
+
// build dual graph, which vertices are internal quad corners
// and two vertices are connected iff they lie on the same quad edge
for( i = 0; i < quad_count; i++ )
result = corner_count;
finalize:
-
+
if( result <= 0 )
{
corner_count = MIN( corner_count, pattern_size.width*pattern_size.height );
CV_POLY_APPROX_DP, (float)approx_level );
if( dst_contour->total == 4 )
break;
-
+
// we call this again on its own output, because sometimes
// cvApproxPoly() does not simplify as much as it should.
dst_contour = cvApproxPoly( dst_contour, sizeof(CvContour), temp_storage,
#endif
if (isFound)
{
- switch(parameters.gridType)
- {
+ switch(parameters.gridType)
+ {
case CirclesGridFinderParameters::SYMMETRIC_GRID:
boxFinder.getHoles(centers);
break;
case CirclesGridFinderParameters::ASYMMETRIC_GRID:
- boxFinder.getAsymmetricHoles(centers);
- break;
+ boxFinder.getAsymmetricHoles(centers);
+ break;
default:
CV_Error(CV_StsBadArg, "Unkown pattern type");
- }
+ }
if (i != 0)
{
Mat(centers).copyTo(_centers);
return true;
}
-
+
boxFinder.getHoles(centers);
if (i != attempts - 1)
{
int useExtrinsicGuess )
{
const int max_iter = 20;
- Ptr<CvMat> matM, _Mxy, _m, _mn, matL, matJ;
+ Ptr<CvMat> matM, _Mxy, _m, _mn, matL;
int i, count;
double a[9], ar[9]={1,0,0,0,1,0,0,0,1}, R[9];
}
#endif
-void CirclesGridClusterFinder::hierarchicalClustering(const vector<Point2f> points, const Size &patternSize, vector<Point2f> &patternPoints)
+void CirclesGridClusterFinder::hierarchicalClustering(const vector<Point2f> points, const Size &patternSz, vector<Point2f> &patternPoints)
{
#ifdef HAVE_TEGRA_OPTIMIZATION
- if(tegra::hierarchicalClustering(points, patternSize, patternPoints))
+ if(tegra::hierarchicalClustering(points, patternSz, patternPoints))
return;
#endif
- int i, j, n = (int)points.size();
- size_t pn = static_cast<size_t>(patternSize.area());
+ int j, n = (int)points.size();
+ size_t pn = static_cast<size_t>(patternSz.area());
patternPoints.clear();
if (pn >= points.size())
Mat dists(n, n, CV_32FC1, Scalar(0));
Mat distsMask(dists.size(), CV_8UC1, Scalar(0));
- for(i = 0; i < n; i++)
+ for(int i = 0; i < n; i++)
{
for(j = i+1; j < n; j++)
{
}
//the largest cluster can have more than pn points -- we need to filter out such situations
- if(clusters[patternClusterIdx].size() != static_cast<size_t>(patternSize.area()))
+ if(clusters[patternClusterIdx].size() != static_cast<size_t>(patternSz.area()))
{
return;
}
{
for (Vertices::const_iterator it3 = vertices.begin(); it3 != vertices.end(); it3++)
{
- int i1 = (int)it1->first, i2 = (int)it2->first, i3 = (int)it3->first;
+ int i1 = (int)it1->first, i2 = (int)it2->first, i3 = (int)it3->first;
int val1 = distanceMatrix.at<int> (i2, i3);
int val2;
if (distanceMatrix.at<int> (i2, i1) == infinity ||
- distanceMatrix.at<int> (i1, i3) == infinity)
+ distanceMatrix.at<int> (i1, i3) == infinity)
val2 = val1;
else
{
if (cameraMatrix.depth() == CV_32F)\r
init_camera_parameters<float>(cameraMatrix);\r
else\r
- init_camera_parameters<double>(cameraMatrix);\r
+ init_camera_parameters<double>(cameraMatrix);\r
\r
number_of_correspondences = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));\r
\r
pws.resize(3 * number_of_correspondences);\r
- us.resize(2 * number_of_correspondences); \r
- \r
+ us.resize(2 * number_of_correspondences);\r
+\r
if (opoints.depth() == ipoints.depth())\r
{\r
- if (opoints.depth() == CV_32F)\r
- init_points<cv::Point3f,cv::Point2f>(opoints, ipoints);\r
- else\r
- init_points<cv::Point3d,cv::Point2d>(opoints, ipoints);\r
+ if (opoints.depth() == CV_32F)\r
+ init_points<cv::Point3f,cv::Point2f>(opoints, ipoints);\r
+ else\r
+ init_points<cv::Point3d,cv::Point2d>(opoints, ipoints);\r
}\r
else if (opoints.depth() == CV_32F)\r
- init_points<cv::Point3f,cv::Point2d>(opoints, ipoints);\r
+ init_points<cv::Point3f,cv::Point2d>(opoints, ipoints);\r
else\r
- init_points<cv::Point3d,cv::Point2f>(opoints, ipoints);\r
+ init_points<cv::Point3d,cv::Point2f>(opoints, ipoints);\r
\r
- alphas.resize(4 * number_of_correspondences); \r
+ alphas.resize(4 * number_of_correspondences);\r
pcs.resize(3 * number_of_correspondences);\r
\r
max_nr = 0;\r
\r
for(int j = 0; j < 3; j++)\r
a[1 + j] =\r
- ci[3 * j ] * (pi[0] - cws[0][0]) +\r
- ci[3 * j + 1] * (pi[1] - cws[0][1]) +\r
- ci[3 * j + 2] * (pi[2] - cws[0][2]);\r
+ ci[3 * j ] * (pi[0] - cws[0][0]) +\r
+ ci[3 * j + 1] * (pi[1] - cws[0][1]) +\r
+ ci[3 * j + 2] * (pi[2] - cws[0][2]);\r
a[0] = 1.0f - a[1] - a[2] - a[3];\r
}\r
}\r
\r
void epnp::fill_M(CvMat * M,\r
- const int row, const double * as, const double u, const double v)\r
+ const int row, const double * as, const double u, const double v)\r
{\r
double * M1 = M->data.db + row * 12;\r
double * M2 = M1 + 12;\r
const double * v = ut + 12 * (11 - i);\r
for(int j = 0; j < 4; j++)\r
for(int k = 0; k < 3; k++)\r
- ccs[j][k] += betas[i] * v[3 * j + k];\r
+ ccs[j][k] += betas[i] * v[3 * j + k];\r
}\r
}\r
\r
}\r
\r
void epnp::copy_R_and_t(const double R_src[3][3], const double t_src[3],\r
- double R_dst[3][3], double t_dst[3])\r
+ double R_dst[3][3], double t_dst[3])\r
{\r
for(int i = 0; i < 3; i++) {\r
for(int j = 0; j < 3; j++)\r
if (pcs[2] < 0.0) {\r
for(int i = 0; i < 4; i++)\r
for(int j = 0; j < 3; j++)\r
- ccs[i][j] = -ccs[i][j];\r
+ ccs[i][j] = -ccs[i][j];\r
\r
for(int i = 0; i < number_of_correspondences; i++) {\r
pcs[3 * i ] = -pcs[3 * i];\r
}\r
\r
double epnp::compute_R_and_t(const double * ut, const double * betas,\r
- double R[3][3], double t[3])\r
+ double R[3][3], double t[3])\r
{\r
compute_ccs(betas, ut);\r
compute_pcs();\r
}\r
\r
return sum2 / number_of_correspondences;\r
-} \r
+}\r
\r
// betas10 = [B11 B12 B22 B13 B23 B33 B14 B24 B34 B44]\r
// betas_approx_1 = [B11 B12 B13 B14]\r
\r
void epnp::find_betas_approx_1(const CvMat * L_6x10, const CvMat * Rho,\r
- double * betas)\r
+ double * betas)\r
{\r
double l_6x4[6 * 4], b4[4];\r
CvMat L_6x4 = cvMat(6, 4, CV_64F, l_6x4);\r
// betas_approx_2 = [B11 B12 B22 ]\r
\r
void epnp::find_betas_approx_2(const CvMat * L_6x10, const CvMat * Rho,\r
- double * betas)\r
+ double * betas)\r
{\r
double l_6x3[6 * 3], b3[3];\r
CvMat L_6x3 = cvMat(6, 3, CV_64F, l_6x3);\r
// betas_approx_3 = [B11 B12 B22 B13 B23 ]\r
\r
void epnp::find_betas_approx_3(const CvMat * L_6x10, const CvMat * Rho,\r
- double * betas)\r
+ double * betas)\r
{\r
double l_6x5[6 * 5], b5[5];\r
CvMat L_6x5 = cvMat(6, 5, CV_64F, l_6x5);\r
\r
b++;\r
if (b > 3) {\r
- a++;\r
- b = a + 1;\r
+ a++;\r
+ b = a + 1;\r
}\r
}\r
}\r
}\r
\r
void epnp::compute_A_and_b_gauss_newton(const double * l_6x10, const double * rho,\r
- const double betas[4], CvMat * A, CvMat * b)\r
+ const double betas[4], CvMat * A, CvMat * b)\r
{\r
for(int i = 0; i < 6; i++) {\r
const double * rowL = l_6x10 + i * 10;\r
rowA[3] = rowL[6] * betas[0] + rowL[7] * betas[1] + rowL[8] * betas[2] + 2 * rowL[9] * betas[3];\r
\r
cvmSet(b, i, 0, rho[i] -\r
- (\r
- rowL[0] * betas[0] * betas[0] +\r
- rowL[1] * betas[0] * betas[1] +\r
- rowL[2] * betas[1] * betas[1] +\r
- rowL[3] * betas[0] * betas[2] +\r
- rowL[4] * betas[1] * betas[2] +\r
- rowL[5] * betas[2] * betas[2] +\r
- rowL[6] * betas[0] * betas[3] +\r
- rowL[7] * betas[1] * betas[3] +\r
- rowL[8] * betas[2] * betas[3] +\r
- rowL[9] * betas[3] * betas[3]\r
- ));\r
+ (\r
+ rowL[0] * betas[0] * betas[0] +\r
+ rowL[1] * betas[0] * betas[1] +\r
+ rowL[2] * betas[1] * betas[1] +\r
+ rowL[3] * betas[0] * betas[2] +\r
+ rowL[4] * betas[1] * betas[2] +\r
+ rowL[5] * betas[2] * betas[2] +\r
+ rowL[6] * betas[0] * betas[3] +\r
+ rowL[7] * betas[1] * betas[3] +\r
+ rowL[8] * betas[2] * betas[3] +\r
+ rowL[9] * betas[3] * betas[3]\r
+ ));\r
}\r
}\r
\r
-void epnp::gauss_newton(const CvMat * L_6x10, const CvMat * Rho,\r
- double betas[4])\r
+void epnp::gauss_newton(const CvMat * L_6x10, const CvMat * Rho, double betas[4])\r
{\r
const int iterations_number = 5;\r
\r
CvMat B = cvMat(6, 1, CV_64F, b);\r
CvMat X = cvMat(4, 1, CV_64F, x);\r
\r
- for(int k = 0; k < iterations_number; k++) {\r
+ for(int k = 0; k < iterations_number; k++)\r
+ {\r
compute_A_and_b_gauss_newton(L_6x10->data.db, Rho->data.db,\r
- betas, &A, &B);\r
+ betas, &A, &B);\r
qr_solve(&A, &B, &X);\r
for(int i = 0; i < 4; i++)\r
- betas[i] += x[i];\r
+ betas[i] += x[i];\r
}\r
}\r
\r
const int nr = A->rows;\r
const int nc = A->cols;\r
\r
- if (max_nr != 0 && max_nr < nr) {\r
+ if (max_nr != 0 && max_nr < nr)\r
+ {\r
delete [] A1;\r
delete [] A2;\r
}\r
- if (max_nr < nr) {\r
+ if (max_nr < nr)\r
+ {\r
max_nr = nr;\r
A1 = new double[nr];\r
A2 = new double[nr];\r
}\r
\r
double * pA = A->data.db, * ppAkk = pA;\r
- for(int k = 0; k < nc; k++) {\r
- double * ppAik = ppAkk, eta = fabs(*ppAik);\r
- for(int i = k + 1; i < nr; i++) {\r
- double elt = fabs(*ppAik);\r
+ for(int k = 0; k < nc; k++)\r
+ {\r
+ double * ppAik1 = ppAkk, eta = fabs(*ppAik1);\r
+ for(int i = k + 1; i < nr; i++)\r
+ {\r
+ double elt = fabs(*ppAik1);\r
if (eta < elt) eta = elt;\r
- ppAik += nc;\r
+ ppAik1 += nc;\r
}\r
- if (eta == 0) {\r
+ if (eta == 0)\r
+ {\r
A1[k] = A2[k] = 0.0;\r
//cerr << "God damnit, A is singular, this shouldn't happen." << endl;\r
return;\r
- } else {\r
- double * ppAik = ppAkk, sum = 0.0, inv_eta = 1. / eta;\r
- for(int i = k; i < nr; i++) {\r
- *ppAik *= inv_eta;\r
- sum += *ppAik * *ppAik;\r
- ppAik += nc;\r
+ }\r
+ else\r
+ {\r
+ double * ppAik2 = ppAkk, sum2 = 0.0, inv_eta = 1. / eta;\r
+ for(int i = k; i < nr; i++)\r
+ {\r
+ *ppAik2 *= inv_eta;\r
+ sum2 += *ppAik2 * *ppAik2;\r
+ ppAik2 += nc;\r
}\r
- double sigma = sqrt(sum);\r
+ double sigma = sqrt(sum2);\r
if (*ppAkk < 0)\r
- sigma = -sigma;\r
+ sigma = -sigma;\r
*ppAkk += sigma;\r
A1[k] = sigma * *ppAkk;\r
A2[k] = -eta * sigma;\r
- for(int j = k + 1; j < nc; j++) {\r
- double * ppAik = ppAkk, sum = 0;\r
- for(int i = k; i < nr; i++) {\r
- sum += *ppAik * ppAik[j - k];\r
- ppAik += nc;\r
- }\r
- double tau = sum / A1[k];\r
- ppAik = ppAkk;\r
- for(int i = k; i < nr; i++) {\r
- ppAik[j - k] -= tau * *ppAik;\r
- ppAik += nc;\r
- }\r
+ for(int j = k + 1; j < nc; j++)\r
+ {\r
+ double * ppAik = ppAkk, sum = 0;\r
+ for(int i = k; i < nr; i++)\r
+ {\r
+ sum += *ppAik * ppAik[j - k];\r
+ ppAik += nc;\r
+ }\r
+ double tau = sum / A1[k];\r
+ ppAik = ppAkk;\r
+ for(int i = k; i < nr; i++)\r
+ {\r
+ ppAik[j - k] -= tau * *ppAik;\r
+ ppAik += nc;\r
+ }\r
}\r
}\r
ppAkk += nc + 1;\r
\r
// b <- Qt b\r
double * ppAjj = pA, * pb = b->data.db;\r
- for(int j = 0; j < nc; j++) {\r
+ for(int j = 0; j < nc; j++)\r
+ {\r
double * ppAij = ppAjj, tau = 0;\r
- for(int i = j; i < nr; i++) {\r
+ for(int i = j; i < nr; i++)\r
+ {\r
tau += *ppAij * pb[i];\r
ppAij += nc;\r
}\r
tau /= A1[j];\r
ppAij = ppAjj;\r
- for(int i = j; i < nr; i++) {\r
+ for(int i = j; i < nr; i++)\r
+ {\r
pb[i] -= tau * *ppAij;\r
ppAij += nc;\r
}\r
// X = R-1 b\r
double * pX = X->data.db;\r
pX[nc - 1] = pb[nc - 1] / A2[nc - 1];\r
- for(int i = nc - 2; i >= 0; i--) {\r
+ for(int i = nc - 2; i >= 0; i--)\r
+ {\r
double * ppAij = pA + i * nc + (i + 1), sum = 0;\r
\r
- for(int j = i + 1; j < nc; j++) {\r
+ for(int j = i + 1; j < nc; j++)\r
+ {\r
sum += *ppAij * pX[j];\r
ppAij++;\r
}\r
void p3p::init_inverse_parameters()
{
- inv_fx = 1. / fx;
- inv_fy = 1. / fy;
- cx_fx = cx / fx;
- cy_fy = cy / fy;
+ inv_fx = 1. / fx;
+ inv_fy = 1. / fy;
+ cx_fx = cx / fx;
+ cy_fy = cy / fy;
}
p3p::p3p(cv::Mat cameraMatrix)
{
- if (cameraMatrix.depth() == CV_32F)\r
- init_camera_parameters<float>(cameraMatrix);\r
- else\r
- init_camera_parameters<double>(cameraMatrix);
- init_inverse_parameters();
+ if (cameraMatrix.depth() == CV_32F)
+ init_camera_parameters<float>(cameraMatrix);
+ else
+ init_camera_parameters<double>(cameraMatrix);
+ init_inverse_parameters();
}
p3p::p3p(double _fx, double _fy, double _cx, double _cy)
{
- fx = _fx;
- fy = _fy;
- cx = _cx;
- cy = _cy;
- init_inverse_parameters();
+ fx = _fx;
+ fy = _fy;
+ cx = _cx;
+ cy = _cy;
+ init_inverse_parameters();
}
bool p3p::solve(cv::Mat& R, cv::Mat& tvec, const cv::Mat& opoints, const cv::Mat& ipoints)
{
- double rotation_matrix[3][3], translation[3];
- std::vector<double> points;
- if (opoints.depth() == ipoints.depth())\r
- {\r
- if (opoints.depth() == CV_32F)\r
- extract_points<cv::Point3f,cv::Point2f>(opoints, ipoints, points);\r
- else\r
- extract_points<cv::Point3d,cv::Point2d>(opoints, ipoints, points);\r
- }\r
- else if (opoints.depth() == CV_32F)\r
- extract_points<cv::Point3f,cv::Point2d>(opoints, ipoints, points);\r
- else\r
- extract_points<cv::Point3d,cv::Point2f>(opoints, ipoints, points);
-
- bool result = solve(rotation_matrix, translation, points[0], points[1], points[2], points[3], points[4], points[5],
- points[6], points[7], points[8], points[9], points[10], points[11], points[12], points[13], points[14],
- points[15], points[16], points[17], points[18], points[19]);
- cv::Mat(3, 1, CV_64F, translation).copyTo(tvec);\r
+ double rotation_matrix[3][3], translation[3];
+ std::vector<double> points;
+ if (opoints.depth() == ipoints.depth())
+ {
+ if (opoints.depth() == CV_32F)
+ extract_points<cv::Point3f,cv::Point2f>(opoints, ipoints, points);
+ else
+ extract_points<cv::Point3d,cv::Point2d>(opoints, ipoints, points);
+ }
+ else if (opoints.depth() == CV_32F)
+ extract_points<cv::Point3f,cv::Point2d>(opoints, ipoints, points);
+ else
+ extract_points<cv::Point3d,cv::Point2f>(opoints, ipoints, points);
+
+ bool result = solve(rotation_matrix, translation, points[0], points[1], points[2], points[3], points[4], points[5],
+ points[6], points[7], points[8], points[9], points[10], points[11], points[12], points[13], points[14],
+ points[15], points[16], points[17], points[18], points[19]);
+ cv::Mat(3, 1, CV_64F, translation).copyTo(tvec);
cv::Mat(3, 3, CV_64F, rotation_matrix).copyTo(R);
- return result;
+ return result;
}
bool p3p::solve(double R[3][3], double t[3],
- double mu0, double mv0, double X0, double Y0, double Z0,
- double mu1, double mv1, double X1, double Y1, double Z1,
- double mu2, double mv2, double X2, double Y2, double Z2,
- double mu3, double mv3, double X3, double Y3, double Z3)
+ double mu0, double mv0, double X0, double Y0, double Z0,
+ double mu1, double mv1, double X1, double Y1, double Z1,
+ double mu2, double mv2, double X2, double Y2, double Z2,
+ double mu3, double mv3, double X3, double Y3, double Z3)
{
- double Rs[4][3][3], ts[4][3];
-
- int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2);
-
- if (n == 0)
- return false;
-
- int ns = 0;
- double min_reproj = 0;
- for(int i = 0; i < n; i++) {
- double X3p = Rs[i][0][0] * X3 + Rs[i][0][1] * Y3 + Rs[i][0][2] * Z3 + ts[i][0];
- double Y3p = Rs[i][1][0] * X3 + Rs[i][1][1] * Y3 + Rs[i][1][2] * Z3 + ts[i][1];
- double Z3p = Rs[i][2][0] * X3 + Rs[i][2][1] * Y3 + Rs[i][2][2] * Z3 + ts[i][2];
- double mu3p = cx + fx * X3p / Z3p;
- double mv3p = cy + fy * Y3p / Z3p;
- double reproj = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
- if (i == 0 || min_reproj > reproj) {
- ns = i;
- min_reproj = reproj;
- }
- }
-
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++)
- R[i][j] = Rs[ns][i][j];
- t[i] = ts[ns][i];
- }
-
- return true;
+ double Rs[4][3][3], ts[4][3];
+
+ int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2);
+
+ if (n == 0)
+ return false;
+
+ int ns = 0;
+ double min_reproj = 0;
+ for(int i = 0; i < n; i++) {
+ double X3p = Rs[i][0][0] * X3 + Rs[i][0][1] * Y3 + Rs[i][0][2] * Z3 + ts[i][0];
+ double Y3p = Rs[i][1][0] * X3 + Rs[i][1][1] * Y3 + Rs[i][1][2] * Z3 + ts[i][1];
+ double Z3p = Rs[i][2][0] * X3 + Rs[i][2][1] * Y3 + Rs[i][2][2] * Z3 + ts[i][2];
+ double mu3p = cx + fx * X3p / Z3p;
+ double mv3p = cy + fy * Y3p / Z3p;
+ double reproj = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
+ if (i == 0 || min_reproj > reproj) {
+ ns = i;
+ min_reproj = reproj;
+ }
+ }
+
+ for(int i = 0; i < 3; i++) {
+ for(int j = 0; j < 3; j++)
+ R[i][j] = Rs[ns][i][j];
+ t[i] = ts[ns][i];
+ }
+
+ return true;
}
int p3p::solve(double R[4][3][3], double t[4][3],
- double mu0, double mv0, double X0, double Y0, double Z0,
- double mu1, double mv1, double X1, double Y1, double Z1,
- double mu2, double mv2, double X2, double Y2, double Z2)
+ double mu0, double mv0, double X0, double Y0, double Z0,
+ double mu1, double mv1, double X1, double Y1, double Z1,
+ double mu2, double mv2, double X2, double Y2, double Z2)
{
- double mk0, mk1, mk2;
- double norm;
+ double mk0, mk1, mk2;
+ double norm;
- mu0 = inv_fx * mu0 - cx_fx;
- mv0 = inv_fy * mv0 - cy_fy;
- norm = sqrt(mu0 * mu0 + mv0 * mv0 + 1);
- mk0 = 1. / norm; mu0 *= mk0; mv0 *= mk0;
+ mu0 = inv_fx * mu0 - cx_fx;
+ mv0 = inv_fy * mv0 - cy_fy;
+ norm = sqrt(mu0 * mu0 + mv0 * mv0 + 1);
+ mk0 = 1. / norm; mu0 *= mk0; mv0 *= mk0;
- mu1 = inv_fx * mu1 - cx_fx;
- mv1 = inv_fy * mv1 - cy_fy;
- norm = sqrt(mu1 * mu1 + mv1 * mv1 + 1);
- mk1 = 1. / norm; mu1 *= mk1; mv1 *= mk1;
+ mu1 = inv_fx * mu1 - cx_fx;
+ mv1 = inv_fy * mv1 - cy_fy;
+ norm = sqrt(mu1 * mu1 + mv1 * mv1 + 1);
+ mk1 = 1. / norm; mu1 *= mk1; mv1 *= mk1;
- mu2 = inv_fx * mu2 - cx_fx;
- mv2 = inv_fy * mv2 - cy_fy;
- norm = sqrt(mu2 * mu2 + mv2 * mv2 + 1);
- mk2 = 1. / norm; mu2 *= mk2; mv2 *= mk2;
+ mu2 = inv_fx * mu2 - cx_fx;
+ mv2 = inv_fy * mv2 - cy_fy;
+ norm = sqrt(mu2 * mu2 + mv2 * mv2 + 1);
+ mk2 = 1. / norm; mu2 *= mk2; mv2 *= mk2;
- double distances[3];
- distances[0] = sqrt( (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2) );
- distances[1] = sqrt( (X0 - X2) * (X0 - X2) + (Y0 - Y2) * (Y0 - Y2) + (Z0 - Z2) * (Z0 - Z2) );
- distances[2] = sqrt( (X0 - X1) * (X0 - X1) + (Y0 - Y1) * (Y0 - Y1) + (Z0 - Z1) * (Z0 - Z1) );
+ double distances[3];
+ distances[0] = sqrt( (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2) );
+ distances[1] = sqrt( (X0 - X2) * (X0 - X2) + (Y0 - Y2) * (Y0 - Y2) + (Z0 - Z2) * (Z0 - Z2) );
+ distances[2] = sqrt( (X0 - X1) * (X0 - X1) + (Y0 - Y1) * (Y0 - Y1) + (Z0 - Z1) * (Z0 - Z1) );
- // Calculate angles
- double cosines[3];
- cosines[0] = mu1 * mu2 + mv1 * mv2 + mk1 * mk2;
- cosines[1] = mu0 * mu2 + mv0 * mv2 + mk0 * mk2;
- cosines[2] = mu0 * mu1 + mv0 * mv1 + mk0 * mk1;
+ // Calculate angles
+ double cosines[3];
+ cosines[0] = mu1 * mu2 + mv1 * mv2 + mk1 * mk2;
+ cosines[1] = mu0 * mu2 + mv0 * mv2 + mk0 * mk2;
+ cosines[2] = mu0 * mu1 + mv0 * mv1 + mk0 * mk1;
- double lengths[4][3];
- int n = solve_for_lengths(lengths, distances, cosines);
+ double lengths[4][3];
+ int n = solve_for_lengths(lengths, distances, cosines);
- int nb_solutions = 0;
- for(int i = 0; i < n; i++) {
- double M_orig[3][3];
+ int nb_solutions = 0;
+ for(int i = 0; i < n; i++) {
+ double M_orig[3][3];
- M_orig[0][0] = lengths[i][0] * mu0;
- M_orig[0][1] = lengths[i][0] * mv0;
- M_orig[0][2] = lengths[i][0] * mk0;
+ M_orig[0][0] = lengths[i][0] * mu0;
+ M_orig[0][1] = lengths[i][0] * mv0;
+ M_orig[0][2] = lengths[i][0] * mk0;
- M_orig[1][0] = lengths[i][1] * mu1;
- M_orig[1][1] = lengths[i][1] * mv1;
- M_orig[1][2] = lengths[i][1] * mk1;
+ M_orig[1][0] = lengths[i][1] * mu1;
+ M_orig[1][1] = lengths[i][1] * mv1;
+ M_orig[1][2] = lengths[i][1] * mk1;
- M_orig[2][0] = lengths[i][2] * mu2;
- M_orig[2][1] = lengths[i][2] * mv2;
- M_orig[2][2] = lengths[i][2] * mk2;
+ M_orig[2][0] = lengths[i][2] * mu2;
+ M_orig[2][1] = lengths[i][2] * mv2;
+ M_orig[2][2] = lengths[i][2] * mk2;
- if (!align(M_orig, X0, Y0, Z0, X1, Y1, Z1, X2, Y2, Z2, R[nb_solutions], t[nb_solutions]))
- continue;
+ if (!align(M_orig, X0, Y0, Z0, X1, Y1, Z1, X2, Y2, Z2, R[nb_solutions], t[nb_solutions]))
+ continue;
- nb_solutions++;
- }
+ nb_solutions++;
+ }
- return nb_solutions;
+ return nb_solutions;
}
/// Given 3D distances between three points and cosines of 3 angles at the apex, calculates
int p3p::solve_for_lengths(double lengths[4][3], double distances[3], double cosines[3])
{
- double p = cosines[0] * 2;
- double q = cosines[1] * 2;
- double r = cosines[2] * 2;
+ double p = cosines[0] * 2;
+ double q = cosines[1] * 2;
+ double r = cosines[2] * 2;
- double inv_d22 = 1. / (distances[2] * distances[2]);
- double a = inv_d22 * (distances[0] * distances[0]);
- double b = inv_d22 * (distances[1] * distances[1]);
+ double inv_d22 = 1. / (distances[2] * distances[2]);
+ double a = inv_d22 * (distances[0] * distances[0]);
+ double b = inv_d22 * (distances[1] * distances[1]);
- double a2 = a * a, b2 = b * b, p2 = p * p, q2 = q * q, r2 = r * r;
- double pr = p * r, pqr = q * pr;
+ double a2 = a * a, b2 = b * b, p2 = p * p, q2 = q * q, r2 = r * r;
+ double pr = p * r, pqr = q * pr;
- // Check reality condition (the four points should not be coplanar)
- if (p2 + q2 + r2 - pqr - 1 == 0)
- return 0;
+ // Check reality condition (the four points should not be coplanar)
+ if (p2 + q2 + r2 - pqr - 1 == 0)
+ return 0;
- double ab = a * b, a_2 = 2*a;
+ double ab = a * b, a_2 = 2*a;
- double A = -2 * b + b2 + a2 + 1 + ab*(2 - r2) - a_2;
+ double A = -2 * b + b2 + a2 + 1 + ab*(2 - r2) - a_2;
- // Check reality condition
- if (A == 0) return 0;
+ // Check reality condition
+ if (A == 0) return 0;
- double a_4 = 4*a;
+ double a_4 = 4*a;
- double B = q*(-2*(ab + a2 + 1 - b) + r2*ab + a_4) + pr*(b - b2 + ab);
- double C = q2 + b2*(r2 + p2 - 2) - b*(p2 + pqr) - ab*(r2 + pqr) + (a2 - a_2)*(2 + q2) + 2;
- double D = pr*(ab-b2+b) + q*((p2-2)*b + 2 * (ab - a2) + a_4 - 2);
- double E = 1 + 2*(b - a - ab) + b2 - b*p2 + a2;
+ double B = q*(-2*(ab + a2 + 1 - b) + r2*ab + a_4) + pr*(b - b2 + ab);
+ double C = q2 + b2*(r2 + p2 - 2) - b*(p2 + pqr) - ab*(r2 + pqr) + (a2 - a_2)*(2 + q2) + 2;
+ double D = pr*(ab-b2+b) + q*((p2-2)*b + 2 * (ab - a2) + a_4 - 2);
+ double E = 1 + 2*(b - a - ab) + b2 - b*p2 + a2;
- double temp = (p2*(a-1+b) + r2*(a-1-b) + pqr - a*pqr);
- double b0 = b * temp * temp;
- // Check reality condition
- if (b0 == 0)
- return 0;
+ double temp = (p2*(a-1+b) + r2*(a-1-b) + pqr - a*pqr);
+ double b0 = b * temp * temp;
+ // Check reality condition
+ if (b0 == 0)
+ return 0;
- double real_roots[4];
- int n = solve_deg4(A, B, C, D, E, real_roots[0], real_roots[1], real_roots[2], real_roots[3]);
+ double real_roots[4];
+ int n = solve_deg4(A, B, C, D, E, real_roots[0], real_roots[1], real_roots[2], real_roots[3]);
- if (n == 0)
- return 0;
+ if (n == 0)
+ return 0;
- int nb_solutions = 0;
- double r3 = r2*r, pr2 = p*r2, r3q = r3 * q;
- double inv_b0 = 1. / b0;
+ int nb_solutions = 0;
+ double r3 = r2*r, pr2 = p*r2, r3q = r3 * q;
+ double inv_b0 = 1. / b0;
- // For each solution of x
- for(int i = 0; i < n; i++) {
- double x = real_roots[i];
+ // For each solution of x
+ for(int i = 0; i < n; i++) {
+ double x = real_roots[i];
- // Check reality condition
- if (x <= 0)
- continue;
+ // Check reality condition
+ if (x <= 0)
+ continue;
- double x2 = x*x;
+ double x2 = x*x;
- double b1 =
- ((1-a-b)*x2 + (q*a-q)*x + 1 - a + b) *
- (((r3*(a2 + ab*(2 - r2) - a_2 + b2 - 2*b + 1)) * x +
+ double b1 =
+ ((1-a-b)*x2 + (q*a-q)*x + 1 - a + b) *
+ (((r3*(a2 + ab*(2 - r2) - a_2 + b2 - 2*b + 1)) * x +
- (r3q*(2*(b-a2) + a_4 + ab*(r2 - 2) - 2) + pr2*(1 + a2 + 2*(ab-a-b) + r2*(b - b2) + b2))) * x2 +
+ (r3q*(2*(b-a2) + a_4 + ab*(r2 - 2) - 2) + pr2*(1 + a2 + 2*(ab-a-b) + r2*(b - b2) + b2))) * x2 +
- (r3*(q2*(1-2*a+a2) + r2*(b2-ab) - a_4 + 2*(a2 - b2) + 2) + r*p2*(b2 + 2*(ab - b - a) + 1 + a2) + pr2*q*(a_4 + 2*(b - ab - a2) - 2 - r2*b)) * x +
+ (r3*(q2*(1-2*a+a2) + r2*(b2-ab) - a_4 + 2*(a2 - b2) + 2) + r*p2*(b2 + 2*(ab - b - a) + 1 + a2) + pr2*q*(a_4 + 2*(b - ab - a2) - 2 - r2*b)) * x +
- 2*r3q*(a_2 - b - a2 + ab - 1) + pr2*(q2 - a_4 + 2*(a2 - b2) + r2*b + q2*(a2 - a_2) + 2) +
- p2*(p*(2*(ab - a - b) + a2 + b2 + 1) + 2*q*r*(b + a_2 - a2 - ab - 1)));
+ 2*r3q*(a_2 - b - a2 + ab - 1) + pr2*(q2 - a_4 + 2*(a2 - b2) + r2*b + q2*(a2 - a_2) + 2) +
+ p2*(p*(2*(ab - a - b) + a2 + b2 + 1) + 2*q*r*(b + a_2 - a2 - ab - 1)));
- // Check reality condition
- if (b1 <= 0)
- continue;
+ // Check reality condition
+ if (b1 <= 0)
+ continue;
- double y = inv_b0 * b1;
- double v = x2 + y*y - x*y*r;
+ double y = inv_b0 * b1;
+ double v = x2 + y*y - x*y*r;
- if (v <= 0)
- continue;
+ if (v <= 0)
+ continue;
- double Z = distances[2] / sqrt(v);
- double X = x * Z;
- double Y = y * Z;
+ double Z = distances[2] / sqrt(v);
+ double X = x * Z;
+ double Y = y * Z;
- lengths[nb_solutions][0] = X;
- lengths[nb_solutions][1] = Y;
- lengths[nb_solutions][2] = Z;
+ lengths[nb_solutions][0] = X;
+ lengths[nb_solutions][1] = Y;
+ lengths[nb_solutions][2] = Z;
- nb_solutions++;
- }
+ nb_solutions++;
+ }
- return nb_solutions;
+ return nb_solutions;
}
bool p3p::align(double M_end[3][3],
- double X0, double Y0, double Z0,
- double X1, double Y1, double Z1,
- double X2, double Y2, double Z2,
- double R[3][3], double T[3])
+ double X0, double Y0, double Z0,
+ double X1, double Y1, double Z1,
+ double X2, double Y2, double Z2,
+ double R[3][3], double T[3])
{
- // Centroids:
- double C_start[3], C_end[3];
- for(int i = 0; i < 3; i++) C_end[i] = (M_end[0][i] + M_end[1][i] + M_end[2][i]) / 3;
- C_start[0] = (X0 + X1 + X2) / 3;
- C_start[1] = (Y0 + Y1 + Y2) / 3;
- C_start[2] = (Z0 + Z1 + Z2) / 3;
-
- // Covariance matrix s:
- double s[3 * 3];
- for(int j = 0; j < 3; j++) {
- s[0 * 3 + j] = (X0 * M_end[0][j] + X1 * M_end[1][j] + X2 * M_end[2][j]) / 3 - C_end[j] * C_start[0];
- s[1 * 3 + j] = (Y0 * M_end[0][j] + Y1 * M_end[1][j] + Y2 * M_end[2][j]) / 3 - C_end[j] * C_start[1];
- s[2 * 3 + j] = (Z0 * M_end[0][j] + Z1 * M_end[1][j] + Z2 * M_end[2][j]) / 3 - C_end[j] * C_start[2];
- }
-
- double Qs[16], evs[4], U[16];
-
- Qs[0 * 4 + 0] = s[0 * 3 + 0] + s[1 * 3 + 1] + s[2 * 3 + 2];
- Qs[1 * 4 + 1] = s[0 * 3 + 0] - s[1 * 3 + 1] - s[2 * 3 + 2];
- Qs[2 * 4 + 2] = s[1 * 3 + 1] - s[2 * 3 + 2] - s[0 * 3 + 0];
- Qs[3 * 4 + 3] = s[2 * 3 + 2] - s[0 * 3 + 0] - s[1 * 3 + 1];
-
- Qs[1 * 4 + 0] = Qs[0 * 4 + 1] = s[1 * 3 + 2] - s[2 * 3 + 1];
- Qs[2 * 4 + 0] = Qs[0 * 4 + 2] = s[2 * 3 + 0] - s[0 * 3 + 2];
- Qs[3 * 4 + 0] = Qs[0 * 4 + 3] = s[0 * 3 + 1] - s[1 * 3 + 0];
- Qs[2 * 4 + 1] = Qs[1 * 4 + 2] = s[1 * 3 + 0] + s[0 * 3 + 1];
- Qs[3 * 4 + 1] = Qs[1 * 4 + 3] = s[2 * 3 + 0] + s[0 * 3 + 2];
- Qs[3 * 4 + 2] = Qs[2 * 4 + 3] = s[2 * 3 + 1] + s[1 * 3 + 2];
-
- jacobi_4x4(Qs, evs, U);
-
- // Looking for the largest eigen value:
- int i_ev = 0;
- double ev_max = evs[i_ev];
- for(int i = 1; i < 4; i++)
- if (evs[i] > ev_max)
- ev_max = evs[i_ev = i];
-
- // Quaternion:
- double q[4];
- for(int i = 0; i < 4; i++)
- q[i] = U[i * 4 + i_ev];
-
- double q02 = q[0] * q[0], q12 = q[1] * q[1], q22 = q[2] * q[2], q32 = q[3] * q[3];
- double q0_1 = q[0] * q[1], q0_2 = q[0] * q[2], q0_3 = q[0] * q[3];
- double q1_2 = q[1] * q[2], q1_3 = q[1] * q[3];
- double q2_3 = q[2] * q[3];
-
- R[0][0] = q02 + q12 - q22 - q32;
- R[0][1] = 2. * (q1_2 - q0_3);
- R[0][2] = 2. * (q1_3 + q0_2);
-
- R[1][0] = 2. * (q1_2 + q0_3);
- R[1][1] = q02 + q22 - q12 - q32;
- R[1][2] = 2. * (q2_3 - q0_1);
-
- R[2][0] = 2. * (q1_3 - q0_2);
- R[2][1] = 2. * (q2_3 + q0_1);
- R[2][2] = q02 + q32 - q12 - q22;
-
- for(int i = 0; i < 3; i++)
- T[i] = C_end[i] - (R[i][0] * C_start[0] + R[i][1] * C_start[1] + R[i][2] * C_start[2]);
-
- return true;
+ // Centroids:
+ double C_start[3], C_end[3];
+ for(int i = 0; i < 3; i++) C_end[i] = (M_end[0][i] + M_end[1][i] + M_end[2][i]) / 3;
+ C_start[0] = (X0 + X1 + X2) / 3;
+ C_start[1] = (Y0 + Y1 + Y2) / 3;
+ C_start[2] = (Z0 + Z1 + Z2) / 3;
+
+ // Covariance matrix s:
+ double s[3 * 3];
+ for(int j = 0; j < 3; j++) {
+ s[0 * 3 + j] = (X0 * M_end[0][j] + X1 * M_end[1][j] + X2 * M_end[2][j]) / 3 - C_end[j] * C_start[0];
+ s[1 * 3 + j] = (Y0 * M_end[0][j] + Y1 * M_end[1][j] + Y2 * M_end[2][j]) / 3 - C_end[j] * C_start[1];
+ s[2 * 3 + j] = (Z0 * M_end[0][j] + Z1 * M_end[1][j] + Z2 * M_end[2][j]) / 3 - C_end[j] * C_start[2];
+ }
+
+ double Qs[16], evs[4], U[16];
+
+ Qs[0 * 4 + 0] = s[0 * 3 + 0] + s[1 * 3 + 1] + s[2 * 3 + 2];
+ Qs[1 * 4 + 1] = s[0 * 3 + 0] - s[1 * 3 + 1] - s[2 * 3 + 2];
+ Qs[2 * 4 + 2] = s[1 * 3 + 1] - s[2 * 3 + 2] - s[0 * 3 + 0];
+ Qs[3 * 4 + 3] = s[2 * 3 + 2] - s[0 * 3 + 0] - s[1 * 3 + 1];
+
+ Qs[1 * 4 + 0] = Qs[0 * 4 + 1] = s[1 * 3 + 2] - s[2 * 3 + 1];
+ Qs[2 * 4 + 0] = Qs[0 * 4 + 2] = s[2 * 3 + 0] - s[0 * 3 + 2];
+ Qs[3 * 4 + 0] = Qs[0 * 4 + 3] = s[0 * 3 + 1] - s[1 * 3 + 0];
+ Qs[2 * 4 + 1] = Qs[1 * 4 + 2] = s[1 * 3 + 0] + s[0 * 3 + 1];
+ Qs[3 * 4 + 1] = Qs[1 * 4 + 3] = s[2 * 3 + 0] + s[0 * 3 + 2];
+ Qs[3 * 4 + 2] = Qs[2 * 4 + 3] = s[2 * 3 + 1] + s[1 * 3 + 2];
+
+ jacobi_4x4(Qs, evs, U);
+
+ // Looking for the largest eigen value:
+ int i_ev = 0;
+ double ev_max = evs[i_ev];
+ for(int i = 1; i < 4; i++)
+ if (evs[i] > ev_max)
+ ev_max = evs[i_ev = i];
+
+ // Quaternion:
+ double q[4];
+ for(int i = 0; i < 4; i++)
+ q[i] = U[i * 4 + i_ev];
+
+ double q02 = q[0] * q[0], q12 = q[1] * q[1], q22 = q[2] * q[2], q32 = q[3] * q[3];
+ double q0_1 = q[0] * q[1], q0_2 = q[0] * q[2], q0_3 = q[0] * q[3];
+ double q1_2 = q[1] * q[2], q1_3 = q[1] * q[3];
+ double q2_3 = q[2] * q[3];
+
+ R[0][0] = q02 + q12 - q22 - q32;
+ R[0][1] = 2. * (q1_2 - q0_3);
+ R[0][2] = 2. * (q1_3 + q0_2);
+
+ R[1][0] = 2. * (q1_2 + q0_3);
+ R[1][1] = q02 + q22 - q12 - q32;
+ R[1][2] = 2. * (q2_3 - q0_1);
+
+ R[2][0] = 2. * (q1_3 - q0_2);
+ R[2][1] = 2. * (q2_3 + q0_1);
+ R[2][2] = q02 + q32 - q12 - q22;
+
+ for(int i = 0; i < 3; i++)
+ T[i] = C_end[i] - (R[i][0] * C_start[0] + R[i][1] * C_start[1] + R[i][2] * C_start[2]);
+
+ return true;
}
bool p3p::jacobi_4x4(double * A, double * D, double * U)
{
- double B[4], Z[4];
- double Id[16] = {1., 0., 0., 0.,
- 0., 1., 0., 0.,
- 0., 0., 1., 0.,
- 0., 0., 0., 1.};
-
- memcpy(U, Id, 16 * sizeof(double));
-
- B[0] = A[0]; B[1] = A[5]; B[2] = A[10]; B[3] = A[15];
- memcpy(D, B, 4 * sizeof(double));
- memset(Z, 0, 4 * sizeof(double));
-
- for(int iter = 0; iter < 50; iter++) {
- double sum = fabs(A[1]) + fabs(A[2]) + fabs(A[3]) + fabs(A[6]) + fabs(A[7]) + fabs(A[11]);
-
- if (sum == 0.0)
- return true;
-
- double tresh = (iter < 3) ? 0.2 * sum / 16. : 0.0;
- for(int i = 0; i < 3; i++) {
- double * pAij = A + 5 * i + 1;
- for(int j = i + 1 ; j < 4; j++) {
- double Aij = *pAij;
- double eps_machine = 100.0 * fabs(Aij);
-
- if ( iter > 3 && fabs(D[i]) + eps_machine == fabs(D[i]) && fabs(D[j]) + eps_machine == fabs(D[j]) )
- *pAij = 0.0;
- else if (fabs(Aij) > tresh) {
- double h = D[j] - D[i], t;
- if (fabs(h) + eps_machine == fabs(h))
- t = Aij / h;
- else {
- double theta = 0.5 * h / Aij;
- t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
- if (theta < 0.0) t = -t;
- }
-
- h = t * Aij;
- Z[i] -= h;
- Z[j] += h;
- D[i] -= h;
- D[j] += h;
- *pAij = 0.0;
-
- double c = 1.0 / sqrt(1 + t * t);
- double s = t * c;
- double tau = s / (1.0 + c);
- for(int k = 0; k <= i - 1; k++) {
- double g = A[k * 4 + i], h = A[k * 4 + j];
- A[k * 4 + i] = g - s * (h + g * tau);
- A[k * 4 + j] = h + s * (g - h * tau);
- }
- for(int k = i + 1; k <= j - 1; k++) {
- double g = A[i * 4 + k], h = A[k * 4 + j];
- A[i * 4 + k] = g - s * (h + g * tau);
- A[k * 4 + j] = h + s * (g - h * tau);
- }
- for(int k = j + 1; k < 4; k++) {
- double g = A[i * 4 + k], h = A[j * 4 + k];
- A[i * 4 + k] = g - s * (h + g * tau);
- A[j * 4 + k] = h + s * (g - h * tau);
- }
- for(int k = 0; k < 4; k++) {
- double g = U[k * 4 + i], h = U[k * 4 + j];
- U[k * 4 + i] = g - s * (h + g * tau);
- U[k * 4 + j] = h + s * (g - h * tau);
- }
- }
- pAij++;
- }
- }
-
- for(int i = 0; i < 4; i++) B[i] += Z[i];
- memcpy(D, B, 4 * sizeof(double));
- memset(Z, 0, 4 * sizeof(double));
- }
-
- return false;
+ double B[4], Z[4];
+ double Id[16] = {1., 0., 0., 0.,
+ 0., 1., 0., 0.,
+ 0., 0., 1., 0.,
+ 0., 0., 0., 1.};
+
+ memcpy(U, Id, 16 * sizeof(double));
+
+ B[0] = A[0]; B[1] = A[5]; B[2] = A[10]; B[3] = A[15];
+ memcpy(D, B, 4 * sizeof(double));
+ memset(Z, 0, 4 * sizeof(double));
+
+ for(int iter = 0; iter < 50; iter++) {
+ double sum = fabs(A[1]) + fabs(A[2]) + fabs(A[3]) + fabs(A[6]) + fabs(A[7]) + fabs(A[11]);
+
+ if (sum == 0.0)
+ return true;
+
+ double tresh = (iter < 3) ? 0.2 * sum / 16. : 0.0;
+ for(int i = 0; i < 3; i++) {
+ double * pAij = A + 5 * i + 1;
+ for(int j = i + 1 ; j < 4; j++) {
+ double Aij = *pAij;
+ double eps_machine = 100.0 * fabs(Aij);
+
+ if ( iter > 3 && fabs(D[i]) + eps_machine == fabs(D[i]) && fabs(D[j]) + eps_machine == fabs(D[j]) )
+ *pAij = 0.0;
+ else if (fabs(Aij) > tresh) {
+ double hh = D[j] - D[i], t;
+ if (fabs(hh) + eps_machine == fabs(hh))
+ t = Aij / hh;
+ else {
+ double theta = 0.5 * hh / Aij;
+ t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
+ if (theta < 0.0) t = -t;
+ }
+
+ hh = t * Aij;
+ Z[i] -= hh;
+ Z[j] += hh;
+ D[i] -= hh;
+ D[j] += hh;
+ *pAij = 0.0;
+
+ double c = 1.0 / sqrt(1 + t * t);
+ double s = t * c;
+ double tau = s / (1.0 + c);
+ for(int k = 0; k <= i - 1; k++) {
+ double g = A[k * 4 + i], h = A[k * 4 + j];
+ A[k * 4 + i] = g - s * (h + g * tau);
+ A[k * 4 + j] = h + s * (g - h * tau);
+ }
+ for(int k = i + 1; k <= j - 1; k++) {
+ double g = A[i * 4 + k], h = A[k * 4 + j];
+ A[i * 4 + k] = g - s * (h + g * tau);
+ A[k * 4 + j] = h + s * (g - h * tau);
+ }
+ for(int k = j + 1; k < 4; k++) {
+ double g = A[i * 4 + k], h = A[j * 4 + k];
+ A[i * 4 + k] = g - s * (h + g * tau);
+ A[j * 4 + k] = h + s * (g - h * tau);
+ }
+ for(int k = 0; k < 4; k++) {
+ double g = U[k * 4 + i], h = U[k * 4 + j];
+ U[k * 4 + i] = g - s * (h + g * tau);
+ U[k * 4 + j] = h + s * (g - h * tau);
+ }
+ }
+ pAij++;
+ }
+ }
+
+ for(int i = 0; i < 4; i++) B[i] += Z[i];
+ memcpy(D, B, 4 * sizeof(double));
+ memset(Z, 0, 4 * sizeof(double));
+ }
+
+ return false;
}
}
}
}
- PnPSolver(const Mat& objectPoints, const Mat& imagePoints, const Parameters& parameters,
- Mat& rvec, Mat& tvec, vector<int>& inliers):
- objectPoints(objectPoints), imagePoints(imagePoints), parameters(parameters),
- rvec(rvec), tvec(tvec), inliers(inliers)
+ PnPSolver(const Mat& _objectPoints, const Mat& _imagePoints, const Parameters& _parameters,
+ Mat& _rvec, Mat& _tvec, vector<int>& _inliers):
+ objectPoints(_objectPoints), imagePoints(_imagePoints), parameters(_parameters),
+ rvec(_rvec), tvec(_tvec), inliers(_inliers)
{
rvec.copyTo(initRvec);
tvec.copyTo(initTvec);
val = ((curr[x]*4 + curr[x-1] + curr[x+1] + prev[x] + next[x])*scale_g - sum*scale_s) >> 10;
dptr[x] = tab[val + OFS];
}
-
+
sum += vsum[x+wsz2] - vsum[x-wsz2-1];
val = ((curr[x]*5 + curr[x-1] + prev[x] + next[x])*scale_g - sum*scale_s) >> 10;
dptr[x] = tab[val + OFS];
const int OFS = 256*4, TABSZ = OFS*2 + 256;
uchar tab[TABSZ];
Size size = src.size();
-
+
for( x = 0; x < TABSZ; x++ )
tab[x] = (uchar)(x - OFS < -ftzero ? 0 : x - OFS > ftzero ? ftzero*2 : x - OFS + ftzero);
uchar val0 = tab[0 + OFS];
-
+
#if CV_SSE2
volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
#endif
-
+
for( y = 0; y < size.height-1; y += 2 )
{
const uchar* srow1 = src.ptr<uchar>(y);
const uchar* srow3 = y < size.height-2 ? srow1 + src.step*2 : srow1;
uchar* dptr0 = dst.ptr<uchar>(y);
uchar* dptr1 = dptr0 + dst.step;
-
+
dptr0[0] = dptr0[size.width-1] = dptr1[0] = dptr1[size.width-1] = val0;
x = 1;
-
+
#if CV_SSE2
if( useSIMD )
{
d0 = _mm_sub_epi16(d0, c0);
d1 = _mm_sub_epi16(d1, c1);
-
+
__m128i c2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x - 1)), z);
__m128i c3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x - 1)), z);
__m128i d2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x + 1)), z);
__m128i d3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x + 1)), z);
-
+
d2 = _mm_sub_epi16(d2, c2);
d3 = _mm_sub_epi16(d3, c3);
-
+
__m128i v0 = _mm_add_epi16(d0, _mm_add_epi16(d2, _mm_add_epi16(d1, d1)));
__m128i v1 = _mm_add_epi16(d1, _mm_add_epi16(d3, _mm_add_epi16(d2, d2)));
v0 = _mm_packus_epi16(_mm_add_epi16(v0, ftz), _mm_add_epi16(v1, ftz));
v0 = _mm_min_epu8(v0, ftz2);
-
+
_mm_storel_epi64((__m128i*)(dptr0 + x), v0);
_mm_storel_epi64((__m128i*)(dptr1 + x), _mm_unpackhi_epi64(v0, v0));
}
}
#endif
-
+
for( ; x < size.width-1; x++ )
{
int d0 = srow0[x+1] - srow0[x-1], d1 = srow1[x+1] - srow1[x-1],
dptr1[x] = (uchar)v1;
}
}
-
+
for( ; y < size.height; y++ )
{
uchar* dptr = dst.ptr<uchar>(y);
short* costptr = cost.data ? (short*)cost.data + lofs + x : &costbuf;
int x0 = x - wsz2 - 1, x1 = x + wsz2;
const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
- uchar* cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
+ cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
hsad = hsad0 - dy0*ndisp;
lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep;
lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep;
// initialize sums
for( d = 0; d < ndisp; d++ )
sad[d] = (ushort)(hsad0[d-ndisp*dy0]*(wsz2 + 2 - dy0));
-
+
hsad = hsad0 + (1 - dy0)*ndisp;
for( y = 1 - dy0; y < wsz2; y++, hsad += ndisp )
for( d = 0; d < ndisp; d += 16 )
{
__m128i u0 = _mm_load_si128((__m128i*)(hsad_sub + d));
__m128i u1 = _mm_load_si128((__m128i*)(hsad + d));
-
+
__m128i v0 = _mm_load_si128((__m128i*)(hsad_sub + d + 8));
__m128i v1 = _mm_load_si128((__m128i*)(hsad + d + 8));
-
+
__m128i usad8 = _mm_load_si128((__m128i*)(sad + d));
__m128i vsad8 = _mm_load_si128((__m128i*)(sad + d + 8));
-
+
u1 = _mm_sub_epi16(u1, u0);
v1 = _mm_sub_epi16(v1, v0);
usad8 = _mm_add_epi16(usad8, u1);
vsad8 = _mm_add_epi16(vsad8, v1);
-
+
mask = _mm_cmpgt_epi16(minsad8, usad8);
minsad8 = _mm_min_epi16(minsad8, usad8);
mind8 = _mm_max_epi16(mind8, _mm_and_si128(mask, d8));
-
+
_mm_store_si128((__m128i*)(sad + d), usad8);
_mm_store_si128((__m128i*)(sad + d + 8), vsad8);
-
+
mask = _mm_cmpgt_epi16(minsad8, vsad8);
minsad8 = _mm_min_epi16(minsad8, vsad8);
-
+
d8 = _mm_add_epi16(d8, dd_8);
mind8 = _mm_max_epi16(mind8, _mm_and_si128(mask, d8));
d8 = _mm_add_epi16(d8, dd_8);
dptr[y*dstep] = FILTERED;
continue;
}
-
+
__m128i minsad82 = _mm_unpackhi_epi64(minsad8, minsad8);
__m128i mind82 = _mm_unpackhi_epi64(mind8, mind8);
mask = _mm_cmpgt_epi16(minsad8, minsad82);
mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask));
minsad8 = _mm_min_epi16(minsad8, minsad82);
-
+
minsad82 = _mm_shufflelo_epi16(minsad8, _MM_SHUFFLE(3,2,3,2));
mind82 = _mm_shufflelo_epi16(mind8, _MM_SHUFFLE(3,2,3,2));
mask = _mm_cmpgt_epi16(minsad8, minsad82);
mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask));
minsad8 = _mm_min_epi16(minsad8, minsad82);
-
+
minsad82 = _mm_shufflelo_epi16(minsad8, 1);
mind82 = _mm_shufflelo_epi16(mind8, 1);
mask = _mm_cmpgt_epi16(minsad8, minsad82);
mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask));
mind = (short)_mm_cvtsi128_si32(mind8);
minsad = sad[mind];
-
+
if( uniquenessRatio > 0 )
{
int thresh = minsad + ((minsad * uniquenessRatio) >> 8);
__m128i thresh8 = _mm_set1_epi16((short)(thresh + 1));
__m128i d1 = _mm_set1_epi16((short)(mind-1)), d2 = _mm_set1_epi16((short)(mind+1));
- __m128i dd_16 = _mm_add_epi16(dd_8, dd_8), d8 = _mm_sub_epi16(d0_8, dd_16);
+ __m128i dd_16 = _mm_add_epi16(dd_8, dd_8);
+ d8 = _mm_sub_epi16(d0_8, dd_16);
for( d = 0; d < ndisp; d += 16 )
{
if( 0 < mind && mind < ndisp - 1 )
{
- int p = sad[mind+1], n = sad[mind-1], d = p + n - 2*sad[mind] + std::abs(p - n);
+ int p = sad[mind+1], n = sad[mind-1];
+ d = p + n - 2*sad[mind] + std::abs(p - n);
dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*256/d : 0) + 15) >> 4);
}
else
htext[y] += tab[lval];
}
}
-
+
// initialize the left and right borders of the disparity map
for( y = 0; y < height; y++ )
{
int* costptr = cost.data ? (int*)cost.data + lofs + x : &costbuf;
int x0 = x - wsz2 - 1, x1 = x + wsz2;
const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
- uchar* cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
+ cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
hsad = hsad0 - dy0*ndisp;
lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep;
lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep;
// initialize sums
for( d = 0; d < ndisp; d++ )
sad[d] = (int)(hsad0[d-ndisp*dy0]*(wsz2 + 2 - dy0));
-
+
hsad = hsad0 + (1 - dy0)*ndisp;
for( y = 1 - dy0; y < wsz2; y++, hsad += ndisp )
for( d = 0; d < ndisp; d++ )
{
sad[-1] = sad[1];
sad[ndisp] = sad[ndisp-2];
- int p = sad[mind+1], n = sad[mind-1], d = p + n - 2*sad[mind] + std::abs(p - n);
+ int p = sad[mind+1], n = sad[mind-1];
+ d = p + n - 2*sad[mind] + std::abs(p - n);
dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*256/d : 0) + 15) >> 4);
costptr[y*coststep] = sad[mind];
}
state = _state;
}
- void operator()( int ind ) const
+ void operator()( int ind ) const
{
if( state->preFilterType == CV_STEREO_BM_NORMALIZED_RESPONSE )
prefilterNorm( *imgs0[ind], *imgs[ind], state->preFilterSize, state->preFilterCap, buf[ind] );
else
- prefilterXSobel( *imgs0[ind], *imgs[ind], state->preFilterCap );
+ prefilterXSobel( *imgs0[ind], *imgs[ind], state->preFilterCap );
}
-
+
const Mat* imgs0[2];
- Mat* imgs[2];
+ Mat* imgs[2];
uchar* buf[2];
CvStereoBMState *state;
};
useShorts = _useShorts;
validDisparityRect = _validDisparityRect;
}
-
- void operator()( const BlockedRange& range ) const
+
+ void operator()( const BlockedRange& range ) const
{
int cols = left->cols, rows = left->rows;
int _row0 = min(cvRound(range.begin() * rows / nstripes), rows);
int _row1 = min(cvRound(range.end() * rows / nstripes), rows);
uchar *ptr = state->slidingSumBuf->data.ptr + range.begin() * stripeBufSize;
int FILTERED = (state->minDisparity - 1)*16;
-
+
Rect roi = validDisparityRect & Rect(0, _row0, cols, _row1 - _row0);
if( roi.height == 0 )
return;
int row0 = roi.y;
int row1 = roi.y + roi.height;
-
+
Mat part;
if( row0 > _row0 )
{
part = disp->rowRange(row1, _row1);
part = Scalar::all(FILTERED);
}
-
+
Mat left_i = left->rowRange(row0, row1);
Mat right_i = right->rowRange(row0, row1);
Mat disp_i = disp->rowRange(row0, row1);
Mat cost_i = state->disp12MaxDiff >= 0 ? Mat(state->cost).rowRange(row0, row1) : Mat();
-
-#if CV_SSE2
+
+#if CV_SSE2
if( useShorts )
findStereoCorrespondenceBM_SSE2( left_i, right_i, disp_i, cost_i, *state, ptr, row0, rows - row1 );
else
-#endif
+#endif
findStereoCorrespondenceBM( left_i, right_i, disp_i, cost_i, *state, ptr, row0, rows - row1 );
-
+
if( state->disp12MaxDiff >= 0 )
validateDisparity( disp_i, cost_i, state->minDisparity, state->numberOfDisparities, state->disp12MaxDiff );
-
+
if( roi.x > 0 )
{
part = disp_i.colRange(0, roi.x);
const Mat *left, *right;
Mat* disp;
CvStereoBMState *state;
-
+
int nstripes;
int stripeBufSize;
bool useShorts;
};
static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat& disp0, CvStereoBMState* state)
-{
+{
if (left0.size() != right0.size() || disp0.size() != left0.size())
CV_Error( CV_StsUnmatchedSizes, "All the images must have the same size" );
CV_Error( CV_StsUnsupportedFormat, "Both input images must have CV_8UC1" );
if (disp0.type() != CV_16SC1 && disp0.type() != CV_32FC1)
- CV_Error( CV_StsUnsupportedFormat, "Disparity image must have CV_16SC1 or CV_32FC1 format" );
+ CV_Error( CV_StsUnsupportedFormat, "Disparity image must have CV_16SC1 or CV_32FC1 format" );
if( !state )
CV_Error( CV_StsNullPtr, "Stereo BM state is NULL." );
if( state->uniquenessRatio < 0 )
CV_Error( CV_StsOutOfRange, "uniqueness ratio must be non-negative" );
-
+
if( !state->preFilteredImg0 || state->preFilteredImg0->cols * state->preFilteredImg0->rows < left0.cols * left0.rows )
{
cvReleaseMat( &state->preFilteredImg0 );
}
Mat left(left0.size(), CV_8U, state->preFilteredImg0->data.ptr);
Mat right(right0.size(), CV_8U, state->preFilteredImg1->data.ptr);
-
+
int mindisp = state->minDisparity;
int ndisp = state->numberOfDisparities;
int rofs = -min(ndisp - 1 + mindisp, 0);
int width1 = width - rofs - ndisp + 1;
int FILTERED = (state->minDisparity - 1) << DISPARITY_SHIFT;
-
+
if( lofs >= width || rofs >= width || width1 < 1 )
{
- disp0 = Scalar::all( FILTERED * ( disp0.type() < CV_32F ? 1 : 1./(1 << DISPARITY_SHIFT) ) );
+ disp0 = Scalar::all( FILTERED * ( disp0.type() < CV_32F ? 1 : 1./(1 << DISPARITY_SHIFT) ) );
return;
}
Mat disp = disp0;
-
+
if( disp0.type() == CV_32F)
{
if( !state->disp || state->disp->rows != disp0.rows || state->disp->cols != disp0.cols )
}
disp = cv::cvarrToMat(state->disp);
}
-
- int wsz = state->SADWindowSize;
+
+ int wsz = state->SADWindowSize;
int bufSize0 = (int)((ndisp + 2)*sizeof(int));
bufSize0 += (int)((height+wsz+2)*ndisp*sizeof(int));
bufSize0 += (int)((height + wsz + 2)*sizeof(int));
int bufSize2 = 0;
if( state->speckleRange >= 0 && state->speckleWindowSize > 0 )
bufSize2 = width*height*(sizeof(cv::Point_<short>) + sizeof(int) + sizeof(uchar));
-
+
#if CV_SSE2
bool useShorts = state->preFilterCap <= 31 && state->SADWindowSize <= 21 && checkHardwareSupport(CV_CPU_SSE2);
#else
const bool useShorts = false;
#endif
-
-#ifdef HAVE_TBB
+
+#ifdef HAVE_TBB
const double SAD_overhead_coeff = 10.0;
- double N0 = 8000000 / (useShorts ? 1 : 4); // approx tbb's min number instructions reasonable for one thread
+ double N0 = 8000000 / (useShorts ? 1 : 4); // approx tbb's min number instructions reasonable for one thread
double maxStripeSize = min(max(N0 / (width * ndisp), (wsz-1) * SAD_overhead_coeff), (double)height);
int nstripes = cvCeil(height / maxStripeSize);
#else
#endif
int bufSize = max(bufSize0 * nstripes, max(bufSize1 * 2, bufSize2));
-
+
if( !state->slidingSumBuf || state->slidingSumBuf->cols < bufSize )
{
cvReleaseMat( &state->slidingSumBuf );
state->slidingSumBuf = cvCreateMat( 1, bufSize, CV_8U );
}
-
+
uchar *_buf = state->slidingSumBuf->data.ptr;
int idx[] = {0,1};
parallel_do(idx, idx+2, PrefilterInvoker(left0, right0, left, right, _buf, _buf + bufSize1, state));
-
+
Rect validDisparityRect(0, 0, width, height), R1 = state->roi1, R2 = state->roi2;
validDisparityRect = getValidDisparityROI(R1.area() > 0 ? Rect(0, 0, width, height) : validDisparityRect,
R2.area() > 0 ? Rect(0, 0, width, height) : validDisparityRect,
state->minDisparity, state->numberOfDisparities,
- state->SADWindowSize);
-
+ state->SADWindowSize);
+
parallel_for(BlockedRange(0, nstripes),
FindStereoCorrespInvoker(left, right, disp, state, nstripes,
bufSize0, useShorts, validDisparityRect));
-
+
if( state->speckleRange >= 0 && state->speckleWindowSize > 0 )
{
Mat buf(state->slidingSumBuf);
}
if (disp0.data != disp.data)
- disp.convertTo(disp0, disp0.type(), 1./(1 << DISPARITY_SHIFT), 0);
+ disp.convertTo(disp0, disp0.type(), 1./(1 << DISPARITY_SHIFT), 0);
}
StereoBM::StereoBM()
CV_Assert( disptype == CV_16S || disptype == CV_32F );
_disparity.create(left.size(), disptype);
Mat disparity = _disparity.getMat();
-
+
findStereoCorrespondenceBM(left, right, disparity, state);
}
template<> void Ptr<CvStereoBMState>::delete_obj()
{ cvReleaseStereoBMState(&obj); }
-
+
}
CV_IMPL void cvFindStereoCorrespondenceBM( const CvArr* leftarr, const CvArr* rightarr,
{
cv::Mat left = cv::cvarrToMat(leftarr),
right = cv::cvarrToMat(rightarr),
- disp = cv::cvarrToMat(disparr);
+ disp = cv::cvarrToMat(disparr);
cv::findStereoCorrespondenceBM(left, right, disp, state);
}
This is a variation of
"Stereo Processing by Semiglobal Matching and Mutual Information"
by Heiko Hirschmuller.
-
+
We match blocks rather than individual pixels, thus the algorithm is called
SGBM (Semi-global block matching)
- */
+ */
#include "precomp.hpp"
#include <limits.h>
namespace cv
{
-
+
typedef uchar PixType;
typedef short CostType;
typedef short DispType;
row1[x] and row2[x-d]. The subpixel algorithm from
"Depth Discontinuities by Pixel-to-Pixel Stereo" by Stan Birchfield and C. Tomasi
is used, hence the suffix BT.
-
+
the temporary buffer should contain width2*2 elements
*/
static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
int D = maxD - minD, width1 = maxX1 - minX1, width2 = maxX2 - minX2;
const PixType *row1 = img1.ptr<PixType>(y), *row2 = img2.ptr<PixType>(y);
PixType *prow1 = buffer + width2*2, *prow2 = prow1 + width*cn*2;
-
+
tab += tabOfs;
-
+
for( c = 0; c < cn*2; c++ )
{
- prow1[width*c] = prow1[width*c + width-1] =
+ prow1[width*c] = prow1[width*c + width-1] =
prow2[width*c] = prow2[width*c + width-1] = tab[0];
}
-
+
int n1 = y > 0 ? -(int)img1.step : 0, s1 = y < img1.rows-1 ? (int)img1.step : 0;
int n2 = y > 0 ? -(int)img2.step : 0, s2 = y < img2.rows-1 ? (int)img2.step : 0;
-
+
if( cn == 1 )
{
for( x = 1; x < width-1; x++ )
{
prow1[x] = tab[(row1[x+1] - row1[x-1])*2 + row1[x+n1+1] - row1[x+n1-1] + row1[x+s1+1] - row1[x+s1-1]];
prow2[width-1-x] = tab[(row2[x+1] - row2[x-1])*2 + row2[x+n2+1] - row2[x+n2-1] + row2[x+s2+1] - row2[x+s2-1]];
-
+
prow1[x+width] = row1[x];
prow2[width-1-x+width] = row2[x];
}
prow1[x] = tab[(row1[x*3+3] - row1[x*3-3])*2 + row1[x*3+n1+3] - row1[x*3+n1-3] + row1[x*3+s1+3] - row1[x*3+s1-3]];
prow1[x+width] = tab[(row1[x*3+4] - row1[x*3-2])*2 + row1[x*3+n1+4] - row1[x*3+n1-2] + row1[x*3+s1+4] - row1[x*3+s1-2]];
prow1[x+width*2] = tab[(row1[x*3+5] - row1[x*3-1])*2 + row1[x*3+n1+5] - row1[x*3+n1-1] + row1[x*3+s1+5] - row1[x*3+s1-1]];
-
+
prow2[width-1-x] = tab[(row2[x*3+3] - row2[x*3-3])*2 + row2[x*3+n2+3] - row2[x*3+n2-3] + row2[x*3+s2+3] - row2[x*3+s2-3]];
prow2[width-1-x+width] = tab[(row2[x*3+4] - row2[x*3-2])*2 + row2[x*3+n2+4] - row2[x*3+n2-2] + row2[x*3+s2+4] - row2[x*3+s2-2]];
prow2[width-1-x+width*2] = tab[(row2[x*3+5] - row2[x*3-1])*2 + row2[x*3+n2+5] - row2[x*3+n2-1] + row2[x*3+s2+5] - row2[x*3+s2-1]];
-
+
prow1[x+width*3] = row1[x*3];
prow1[x+width*4] = row1[x*3+1];
prow1[x+width*5] = row1[x*3+2];
-
+
prow2[width-1-x+width*3] = row2[x*3];
prow2[width-1-x+width*4] = row2[x*3+1];
prow2[width-1-x+width*5] = row2[x*3+2];
}
}
-
+
memset( cost, 0, width1*D*sizeof(cost[0]) );
-
+
buffer -= minX2;
cost -= minX1*D + minD; // simplify the cost indices inside the loop
-
-#if CV_SSE2
+
+#if CV_SSE2
volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
#endif
-
-#if 1
+
+#if 1
for( c = 0; c < cn*2; c++, prow1 += width, prow2 += width )
{
int diff_scale = c < cn ? 0 : 2;
-
+
// precompute
// v0 = min(row2[x-1/2], row2[x], row2[x+1/2]) and
// v1 = max(row2[x-1/2], row2[x], row2[x+1/2]) and
buffer[x] = (PixType)v0;
buffer[x + width2] = (PixType)v1;
}
-
+
for( x = minX1; x < maxX1; x++ )
{
int u = prow1[x];
int ur = x < width-1 ? (u + prow1[x+1])/2 : u;
int u0 = min(ul, ur); u0 = min(u0, u);
int u1 = max(ul, ur); u1 = max(u1, u);
-
+
#if CV_SSE2
if( useSIMD )
{
__m128i _u = _mm_set1_epi8((char)u), _u0 = _mm_set1_epi8((char)u0);
__m128i _u1 = _mm_set1_epi8((char)u1), z = _mm_setzero_si128();
__m128i ds = _mm_cvtsi32_si128(diff_scale);
-
+
for( int d = minD; d < maxD; d += 16 )
{
__m128i _v = _mm_loadu_si128((const __m128i*)(prow2 + width-x-1 + d));
__m128i c0 = _mm_max_epu8(_mm_subs_epu8(_u, _v1), _mm_subs_epu8(_v0, _u));
__m128i c1 = _mm_max_epu8(_mm_subs_epu8(_v, _u1), _mm_subs_epu8(_u0, _v));
__m128i diff = _mm_min_epu8(c0, c1);
-
+
c0 = _mm_load_si128((__m128i*)(cost + x*D + d));
c1 = _mm_load_si128((__m128i*)(cost + x*D + d + 8));
-
+
_mm_store_si128((__m128i*)(cost + x*D + d), _mm_adds_epi16(c0, _mm_srl_epi16(_mm_unpacklo_epi8(diff,z), ds)));
_mm_store_si128((__m128i*)(cost + x*D + d + 8), _mm_adds_epi16(c1, _mm_srl_epi16(_mm_unpackhi_epi8(diff,z), ds)));
}
int v1 = buffer[width-x-1 + d + width2];
int c0 = max(0, u - v1); c0 = max(c0, v0 - u);
int c1 = max(0, v - u1); c1 = max(c1, u0 - v);
-
+
cost[x*D + d] = (CostType)(cost[x*D+d] + (min(c0, c1) >> diff_scale));
}
}
if( useSIMD )
{
__m128i _u = _mm_set1_epi8(u), z = _mm_setzero_si128();
-
+
for( int d = minD; d < maxD; d += 16 )
{
__m128i _v = _mm_loadu_si128((const __m128i*)(prow2 + width-1-x + d));
__m128i diff = _mm_adds_epu8(_mm_subs_epu8(_u,_v), _mm_subs_epu8(_v,_u));
__m128i c0 = _mm_load_si128((__m128i*)(cost + x*D + d));
__m128i c1 = _mm_load_si128((__m128i*)(cost + x*D + d + 8));
-
+
_mm_store_si128((__m128i*)(cost + x*D + d), _mm_adds_epi16(c0, _mm_unpacklo_epi8(diff,z)));
_mm_store_si128((__m128i*)(cost + x*D + d + 8), _mm_adds_epi16(c1, _mm_unpackhi_epi8(diff,z)));
}
minD <= d < maxD.
disp2full is the reverse disparity map, that is:
disp2full(x+roi.x,y+roi.y)=d means that img2(x+roi.x, y+roi.y) ~ img1(x+roi.x+d, y+roi.y)
-
+
note that disp1buf will have the same size as the roi and
disp2full will have the same size as img1 (or img2).
On exit disp2buf is not the final disparity, it is an intermediate result that becomes
final after all the tiles are processed.
-
+
the disparity in disp1buf is written with sub-pixel accuracy
(4 fractional bits, see CvStereoSGBM::DISP_SCALE),
using quadratic interpolation, while the disparity in disp2buf
is written as is, without interpolation.
-
+
disp2cost also has the same size as img1 (or img2).
It contains the minimum current cost, used to find the best disparity, corresponding to the minimal cost.
- */
+ */
static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
- Mat& disp1, const StereoSGBM& params,
+ Mat& disp1, const StereoSGBM& params,
Mat& buffer )
{
#if CV_SSE2
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
-
+
volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
-#endif
-
+#endif
+
const int ALIGN = 16;
const int DISP_SHIFT = StereoSGBM::DISP_SHIFT;
const int DISP_SCALE = StereoSGBM::DISP_SCALE;
const CostType MAX_COST = SHRT_MAX;
-
+
int minD = params.minDisparity, maxD = minD + params.numberOfDisparities;
Size SADWindowSize;
SADWindowSize.width = SADWindowSize.height = params.SADWindowSize > 0 ? params.SADWindowSize : 5;
int npasses = params.fullDP ? 2 : 1;
const int TAB_OFS = 256*4, TAB_SIZE = 256 + TAB_OFS*2;
PixType clipTab[TAB_SIZE];
-
+
for( k = 0; k < TAB_SIZE; k++ )
clipTab[k] = (PixType)(min(max(k - TAB_OFS, -ftzero), ftzero) + ftzero);
-
+
if( minX1 >= maxX1 )
{
disp1 = Scalar::all(INVALID_DISP_SCALED);
return;
}
-
+
CV_Assert( D % 16 == 0 );
-
+
// NR - the number of directions. the loop on x below that computes Lr assumes that NR == 8.
// if you change NR, please, modify the loop as well.
int D2 = D+16, NRD2 = NR2*D2;
-
+
// the number of L_r(.,.) and min_k L_r(.,.) lines in the buffer:
// for 8-way dynamic programming we need the current row and
// the previous row, i.e. 2 rows in total
const int NLR = 2;
const int LrBorder = NLR - 1;
-
+
// for each possible stereo match (img1(x,y) <=> img2(x-d,y))
// we keep pixel difference cost (C) and the summary cost over NR directions (S).
// we also keep all the partial costs for the previous line L_r(x,d) and also min_k L_r(x, k)
CSBufSize*2*sizeof(CostType) + // C, S
width*16*img1.channels()*sizeof(PixType) + // temp buffer for computing per-pixel cost
width*(sizeof(CostType) + sizeof(DispType)) + 1024; // disp2cost + disp2
-
+
if( !buffer.data || !buffer.isContinuous() ||
buffer.cols*buffer.rows*buffer.elemSize() < totalBufSize )
buffer.create(1, (int)totalBufSize, CV_8U);
-
+
// summary cost over different (nDirs) directions
CostType* Cbuf = (CostType*)alignPtr(buffer.data, ALIGN);
CostType* Sbuf = Cbuf + CSBufSize;
CostType* hsumBuf = Sbuf + CSBufSize;
CostType* pixDiff = hsumBuf + costBufSize*hsumBufNRows;
-
+
CostType* disp2cost = pixDiff + costBufSize + (LrSize + minLrSize)*NLR;
DispType* disp2ptr = (DispType*)(disp2cost + width);
PixType* tempBuf = (PixType*)(disp2ptr + width);
-
+
// add P2 to every C(x,y). it saves a few operations in the inner loops
for( k = 0; k < width1*D; k++ )
Cbuf[k] = (CostType)P2;
-
+
for( int pass = 1; pass <= npasses; pass++ )
{
int x1, y1, x2, y2, dx, dy;
-
+
if( pass == 1 )
{
y1 = 0; y2 = height; dy = 1;
y1 = height-1; y2 = -1; dy = -1;
x1 = width1-1; x2 = -1; dx = -1;
}
-
+
CostType *Lr[NLR]={0}, *minLr[NLR]={0};
-
+
for( k = 0; k < NLR; k++ )
{
// shift Lr[k] and minLr[k] pointers, because we allocated them with the borders,
minLr[k] = pixDiff + costBufSize + LrSize*NLR + minLrSize*k + NR2*2;
memset( minLr[k] - LrBorder*NR2, 0, minLrSize*sizeof(CostType) );
}
-
+
for( int y = y1; y != y2; y += dy )
{
int x, d;
DispType* disp1ptr = disp1.ptr<DispType>(y);
CostType* C = Cbuf + (!params.fullDP ? 0 : y*costBufSize);
CostType* S = Sbuf + (!params.fullDP ? 0 : y*costBufSize);
-
+
if( pass == 1 ) // compute C on the first pass, and reuse it on the second pass, if any.
{
int dy1 = y == 0 ? 0 : y + SH2, dy2 = y == 0 ? SH2 : dy1;
-
+
for( k = dy1; k <= dy2; k++ )
{
CostType* hsumAdd = hsumBuf + (min(k, height-1) % hsumBufNRows)*costBufSize;
-
+
if( k < height )
{
calcPixelCostBT( img1, img2, k, minD, maxD, pixDiff, tempBuf, clipTab, TAB_OFS, ftzero );
-
+
memset(hsumAdd, 0, D*sizeof(CostType));
for( x = 0; x <= SW2*D; x += D )
{
for( d = 0; d < D; d++ )
hsumAdd[d] = (CostType)(hsumAdd[d] + pixDiff[x + d]*scale);
}
-
+
if( y > 0 )
{
const CostType* hsumSub = hsumBuf + (max(y - SH2 - 1, 0) % hsumBufNRows)*costBufSize;
const CostType* Cprev = !params.fullDP || y == 0 ? C : C - costBufSize;
-
+
for( x = D; x < width1*D; x += D )
{
const CostType* pixAdd = pixDiff + min(x + SW2*D, (width1-1)*D);
const CostType* pixSub = pixDiff + max(x - (SW2+1)*D, 0);
-
+
#if CV_SSE2
if( useSIMD )
{
{
const CostType* pixAdd = pixDiff + min(x + SW2*D, (width1-1)*D);
const CostType* pixSub = pixDiff + max(x - (SW2+1)*D, 0);
-
+
for( d = 0; d < D; d++ )
hsumAdd[x + d] = (CostType)(hsumAdd[x - D + d] + pixAdd[d] - pixSub[d]);
}
}
}
-
+
if( y == 0 )
{
int scale = k == 0 ? SH2 + 1 : 1;
C[x] = (CostType)(C[x] + hsumAdd[x]*scale);
}
}
-
+
// also, clear the S buffer
for( k = 0; k < width1*D; k++ )
S[k] = 0;
}
-
+
// clear the left and the right borders
memset( Lr[0] - NRD2*LrBorder - 8, 0, NRD2*LrBorder*sizeof(CostType) );
memset( Lr[0] + width1*NRD2 - 8, 0, NRD2*LrBorder*sizeof(CostType) );
memset( minLr[0] - NR2*LrBorder, 0, NR2*LrBorder*sizeof(CostType) );
memset( minLr[0] + width1*NR2, 0, NR2*LrBorder*sizeof(CostType) );
-
+
/*
[formula 13 in the paper]
compute L_r(p, d) = C(p, d) +
for( x = x1; x != x2; x += dx )
{
int xm = x*NR2, xd = xm*D2;
-
+
int delta0 = minLr[0][xm - dx*NR2] + P2, delta1 = minLr[1][xm - NR2 + 1] + P2;
int delta2 = minLr[1][xm + 2] + P2, delta3 = minLr[1][xm + NR2 + 3] + P2;
-
+
CostType* Lr_p0 = Lr[0] + xd - dx*NRD2;
CostType* Lr_p1 = Lr[1] + xd - NRD2 + D2;
CostType* Lr_p2 = Lr[1] + xd + D2*2;
CostType* Lr_p3 = Lr[1] + xd + NRD2 + D2*3;
-
+
Lr_p0[-1] = Lr_p0[D] = Lr_p1[-1] = Lr_p1[D] =
Lr_p2[-1] = Lr_p2[D] = Lr_p3[-1] = Lr_p3[D] = MAX_COST;
-
+
CostType* Lr_p = Lr[0] + xd;
const CostType* Cp = C + x*D;
CostType* Sp = S + x*D;
-
+
#if CV_SSE2
if( useSIMD )
{
__m128i _P1 = _mm_set1_epi16((short)P1);
-
+
__m128i _delta0 = _mm_set1_epi16((short)delta0);
__m128i _delta1 = _mm_set1_epi16((short)delta1);
__m128i _delta2 = _mm_set1_epi16((short)delta2);
__m128i _delta3 = _mm_set1_epi16((short)delta3);
__m128i _minL0 = _mm_set1_epi16((short)MAX_COST);
-
+
for( d = 0; d < D; d += 8 )
{
__m128i Cpd = _mm_load_si128((const __m128i*)(Cp + d));
__m128i L0, L1, L2, L3;
-
+
L0 = _mm_load_si128((const __m128i*)(Lr_p0 + d));
L1 = _mm_load_si128((const __m128i*)(Lr_p1 + d));
L2 = _mm_load_si128((const __m128i*)(Lr_p2 + d));
L3 = _mm_load_si128((const __m128i*)(Lr_p3 + d));
-
+
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d - 1)), _P1));
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d + 1)), _P1));
-
+
L1 = _mm_min_epi16(L1, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p1 + d - 1)), _P1));
L1 = _mm_min_epi16(L1, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p1 + d + 1)), _P1));
-
+
L2 = _mm_min_epi16(L2, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p2 + d - 1)), _P1));
L2 = _mm_min_epi16(L2, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p2 + d + 1)), _P1));
-
+
L3 = _mm_min_epi16(L3, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p3 + d - 1)), _P1));
L3 = _mm_min_epi16(L3, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p3 + d + 1)), _P1));
-
+
L0 = _mm_min_epi16(L0, _delta0);
L0 = _mm_adds_epi16(_mm_subs_epi16(L0, _delta0), Cpd);
-
+
L1 = _mm_min_epi16(L1, _delta1);
L1 = _mm_adds_epi16(_mm_subs_epi16(L1, _delta1), Cpd);
-
+
L2 = _mm_min_epi16(L2, _delta2);
L2 = _mm_adds_epi16(_mm_subs_epi16(L2, _delta2), Cpd);
-
+
L3 = _mm_min_epi16(L3, _delta3);
L3 = _mm_adds_epi16(_mm_subs_epi16(L3, _delta3), Cpd);
-
+
_mm_store_si128( (__m128i*)(Lr_p + d), L0);
_mm_store_si128( (__m128i*)(Lr_p + d + D2), L1);
_mm_store_si128( (__m128i*)(Lr_p + d + D2*2), L2);
_mm_store_si128( (__m128i*)(Lr_p + d + D2*3), L3);
-
+
__m128i t0 = _mm_min_epi16(_mm_unpacklo_epi16(L0, L2), _mm_unpackhi_epi16(L0, L2));
__m128i t1 = _mm_min_epi16(_mm_unpacklo_epi16(L1, L3), _mm_unpackhi_epi16(L1, L3));
t0 = _mm_min_epi16(_mm_unpacklo_epi16(t0, t1), _mm_unpackhi_epi16(t0, t1));
_minL0 = _mm_min_epi16(_minL0, t0);
-
+
__m128i Sval = _mm_load_si128((const __m128i*)(Sp + d));
-
+
L0 = _mm_adds_epi16(L0, L1);
L2 = _mm_adds_epi16(L2, L3);
Sval = _mm_adds_epi16(Sval, L0);
Sval = _mm_adds_epi16(Sval, L2);
-
+
_mm_store_si128((__m128i*)(Sp + d), Sval);
}
-
+
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 8));
_mm_storel_epi64((__m128i*)&minLr[0][xm], _minL0);
}
#endif
{
int minL0 = MAX_COST, minL1 = MAX_COST, minL2 = MAX_COST, minL3 = MAX_COST;
-
+
for( d = 0; d < D; d++ )
{
int Cpd = Cp[d], L0, L1, L2, L3;
-
+
L0 = Cpd + min((int)Lr_p0[d], min(Lr_p0[d-1] + P1, min(Lr_p0[d+1] + P1, delta0))) - delta0;
- L1 = Cpd + min((int)Lr_p1[d], min(Lr_p1[d-1] + P1, min(Lr_p1[d+1] + P1, delta1))) - delta1;
+ L1 = Cpd + min((int)Lr_p1[d], min(Lr_p1[d-1] + P1, min(Lr_p1[d+1] + P1, delta1))) - delta1;
L2 = Cpd + min((int)Lr_p2[d], min(Lr_p2[d-1] + P1, min(Lr_p2[d+1] + P1, delta2))) - delta2;
L3 = Cpd + min((int)Lr_p3[d], min(Lr_p3[d-1] + P1, min(Lr_p3[d+1] + P1, delta3))) - delta3;
-
+
Lr_p[d] = (CostType)L0;
minL0 = min(minL0, L0);
-
+
Lr_p[d + D2] = (CostType)L1;
minL1 = min(minL1, L1);
-
+
Lr_p[d + D2*2] = (CostType)L2;
minL2 = min(minL2, L2);
-
+
Lr_p[d + D2*3] = (CostType)L3;
minL3 = min(minL3, L3);
-
+
Sp[d] = saturate_cast<CostType>(Sp[d] + L0 + L1 + L2 + L3);
}
minLr[0][xm] = (CostType)minL0;
minLr[0][xm+3] = (CostType)minL3;
}
}
-
+
if( pass == npasses )
{
for( x = 0; x < width; x++ )
disp1ptr[x] = disp2ptr[x] = (DispType)INVALID_DISP_SCALED;
disp2cost[x] = MAX_COST;
}
-
+
for( x = width1 - 1; x >= 0; x-- )
{
CostType* Sp = S + x*D;
int minS = MAX_COST, bestDisp = -1;
-
+
if( npasses == 1 )
{
int xm = x*NR2, xd = xm*D2;
-
+
int minL0 = MAX_COST;
int delta0 = minLr[0][xm + NR2] + P2;
CostType* Lr_p0 = Lr[0] + xd + NRD2;
Lr_p0[-1] = Lr_p0[D] = MAX_COST;
CostType* Lr_p = Lr[0] + xd;
-
+
const CostType* Cp = C + x*D;
-
+
#if CV_SSE2
if( useSIMD )
{
__m128i _P1 = _mm_set1_epi16((short)P1);
__m128i _delta0 = _mm_set1_epi16((short)delta0);
-
+
__m128i _minL0 = _mm_set1_epi16((short)minL0);
__m128i _minS = _mm_set1_epi16(MAX_COST), _bestDisp = _mm_set1_epi16(-1);
__m128i _d8 = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7), _8 = _mm_set1_epi16(8);
-
+
for( d = 0; d < D; d += 8 )
{
__m128i Cpd = _mm_load_si128((const __m128i*)(Cp + d)), L0;
-
+
L0 = _mm_load_si128((const __m128i*)(Lr_p0 + d));
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d - 1)), _P1));
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d + 1)), _P1));
L0 = _mm_min_epi16(L0, _delta0);
L0 = _mm_adds_epi16(_mm_subs_epi16(L0, _delta0), Cpd);
-
+
_mm_store_si128((__m128i*)(Lr_p + d), L0);
_minL0 = _mm_min_epi16(_minL0, L0);
L0 = _mm_adds_epi16(L0, *(__m128i*)(Sp + d));
_mm_store_si128((__m128i*)(Sp + d), L0);
-
+
__m128i mask = _mm_cmpgt_epi16(_minS, L0);
_minS = _mm_min_epi16(_minS, L0);
_bestDisp = _mm_xor_si128(_bestDisp, _mm_and_si128(_mm_xor_si128(_bestDisp,_d8), mask));
_d8 = _mm_adds_epi16(_d8, _8);
}
-
+
short CV_DECL_ALIGNED(16) bestDispBuf[8];
_mm_store_si128((__m128i*)bestDispBuf, _bestDisp);
-
+
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 8));
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 4));
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 2));
-
+
__m128i qS = _mm_min_epi16(_minS, _mm_srli_si128(_minS, 8));
qS = _mm_min_epi16(qS, _mm_srli_si128(qS, 4));
qS = _mm_min_epi16(qS, _mm_srli_si128(qS, 2));
-
+
minLr[0][xm] = (CostType)_mm_cvtsi128_si32(_minL0);
minS = (CostType)_mm_cvtsi128_si32(qS);
-
+
qS = _mm_shuffle_epi32(_mm_unpacklo_epi16(qS, qS), 0);
qS = _mm_cmpeq_epi16(_minS, qS);
int idx = _mm_movemask_epi8(_mm_packs_epi16(qS, qS)) & 255;
-
+
bestDisp = bestDispBuf[LSBTab[idx]];
}
else
for( d = 0; d < D; d++ )
{
int L0 = Cp[d] + min((int)Lr_p0[d], min(Lr_p0[d-1] + P1, min(Lr_p0[d+1] + P1, delta0))) - delta0;
-
+
Lr_p[d] = (CostType)L0;
minL0 = min(minL0, L0);
-
+
int Sval = Sp[d] = saturate_cast<CostType>(Sp[d] + L0);
if( Sval < minS )
{
}
}
}
-
+
for( d = 0; d < D; d++ )
{
if( Sp[d]*(100 - uniquenessRatio) < minS*100 && std::abs(bestDisp - d) > 1 )
if( d < D )
continue;
d = bestDisp;
- int x2 = x + minX1 - d - minD;
- if( disp2cost[x2] > minS )
+ int _x2 = x + minX1 - d - minD;
+ if( disp2cost[_x2] > minS )
{
- disp2cost[x2] = (CostType)minS;
- disp2ptr[x2] = (DispType)(d + minD);
+ disp2cost[_x2] = (CostType)minS;
+ disp2ptr[_x2] = (DispType)(d + minD);
}
-
+
if( 0 < d && d < D-1 )
{
// do subpixel quadratic interpolation:
d *= DISP_SCALE;
disp1ptr[x + minX1] = (DispType)(d + minD*DISP_SCALE);
}
-
+
for( x = minX1; x < maxX1; x++ )
{
// we round the computed disparity both towards -inf and +inf and check
// if either of the corresponding disparities in disp2 is consistent.
// This is to give the computed disparity a chance to look valid if it is.
- int d = disp1ptr[x];
- if( d == INVALID_DISP_SCALED )
+ int d1 = disp1ptr[x];
+ if( d1 == INVALID_DISP_SCALED )
continue;
- int _d = d >> DISP_SHIFT;
- int d_ = (d + DISP_SCALE-1) >> DISP_SHIFT;
+ int _d = d1 >> DISP_SHIFT;
+ int d_ = (d1 + DISP_SCALE-1) >> DISP_SHIFT;
int _x = x - _d, x_ = x - d_;
if( 0 <= _x && _x < width && disp2ptr[_x] >= minD && std::abs(disp2ptr[_x] - _d) > disp12MaxDiff &&
0 <= x_ && x_ < width && disp2ptr[x_] >= minD && std::abs(disp2ptr[x_] - d_) > disp12MaxDiff )
disp1ptr[x] = (DispType)INVALID_DISP_SCALED;
}
}
-
+
// now shift the cyclic buffers
std::swap( Lr[0], Lr[1] );
std::swap( minLr[0], minLr[1] );
Mat left = _left.getMat(), right = _right.getMat();
CV_Assert( left.size() == right.size() && left.type() == right.type() &&
left.depth() == DataType<PixType>::depth );
-
+
_disp.create( left.size(), CV_16S );
Mat disp = _disp.getMat();
-
+
computeDisparitySGBM( left, right, disp, *this, buffer );
medianBlur(disp, disp, 3);
-
+
if( speckleWindowSize > 0 )
filterSpeckles(disp, (minDisparity - 1)*DISP_SCALE, speckleWindowSize, DISP_SCALE*speckleRange, buffer);
}
{
int SW2 = SADWindowSize/2;
int minD = minDisparity, maxD = minDisparity + numberOfDisparities - 1;
-
+
int xmin = max(roi1.x, roi2.x + maxD) + SW2;
int xmax = min(roi1.x + roi1.width, roi2.x + roi2.width - minD) - SW2;
int ymin = max(roi1.y, roi2.y) + SW2;
int ymax = min(roi1.y + roi1.height, roi2.y + roi2.height) - SW2;
-
+
Rect r(xmin, ymin, xmax - xmin, ymax - ymin);
-
+
return r.width > 0 && r.height > 0 ? r : Rect();
-}
-
}
-
+
+}
+
void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSize,
double _maxDiff, InputOutputArray __buf )
{
Mat img = _img.getMat();
Mat temp, &_buf = __buf.needed() ? __buf.getMatRef() : temp;
CV_Assert( img.type() == CV_16SC1 );
-
+
int newVal = cvRound(_newval);
int maxDiff = cvRound(_maxDiff);
int width = img.cols, height = img.rows, npixels = width*height;
size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar));
if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize )
_buf.create(1, (int)bufSize, CV_8U);
-
+
uchar* buf = _buf.data;
int i, j, dstep = (int)(img.step/sizeof(short));
int* labels = (int*)buf;
buf += npixels*sizeof(wbuf[0]);
uchar* rtype = (uchar*)buf;
int curlabel = 0;
-
+
// clear out label assignments
memset(labels, 0, npixels*sizeof(labels[0]));
-
+
for( i = 0; i < height; i++ )
{
short* ds = img.ptr<short>(i);
int* ls = labels + width*i;
-
+
for( j = 0; j < width; j++ )
{
- if( ds[j] != newVal ) // not a bad disparity
+ if( ds[j] != newVal ) // not a bad disparity
{
- if( ls[j] ) // has a label, check for bad label
- {
+ if( ls[j] ) // has a label, check for bad label
+ {
if( rtype[ls[j]] ) // small region, zero out disparity
ds[j] = (short)newVal;
}
// no label, assign and propagate
else
{
- Point2s* ws = wbuf; // initialize wavefront
- Point2s p((short)j, (short)i); // current pixel
- curlabel++; // next label
- int count = 0; // current region size
+ Point2s* ws = wbuf; // initialize wavefront
+ Point2s p((short)j, (short)i); // current pixel
+ curlabel++; // next label
+ int count = 0; // current region size
ls[j] = curlabel;
-
+
// wavefront propagation
while( ws >= wbuf ) // wavefront not empty
{
short* dpp = &img.at<short>(p.y, p.x);
short dp = *dpp;
int* lpp = labels + width*p.y + p.x;
-
+
if( p.x < width-1 && !lpp[+1] && dpp[+1] != newVal && std::abs(dp - dpp[+1]) <= maxDiff )
{
lpp[+1] = curlabel;
*ws++ = Point2s(p.x+1, p.y);
}
-
+
if( p.x > 0 && !lpp[-1] && dpp[-1] != newVal && std::abs(dp - dpp[-1]) <= maxDiff )
{
lpp[-1] = curlabel;
*ws++ = Point2s(p.x-1, p.y);
}
-
+
if( p.y < height-1 && !lpp[+width] && dpp[+dstep] != newVal && std::abs(dp - dpp[+dstep]) <= maxDiff )
{
lpp[+width] = curlabel;
*ws++ = Point2s(p.x, p.y+1);
}
-
+
if( p.y > 0 && !lpp[-width] && dpp[-dstep] != newVal && std::abs(dp - dpp[-dstep]) <= maxDiff )
{
lpp[-width] = curlabel;
*ws++ = Point2s(p.x, p.y-1);
}
-
+
// pop most recent and propagate
// NB: could try least recent, maybe better convergence
p = *--ws;
}
-
+
// assign label type
- if( count <= maxSpeckleSize ) // speckle region
+ if( count <= maxSpeckleSize ) // speckle region
{
- rtype[ls[j]] = 1; // small region label
+ rtype[ls[j]] = 1; // small region label
ds[j] = (short)newVal;
}
else
- rtype[ls[j]] = 0; // large region label
+ rtype[ls[j]] = 0; // large region label
}
}
}
}
-}
-
+}
+
void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDisparity,
int numberOfDisparities, int disp12MaxDiff )
{
const int DISP_SHIFT = 4, DISP_SCALE = 1 << DISP_SHIFT;
int INVALID_DISP = minD - 1, INVALID_DISP_SCALED = INVALID_DISP*DISP_SCALE;
int costType = cost.type();
-
+
disp12MaxDiff *= DISP_SCALE;
-
+
CV_Assert( numberOfDisparities > 0 && disp.type() == CV_16S &&
(costType == CV_16S || costType == CV_32S) &&
disp.size() == cost.size() );
-
+
for( int y = 0; y < rows; y++ )
{
short* dptr = disp.ptr<short>(y);
-
+
for( x = 0; x < cols; x++ )
{
disp2buf[x] = INVALID_DISP_SCALED;
disp2cost[x] = INT_MAX;
}
-
+
if( costType == CV_16S )
{
const short* cptr = cost.ptr<short>(y);
-
+
for( x = minX1; x < maxX1; x++ )
{
int d = dptr[x], c = cptr[x];
int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT);
-
+
if( disp2cost[x2] > c )
{
disp2cost[x2] = c;
else
{
const int* cptr = cost.ptr<int>(y);
-
+
for( x = minX1; x < maxX1; x++ )
{
int d = dptr[x], c = cptr[x];
int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT);
-
+
if( disp2cost[x2] < c )
{
disp2cost[x2] = c;
}
}
}
-
+
for( x = minX1; x < maxX1; x++ )
{
// we round the computed disparity both towards -inf and +inf and check
protected:
int compare(double* val, double* refVal, int len,
double eps, const char* paramName);
- virtual void calibrate( int imageCount, int* pointCounts,
- CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
- double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
- double* rotationMatrices, int flags ) = 0;
- virtual void project( int pointCount, CvPoint3D64f* objectPoints,
- double* rotationMatrix, double* translationVector,
- double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints ) = 0;
+ virtual void calibrate( int imageCount, int* pointCounts,
+ CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
+ double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
+ double* rotationMatrices, int flags ) = 0;
+ virtual void project( int pointCount, CvPoint3D64f* objectPoints,
+ double* rotationMatrix, double* translationVector,
+ double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints ) = 0;
void run(int);
};
void CV_CameraCalibrationTest::clear()
{
- cvtest::BaseTest::clear();
+ cvtest::BaseTest::clear();
}
int CV_CameraCalibrationTest::compare(double* val, double* ref_val, int len,
/* ---- Reproject points to the image ---- */
for( currImage = 0; currImage < numImages; currImage++ )
{
- int numPoints = etalonSize.width * etalonSize.height;
- project( numPoints,
- objectPoints + currImage * numPoints,
+ int nPoints = etalonSize.width * etalonSize.height;
+ project( nPoints,
+ objectPoints + currImage * nPoints,
rotMatrs + currImage * 9,
transVects + currImage * 3,
cameraMatrix,
distortion,
- reprojectPoints + currImage * numPoints);
+ reprojectPoints + currImage * nPoints);
}
/* ----- Compute reprojection error ----- */
class CV_CameraCalibrationTest_C : public CV_CameraCalibrationTest
{
public:
- CV_CameraCalibrationTest_C(){}
+ CV_CameraCalibrationTest_C(){}
protected:
- virtual void calibrate( int imageCount, int* pointCounts,
- CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
- double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
- double* rotationMatrices, int flags );
- virtual void project( int pointCount, CvPoint3D64f* objectPoints,
- double* rotationMatrix, double* translationVector,
- double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints );
+ virtual void calibrate( int imageCount, int* pointCounts,
+ CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
+ double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
+ double* rotationMatrices, int flags );
+ virtual void project( int pointCount, CvPoint3D64f* objectPoints,
+ double* rotationMatrix, double* translationVector,
+ double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints );
};
void CV_CameraCalibrationTest_C::calibrate( int imageCount, int* pointCounts,
- CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
- double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
- double* rotationMatrices, int flags )
+ CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
+ double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
+ double* rotationMatrices, int flags )
{
int i, total = 0;
for( i = 0; i < imageCount; i++ )
total += pointCounts[i];
-
+
CvMat _objectPoints = cvMat(1, total, CV_64FC3, objectPoints);
CvMat _imagePoints = cvMat(1, total, CV_64FC2, imagePoints);
CvMat _pointCounts = cvMat(1, imageCount, CV_32S, pointCounts);
CvMat _distCoeffs = cvMat(4, 1, CV_64F, distortionCoeffs);
CvMat _rotationMatrices = cvMat(imageCount, 9, CV_64F, rotationMatrices);
CvMat _translationVectors = cvMat(imageCount, 3, CV_64F, translationVectors);
-
+
cvCalibrateCamera2(&_objectPoints, &_imagePoints, &_pointCounts, imageSize,
&_cameraMatrix, &_distCoeffs, &_rotationMatrices, &_translationVectors,
flags);
}
void CV_CameraCalibrationTest_C::project( int pointCount, CvPoint3D64f* objectPoints,
- double* rotationMatrix, double* translationVector,
- double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints )
+ double* rotationMatrix, double* translationVector,
+ double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints )
{
- CvMat _objectPoints = cvMat(1, pointCount, CV_64FC3, objectPoints);
+ CvMat _objectPoints = cvMat(1, pointCount, CV_64FC3, objectPoints);
CvMat _imagePoints = cvMat(1, pointCount, CV_64FC2, imagePoints);
CvMat _cameraMatrix = cvMat(3, 3, CV_64F, cameraMatrix);
CvMat _distCoeffs = cvMat(4, 1, CV_64F, distortion);
CvMat _rotationMatrix = cvMat(3, 3, CV_64F, rotationMatrix);
CvMat _translationVector = cvMat(1, 3, CV_64F, translationVector);
-
+
cvProjectPoints2(&_objectPoints, &_rotationMatrix, &_translationVector, &_cameraMatrix, &_distCoeffs, &_imagePoints);
}
class CV_CameraCalibrationTest_CPP : public CV_CameraCalibrationTest
{
public:
- CV_CameraCalibrationTest_CPP(){}
+ CV_CameraCalibrationTest_CPP(){}
protected:
- virtual void calibrate( int imageCount, int* pointCounts,
- CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
- double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
- double* rotationMatrices, int flags );
- virtual void project( int pointCount, CvPoint3D64f* objectPoints,
- double* rotationMatrix, double* translationVector,
- double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints );
+ virtual void calibrate( int imageCount, int* pointCounts,
+ CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
+ double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
+ double* rotationMatrices, int flags );
+ virtual void project( int pointCount, CvPoint3D64f* objectPoints,
+ double* rotationMatrix, double* translationVector,
+ double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints );
};
void CV_CameraCalibrationTest_CPP::calibrate( int imageCount, int* pointCounts,
- CvSize _imageSize, CvPoint2D64f* _imagePoints, CvPoint3D64f* _objectPoints,
- double* _distortionCoeffs, double* _cameraMatrix, double* translationVectors,
- double* rotationMatrices, int flags )
+ CvSize _imageSize, CvPoint2D64f* _imagePoints, CvPoint3D64f* _objectPoints,
+ double* _distortionCoeffs, double* _cameraMatrix, double* translationVectors,
+ double* rotationMatrices, int flags )
{
- vector<vector<Point3f> > objectPoints( imageCount );
- vector<vector<Point2f> > imagePoints( imageCount );
- Size imageSize = _imageSize;
- Mat cameraMatrix, distCoeffs(1,4,CV_64F,Scalar::all(0));
- vector<Mat> rvecs, tvecs;
-
- CvPoint3D64f* op = _objectPoints;
- CvPoint2D64f* ip = _imagePoints;
- vector<vector<Point3f> >::iterator objectPointsIt = objectPoints.begin();
- vector<vector<Point2f> >::iterator imagePointsIt = imagePoints.begin();
- for( int i = 0; i < imageCount; ++objectPointsIt, ++imagePointsIt, i++ )
- {
- int num = pointCounts[i];
- objectPointsIt->resize( num );
- imagePointsIt->resize( num );
- vector<Point3f>::iterator oIt = objectPointsIt->begin();
- vector<Point2f>::iterator iIt = imagePointsIt->begin();
- for( int j = 0; j < num; ++oIt, ++iIt, j++, op++, ip++)
- {
- oIt->x = (float)op->x, oIt->y = (float)op->y, oIt->z = (float)op->z;
- iIt->x = (float)ip->x, iIt->y = (float)ip->y;
- }
- }
-
- calibrateCamera( objectPoints,
- imagePoints,
- imageSize,
- cameraMatrix,
- distCoeffs,
- rvecs,
- tvecs,
- flags );
-
- assert( cameraMatrix.type() == CV_64FC1 );
- memcpy( _cameraMatrix, cameraMatrix.data, 9*sizeof(double) );
-
- assert( cameraMatrix.type() == CV_64FC1 );
- memcpy( _distortionCoeffs, distCoeffs.data, 4*sizeof(double) );
-
- vector<Mat>::iterator rvecsIt = rvecs.begin();
- vector<Mat>::iterator tvecsIt = tvecs.begin();
- double *rm = rotationMatrices,
- *tm = translationVectors;
- assert( rvecsIt->type() == CV_64FC1 );
- assert( tvecsIt->type() == CV_64FC1 );
- for( int i = 0; i < imageCount; ++rvecsIt, ++tvecsIt, i++, rm+=9, tm+=3 )
- {
- Mat r9( 3, 3, CV_64FC1 );
- Rodrigues( *rvecsIt, r9 );
- memcpy( rm, r9.data, 9*sizeof(double) );
- memcpy( tm, tvecsIt->data, 3*sizeof(double) );
- }
+ vector<vector<Point3f> > objectPoints( imageCount );
+ vector<vector<Point2f> > imagePoints( imageCount );
+ Size imageSize = _imageSize;
+ Mat cameraMatrix, distCoeffs(1,4,CV_64F,Scalar::all(0));
+ vector<Mat> rvecs, tvecs;
+
+ CvPoint3D64f* op = _objectPoints;
+ CvPoint2D64f* ip = _imagePoints;
+ vector<vector<Point3f> >::iterator objectPointsIt = objectPoints.begin();
+ vector<vector<Point2f> >::iterator imagePointsIt = imagePoints.begin();
+ for( int i = 0; i < imageCount; ++objectPointsIt, ++imagePointsIt, i++ )
+ {
+ int num = pointCounts[i];
+ objectPointsIt->resize( num );
+ imagePointsIt->resize( num );
+ vector<Point3f>::iterator oIt = objectPointsIt->begin();
+ vector<Point2f>::iterator iIt = imagePointsIt->begin();
+ for( int j = 0; j < num; ++oIt, ++iIt, j++, op++, ip++)
+ {
+ oIt->x = (float)op->x, oIt->y = (float)op->y, oIt->z = (float)op->z;
+ iIt->x = (float)ip->x, iIt->y = (float)ip->y;
+ }
+ }
+
+ calibrateCamera( objectPoints,
+ imagePoints,
+ imageSize,
+ cameraMatrix,
+ distCoeffs,
+ rvecs,
+ tvecs,
+ flags );
+
+ assert( cameraMatrix.type() == CV_64FC1 );
+ memcpy( _cameraMatrix, cameraMatrix.data, 9*sizeof(double) );
+
+ assert( cameraMatrix.type() == CV_64FC1 );
+ memcpy( _distortionCoeffs, distCoeffs.data, 4*sizeof(double) );
+
+ vector<Mat>::iterator rvecsIt = rvecs.begin();
+ vector<Mat>::iterator tvecsIt = tvecs.begin();
+ double *rm = rotationMatrices,
+ *tm = translationVectors;
+ assert( rvecsIt->type() == CV_64FC1 );
+ assert( tvecsIt->type() == CV_64FC1 );
+ for( int i = 0; i < imageCount; ++rvecsIt, ++tvecsIt, i++, rm+=9, tm+=3 )
+ {
+ Mat r9( 3, 3, CV_64FC1 );
+ Rodrigues( *rvecsIt, r9 );
+ memcpy( rm, r9.data, 9*sizeof(double) );
+ memcpy( tm, tvecsIt->data, 3*sizeof(double) );
+ }
}
void CV_CameraCalibrationTest_CPP::project( int pointCount, CvPoint3D64f* _objectPoints,
- double* rotationMatrix, double* translationVector,
- double* _cameraMatrix, double* distortion, CvPoint2D64f* _imagePoints )
+ double* rotationMatrix, double* translationVector,
+ double* _cameraMatrix, double* distortion, CvPoint2D64f* _imagePoints )
{
- Mat objectPoints( pointCount, 3, CV_64FC1, _objectPoints );
- Mat rmat( 3, 3, CV_64FC1, rotationMatrix ),
- rvec( 1, 3, CV_64FC1 ),
- tvec( 1, 3, CV_64FC1, translationVector );
- Mat cameraMatrix( 3, 3, CV_64FC1, _cameraMatrix );
- Mat distCoeffs( 1, 4, CV_64FC1, distortion );
- vector<Point2f> imagePoints;
- Rodrigues( rmat, rvec );
-
- objectPoints.convertTo( objectPoints, CV_32FC1 );
- projectPoints( objectPoints, rvec, tvec,
- cameraMatrix, distCoeffs, imagePoints );
- vector<Point2f>::const_iterator it = imagePoints.begin();
- for( int i = 0; it != imagePoints.end(); ++it, i++ )
- {
- _imagePoints[i] = cvPoint2D64f( it->x, it->y );
- }
+ Mat objectPoints( pointCount, 3, CV_64FC1, _objectPoints );
+ Mat rmat( 3, 3, CV_64FC1, rotationMatrix ),
+ rvec( 1, 3, CV_64FC1 ),
+ tvec( 1, 3, CV_64FC1, translationVector );
+ Mat cameraMatrix( 3, 3, CV_64FC1, _cameraMatrix );
+ Mat distCoeffs( 1, 4, CV_64FC1, distortion );
+ vector<Point2f> imagePoints;
+ Rodrigues( rmat, rvec );
+
+ objectPoints.convertTo( objectPoints, CV_32FC1 );
+ projectPoints( objectPoints, rvec, tvec,
+ cameraMatrix, distCoeffs, imagePoints );
+ vector<Point2f>::const_iterator it = imagePoints.begin();
+ for( int i = 0; it != imagePoints.end(); ++it, i++ )
+ {
+ _imagePoints[i] = cvPoint2D64f( it->x, it->y );
+ }
}
class CV_CalibrationMatrixValuesTest : public cvtest::BaseTest
{
public:
- CV_CalibrationMatrixValuesTest() {}
+ CV_CalibrationMatrixValuesTest() {}
protected:
- void run(int);
- virtual void calibMatrixValues( const Mat& cameraMatrix, Size imageSize,
- double apertureWidth, double apertureHeight, double& fovx, double& fovy, double& focalLength,
- Point2d& principalPoint, double& aspectRatio ) = 0;
+ void run(int);
+ virtual void calibMatrixValues( const Mat& cameraMatrix, Size imageSize,
+ double apertureWidth, double apertureHeight, double& fovx, double& fovy, double& focalLength,
+ Point2d& principalPoint, double& aspectRatio ) = 0;
};
void CV_CalibrationMatrixValuesTest::run(int)
{
- int code = cvtest::TS::OK;
- const double fcMinVal = 1e-5;
- const double fcMaxVal = 1000;
- const double apertureMaxVal = 0.01;
-
- RNG rng = ts->get_rng();
-
- double fx, fy, cx, cy, nx, ny;
- Mat cameraMatrix( 3, 3, CV_64FC1 );
- cameraMatrix.setTo( Scalar(0) );
- fx = cameraMatrix.at<double>(0,0) = rng.uniform( fcMinVal, fcMaxVal );
- fy = cameraMatrix.at<double>(1,1) = rng.uniform( fcMinVal, fcMaxVal );
- cx = cameraMatrix.at<double>(0,2) = rng.uniform( fcMinVal, fcMaxVal );
- cy = cameraMatrix.at<double>(1,2) = rng.uniform( fcMinVal, fcMaxVal );
- cameraMatrix.at<double>(2,2) = 1;
-
- Size imageSize( 600, 400 );
-
- double apertureWidth = (double)rng * apertureMaxVal,
- apertureHeight = (double)rng * apertureMaxVal;
-
- double fovx, fovy, focalLength, aspectRatio,
- goodFovx, goodFovy, goodFocalLength, goodAspectRatio;
- Point2d principalPoint, goodPrincipalPoint;
-
-
- calibMatrixValues( cameraMatrix, imageSize, apertureWidth, apertureHeight,
- fovx, fovy, focalLength, principalPoint, aspectRatio );
-
- // calculate calibration matrix values
- goodAspectRatio = fy / fx;
-
- if( apertureWidth != 0.0 && apertureHeight != 0.0 )
- {
- nx = imageSize.width / apertureWidth;
- ny = imageSize.height / apertureHeight;
- }
- else
- {
- nx = 1.0;
- ny = goodAspectRatio;
- }
-
- goodFovx = 2 * atan( imageSize.width / (2 * fx)) * 180.0 / CV_PI;
- goodFovy = 2 * atan( imageSize.height / (2 * fy)) * 180.0 / CV_PI;
-
- goodFocalLength = fx / nx;
-
- goodPrincipalPoint.x = cx / nx;
- goodPrincipalPoint.y = cy / ny;
-
- // check results
- if( fabs(fovx - goodFovx) > FLT_EPSILON )
- {
- ts->printf( cvtest::TS::LOG, "bad fovx (real=%f, good = %f\n", fovx, goodFovx );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- goto _exit_;
- }
- if( fabs(fovy - goodFovy) > FLT_EPSILON )
- {
- ts->printf( cvtest::TS::LOG, "bad fovy (real=%f, good = %f\n", fovy, goodFovy );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- goto _exit_;
- }
- if( fabs(focalLength - goodFocalLength) > FLT_EPSILON )
- {
- ts->printf( cvtest::TS::LOG, "bad focalLength (real=%f, good = %f\n", focalLength, goodFocalLength );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- goto _exit_;
- }
- if( fabs(aspectRatio - goodAspectRatio) > FLT_EPSILON )
- {
- ts->printf( cvtest::TS::LOG, "bad aspectRatio (real=%f, good = %f\n", aspectRatio, goodAspectRatio );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- goto _exit_;
- }
- if( norm( principalPoint - goodPrincipalPoint ) > FLT_EPSILON )
- {
- ts->printf( cvtest::TS::LOG, "bad principalPoint\n" );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- goto _exit_;
- }
+ int code = cvtest::TS::OK;
+ const double fcMinVal = 1e-5;
+ const double fcMaxVal = 1000;
+ const double apertureMaxVal = 0.01;
+
+ RNG rng = ts->get_rng();
+
+ double fx, fy, cx, cy, nx, ny;
+ Mat cameraMatrix( 3, 3, CV_64FC1 );
+ cameraMatrix.setTo( Scalar(0) );
+ fx = cameraMatrix.at<double>(0,0) = rng.uniform( fcMinVal, fcMaxVal );
+ fy = cameraMatrix.at<double>(1,1) = rng.uniform( fcMinVal, fcMaxVal );
+ cx = cameraMatrix.at<double>(0,2) = rng.uniform( fcMinVal, fcMaxVal );
+ cy = cameraMatrix.at<double>(1,2) = rng.uniform( fcMinVal, fcMaxVal );
+ cameraMatrix.at<double>(2,2) = 1;
+
+ Size imageSize( 600, 400 );
+
+ double apertureWidth = (double)rng * apertureMaxVal,
+ apertureHeight = (double)rng * apertureMaxVal;
+
+ double fovx, fovy, focalLength, aspectRatio,
+ goodFovx, goodFovy, goodFocalLength, goodAspectRatio;
+ Point2d principalPoint, goodPrincipalPoint;
+
+
+ calibMatrixValues( cameraMatrix, imageSize, apertureWidth, apertureHeight,
+ fovx, fovy, focalLength, principalPoint, aspectRatio );
+
+ // calculate calibration matrix values
+ goodAspectRatio = fy / fx;
+
+ if( apertureWidth != 0.0 && apertureHeight != 0.0 )
+ {
+ nx = imageSize.width / apertureWidth;
+ ny = imageSize.height / apertureHeight;
+ }
+ else
+ {
+ nx = 1.0;
+ ny = goodAspectRatio;
+ }
+
+ goodFovx = 2 * atan( imageSize.width / (2 * fx)) * 180.0 / CV_PI;
+ goodFovy = 2 * atan( imageSize.height / (2 * fy)) * 180.0 / CV_PI;
+
+ goodFocalLength = fx / nx;
+
+ goodPrincipalPoint.x = cx / nx;
+ goodPrincipalPoint.y = cy / ny;
+
+ // check results
+ if( fabs(fovx - goodFovx) > FLT_EPSILON )
+ {
+ ts->printf( cvtest::TS::LOG, "bad fovx (real=%f, good = %f\n", fovx, goodFovx );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ goto _exit_;
+ }
+ if( fabs(fovy - goodFovy) > FLT_EPSILON )
+ {
+ ts->printf( cvtest::TS::LOG, "bad fovy (real=%f, good = %f\n", fovy, goodFovy );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ goto _exit_;
+ }
+ if( fabs(focalLength - goodFocalLength) > FLT_EPSILON )
+ {
+ ts->printf( cvtest::TS::LOG, "bad focalLength (real=%f, good = %f\n", focalLength, goodFocalLength );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ goto _exit_;
+ }
+ if( fabs(aspectRatio - goodAspectRatio) > FLT_EPSILON )
+ {
+ ts->printf( cvtest::TS::LOG, "bad aspectRatio (real=%f, good = %f\n", aspectRatio, goodAspectRatio );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ goto _exit_;
+ }
+ if( norm( principalPoint - goodPrincipalPoint ) > FLT_EPSILON )
+ {
+ ts->printf( cvtest::TS::LOG, "bad principalPoint\n" );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ goto _exit_;
+ }
_exit_:
- RNG& _rng = ts->get_rng();
- _rng = rng;
- ts->set_failed_test_info( code );
+ RNG& _rng = ts->get_rng();
+ _rng = rng;
+ ts->set_failed_test_info( code );
}
//----------------------------------------- CV_CalibrationMatrixValuesTest_C --------------------------------
class CV_CalibrationMatrixValuesTest_C : public CV_CalibrationMatrixValuesTest
{
public:
- CV_CalibrationMatrixValuesTest_C(){}
+ CV_CalibrationMatrixValuesTest_C(){}
protected:
- virtual void calibMatrixValues( const Mat& cameraMatrix, Size imageSize,
- double apertureWidth, double apertureHeight, double& fovx, double& fovy, double& focalLength,
- Point2d& principalPoint, double& aspectRatio );
+ virtual void calibMatrixValues( const Mat& cameraMatrix, Size imageSize,
+ double apertureWidth, double apertureHeight, double& fovx, double& fovy, double& focalLength,
+ Point2d& principalPoint, double& aspectRatio );
};
void CV_CalibrationMatrixValuesTest_C::calibMatrixValues( const Mat& _cameraMatrix, Size imageSize,
- double apertureWidth, double apertureHeight,
- double& fovx, double& fovy, double& focalLength,
- Point2d& principalPoint, double& aspectRatio )
+ double apertureWidth, double apertureHeight,
+ double& fovx, double& fovy, double& focalLength,
+ Point2d& principalPoint, double& aspectRatio )
{
- CvMat cameraMatrix = _cameraMatrix;
- CvPoint2D64f pp;
- cvCalibrationMatrixValues( &cameraMatrix, imageSize, apertureWidth, apertureHeight,
- &fovx, &fovy, &focalLength, &pp, &aspectRatio );
- principalPoint.x = pp.x;
- principalPoint.y = pp.y;
+ CvMat cameraMatrix = _cameraMatrix;
+ CvPoint2D64f pp;
+ cvCalibrationMatrixValues( &cameraMatrix, imageSize, apertureWidth, apertureHeight,
+ &fovx, &fovy, &focalLength, &pp, &aspectRatio );
+ principalPoint.x = pp.x;
+ principalPoint.y = pp.y;
}
class CV_CalibrationMatrixValuesTest_CPP : public CV_CalibrationMatrixValuesTest
{
public:
- CV_CalibrationMatrixValuesTest_CPP() {}
+ CV_CalibrationMatrixValuesTest_CPP() {}
protected:
- virtual void calibMatrixValues( const Mat& cameraMatrix, Size imageSize,
- double apertureWidth, double apertureHeight, double& fovx, double& fovy, double& focalLength,
- Point2d& principalPoint, double& aspectRatio );
+ virtual void calibMatrixValues( const Mat& cameraMatrix, Size imageSize,
+ double apertureWidth, double apertureHeight, double& fovx, double& fovy, double& focalLength,
+ Point2d& principalPoint, double& aspectRatio );
};
void CV_CalibrationMatrixValuesTest_CPP::calibMatrixValues( const Mat& cameraMatrix, Size imageSize,
- double apertureWidth, double apertureHeight,
- double& fovx, double& fovy, double& focalLength,
- Point2d& principalPoint, double& aspectRatio )
+ double apertureWidth, double apertureHeight,
+ double& fovx, double& fovy, double& focalLength,
+ Point2d& principalPoint, double& aspectRatio )
{
- calibrationMatrixValues( cameraMatrix, imageSize, apertureWidth, apertureHeight,
- fovx, fovy, focalLength, principalPoint, aspectRatio );
+ calibrationMatrixValues( cameraMatrix, imageSize, apertureWidth, apertureHeight,
+ fovx, fovy, focalLength, principalPoint, aspectRatio );
}
void calcdfdx( const vector<vector<Point2f> >& leftF, const vector<vector<Point2f> >& rightF, double eps, Mat& dfdx )
{
const int fdim = 2;
- CV_Assert( !leftF.empty() && !rightF.empty() && !leftF[0].empty() && !rightF[0].empty() );
- CV_Assert( leftF[0].size() == rightF[0].size() );
- CV_Assert( fabs(eps) > std::numeric_limits<double>::epsilon() );
- int fcount = (int)leftF[0].size(), xdim = (int)leftF.size();
+ CV_Assert( !leftF.empty() && !rightF.empty() && !leftF[0].empty() && !rightF[0].empty() );
+ CV_Assert( leftF[0].size() == rightF[0].size() );
+ CV_Assert( fabs(eps) > std::numeric_limits<double>::epsilon() );
+ int fcount = (int)leftF[0].size(), xdim = (int)leftF.size();
- dfdx.create( fcount*fdim, xdim, CV_64FC1 );
+ dfdx.create( fcount*fdim, xdim, CV_64FC1 );
- vector<vector<Point2f> >::const_iterator arrLeftIt = leftF.begin();
- vector<vector<Point2f> >::const_iterator arrRightIt = rightF.begin();
- for( int xi = 0; xi < xdim; xi++, ++arrLeftIt, ++arrRightIt )
- {
+ vector<vector<Point2f> >::const_iterator arrLeftIt = leftF.begin();
+ vector<vector<Point2f> >::const_iterator arrRightIt = rightF.begin();
+ for( int xi = 0; xi < xdim; xi++, ++arrLeftIt, ++arrRightIt )
+ {
CV_Assert( (int)arrLeftIt->size() == fcount );
CV_Assert( (int)arrRightIt->size() == fcount );
vector<Point2f>::const_iterator lIt = arrLeftIt->begin();
for( int fi = 0; fi < dfdx.rows; fi+=fdim, ++lIt, ++rIt )
{
dfdx.at<double>(fi, xi ) = 0.5 * ((double)(rIt->x - lIt->x)) / eps;
- dfdx.at<double>(fi+1, xi ) = 0.5 * ((double)(rIt->y - lIt->y)) / eps;
- }
- }
+ dfdx.at<double>(fi+1, xi ) = 0.5 * ((double)(rIt->y - lIt->y)) / eps;
+ }
+ }
}
class CV_ProjectPointsTest : public cvtest::BaseTest
{
public:
- CV_ProjectPointsTest() {}
+ CV_ProjectPointsTest() {}
protected:
- void run(int);
- virtual void project( const Mat& objectPoints,
- const Mat& rvec, const Mat& tvec,
- const Mat& cameraMatrix,
- const Mat& distCoeffs,
- vector<Point2f>& imagePoints,
- Mat& dpdrot, Mat& dpdt, Mat& dpdf,
- Mat& dpdc, Mat& dpddist,
- double aspectRatio=0 ) = 0;
+ void run(int);
+ virtual void project( const Mat& objectPoints,
+ const Mat& rvec, const Mat& tvec,
+ const Mat& cameraMatrix,
+ const Mat& distCoeffs,
+ vector<Point2f>& imagePoints,
+ Mat& dpdrot, Mat& dpdt, Mat& dpdf,
+ Mat& dpdc, Mat& dpddist,
+ double aspectRatio=0 ) = 0;
};
void CV_ProjectPointsTest::run(int)
{
//typedef float matType;
- int code = cvtest::TS::OK;
- const int pointCount = 100;
+ int code = cvtest::TS::OK;
+ const int pointCount = 100;
- const float zMinVal = 10.0f, zMaxVal = 100.0f,
+ const float zMinVal = 10.0f, zMaxVal = 100.0f,
rMinVal = -0.3f, rMaxVal = 0.3f,
- tMinVal = -2.0f, tMaxVal = 2.0f;
+ tMinVal = -2.0f, tMaxVal = 2.0f;
const float imgPointErr = 1e-3f,
dEps = 1e-3f;
-
+
double err;
Size imgSize( 600, 800 );
Mat_<float> objPoints( pointCount, 3), rvec( 1, 3), rmat, tvec( 1, 3 ), cameraMatrix( 3, 3 ), distCoeffs( 1, 4 ),
leftRvec, rightRvec, leftTvec, rightTvec, leftCameraMatrix, rightCameraMatrix, leftDistCoeffs, rightDistCoeffs;
- RNG rng = ts->get_rng();
+ RNG rng = ts->get_rng();
- // generate data
- cameraMatrix << 300.f, 0.f, imgSize.width/2.f,
+ // generate data
+ cameraMatrix << 300.f, 0.f, imgSize.width/2.f,
0.f, 300.f, imgSize.height/2.f,
0.f, 0.f, 1.f;
- distCoeffs << 0.1, 0.01, 0.001, 0.001;
+ distCoeffs << 0.1, 0.01, 0.001, 0.001;
- rvec(0,0) = rng.uniform( rMinVal, rMaxVal );
- rvec(0,1) = rng.uniform( rMinVal, rMaxVal );
- rvec(0,2) = rng.uniform( rMinVal, rMaxVal );
- Rodrigues( rvec, rmat );
+ rvec(0,0) = rng.uniform( rMinVal, rMaxVal );
+ rvec(0,1) = rng.uniform( rMinVal, rMaxVal );
+ rvec(0,2) = rng.uniform( rMinVal, rMaxVal );
+ Rodrigues( rvec, rmat );
- tvec(0,0) = rng.uniform( tMinVal, tMaxVal );
- tvec(0,1) = rng.uniform( tMinVal, tMaxVal );
- tvec(0,2) = rng.uniform( tMinVal, tMaxVal );
+ tvec(0,0) = rng.uniform( tMinVal, tMaxVal );
+ tvec(0,1) = rng.uniform( tMinVal, tMaxVal );
+ tvec(0,2) = rng.uniform( tMinVal, tMaxVal );
for( int y = 0; y < objPoints.rows; y++ )
- {
- Mat point(1, 3, CV_32FC1, objPoints.ptr(y) );
- float z = rng.uniform( zMinVal, zMaxVal );
- point.at<float>(0,2) = z;
+ {
+ Mat point(1, 3, CV_32FC1, objPoints.ptr(y) );
+ float z = rng.uniform( zMinVal, zMaxVal );
+ point.at<float>(0,2) = z;
point.at<float>(0,0) = (rng.uniform(2.f,(float)(imgSize.width-2)) - cameraMatrix(0,2)) / cameraMatrix(0,0) * z;
point.at<float>(0,1) = (rng.uniform(2.f,(float)(imgSize.height-2)) - cameraMatrix(1,2)) / cameraMatrix(1,1) * z;
point = (point - tvec) * rmat;
- }
+ }
- vector<Point2f> imgPoints;
- vector<vector<Point2f> > leftImgPoints;
- vector<vector<Point2f> > rightImgPoints;
- Mat dpdrot, dpdt, dpdf, dpdc, dpddist,
- valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist;
+ vector<Point2f> imgPoints;
+ vector<vector<Point2f> > leftImgPoints;
+ vector<vector<Point2f> > rightImgPoints;
+ Mat dpdrot, dpdt, dpdf, dpdc, dpddist,
+ valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist;
- project( objPoints, rvec, tvec, cameraMatrix, distCoeffs,
- imgPoints, dpdrot, dpdt, dpdf, dpdc, dpddist, 0 );
+ project( objPoints, rvec, tvec, cameraMatrix, distCoeffs,
+ imgPoints, dpdrot, dpdt, dpdf, dpdc, dpddist, 0 );
// calculate and check image points
assert( (int)imgPoints.size() == pointCount );
- vector<Point2f>::const_iterator it = imgPoints.begin();
- for( int i = 0; i < pointCount; i++, ++it )
- {
- Point3d p( objPoints(i,0), objPoints(i,1), objPoints(i,2) );
- double z = p.x*rmat(2,0) + p.y*rmat(2,1) + p.z*rmat(2,2) + tvec(0,2),
+ vector<Point2f>::const_iterator it = imgPoints.begin();
+ for( int i = 0; i < pointCount; i++, ++it )
+ {
+ Point3d p( objPoints(i,0), objPoints(i,1), objPoints(i,2) );
+ double z = p.x*rmat(2,0) + p.y*rmat(2,1) + p.z*rmat(2,2) + tvec(0,2),
x = (p.x*rmat(0,0) + p.y*rmat(0,1) + p.z*rmat(0,2) + tvec(0,0)) / z,
y = (p.x*rmat(1,0) + p.y*rmat(1,1) + p.z*rmat(1,2) + tvec(0,1)) / z,
r2 = x*x + y*y,
- r4 = r2*r2;
- Point2f validImgPoint;
- double a1 = 2*x*y,
+ r4 = r2*r2;
+ Point2f validImgPoint;
+ double a1 = 2*x*y,
a2 = r2 + 2*x*x,
a3 = r2 + 2*y*y,
cdist = 1+distCoeffs(0,0)*r2+distCoeffs(0,1)*r4;
- validImgPoint.x = static_cast<float>((double)cameraMatrix(0,0)*(x*cdist + (double)distCoeffs(0,2)*a1 + (double)distCoeffs(0,3)*a2)
+ validImgPoint.x = static_cast<float>((double)cameraMatrix(0,0)*(x*cdist + (double)distCoeffs(0,2)*a1 + (double)distCoeffs(0,3)*a2)
+ (double)cameraMatrix(0,2));
- validImgPoint.y = static_cast<float>((double)cameraMatrix(1,1)*(y*cdist + (double)distCoeffs(0,2)*a3 + distCoeffs(0,3)*a1)
+ validImgPoint.y = static_cast<float>((double)cameraMatrix(1,1)*(y*cdist + (double)distCoeffs(0,2)*a3 + distCoeffs(0,3)*a1)
+ (double)cameraMatrix(1,2));
if( fabs(it->x - validImgPoint.x) > imgPointErr ||
fabs(it->y - validImgPoint.y) > imgPointErr )
- {
- ts->printf( cvtest::TS::LOG, "bad image point\n" );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- goto _exit_;
- }
- }
-
- // check derivatives
- // 1. rotation
- leftImgPoints.resize(3);
+ {
+ ts->printf( cvtest::TS::LOG, "bad image point\n" );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ goto _exit_;
+ }
+ }
+
+ // check derivatives
+ // 1. rotation
+ leftImgPoints.resize(3);
rightImgPoints.resize(3);
- for( int i = 0; i < 3; i++ )
- {
+ for( int i = 0; i < 3; i++ )
+ {
rvec.copyTo( leftRvec ); leftRvec(0,i) -= dEps;
project( objPoints, leftRvec, tvec, cameraMatrix, distCoeffs,
leftImgPoints[i], valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist, 0 );
rvec.copyTo( rightRvec ); rightRvec(0,i) += dEps;
project( objPoints, rightRvec, tvec, cameraMatrix, distCoeffs,
rightImgPoints[i], valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist, 0 );
- }
+ }
calcdfdx( leftImgPoints, rightImgPoints, dEps, valDpdrot );
err = norm( dpdrot, valDpdrot, NORM_INF );
if( err > 3 )
- {
- ts->printf( cvtest::TS::LOG, "bad dpdrot: too big difference = %g\n", err );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- }
+ {
+ ts->printf( cvtest::TS::LOG, "bad dpdrot: too big difference = %g\n", err );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ }
// 2. translation
for( int i = 0; i < 3; i++ )
- {
+ {
tvec.copyTo( leftTvec ); leftTvec(0,i) -= dEps;
project( objPoints, rvec, leftTvec, cameraMatrix, distCoeffs,
leftImgPoints[i], valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist, 0 );
tvec.copyTo( rightTvec ); rightTvec(0,i) += dEps;
project( objPoints, rvec, rightTvec, cameraMatrix, distCoeffs,
rightImgPoints[i], valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist, 0 );
- }
+ }
calcdfdx( leftImgPoints, rightImgPoints, dEps, valDpdt );
if( norm( dpdt, valDpdt, NORM_INF ) > 0.2 )
- {
- ts->printf( cvtest::TS::LOG, "bad dpdtvec\n" );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- }
+ {
+ ts->printf( cvtest::TS::LOG, "bad dpdtvec\n" );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ }
// 3. camera matrix
// 3.1. focus
// 4. distortion
leftImgPoints.resize(distCoeffs.cols);
rightImgPoints.resize(distCoeffs.cols);
- for( int i = 0; i < distCoeffs.cols; i++ )
- {
+ for( int i = 0; i < distCoeffs.cols; i++ )
+ {
distCoeffs.copyTo( leftDistCoeffs ); leftDistCoeffs(0,i) -= dEps;
project( objPoints, rvec, tvec, cameraMatrix, leftDistCoeffs,
leftImgPoints[i], valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist, 0 );
distCoeffs.copyTo( rightDistCoeffs ); rightDistCoeffs(0,i) += dEps;
project( objPoints, rvec, tvec, cameraMatrix, rightDistCoeffs,
rightImgPoints[i], valDpdrot, valDpdt, valDpdf, valDpdc, valDpddist, 0 );
- }
+ }
calcdfdx( leftImgPoints, rightImgPoints, dEps, valDpddist );
if( norm( dpddist, valDpddist ) > 0.3 )
- {
- ts->printf( cvtest::TS::LOG, "bad dpddist\n" );
- code = cvtest::TS::FAIL_BAD_ACCURACY;
- }
+ {
+ ts->printf( cvtest::TS::LOG, "bad dpddist\n" );
+ code = cvtest::TS::FAIL_BAD_ACCURACY;
+ }
_exit_:
- RNG& _rng = ts->get_rng();
- _rng = rng;
- ts->set_failed_test_info( code );
+ RNG& _rng = ts->get_rng();
+ _rng = rng;
+ ts->set_failed_test_info( code );
}
//----------------------------------------- CV_ProjectPointsTest_C --------------------------------
class CV_ProjectPointsTest_C : public CV_ProjectPointsTest
{
public:
- CV_ProjectPointsTest_C() {}
+ CV_ProjectPointsTest_C() {}
protected:
- virtual void project( const Mat& objectPoints,
- const Mat& rvec, const Mat& tvec,
- const Mat& cameraMatrix,
- const Mat& distCoeffs,
- vector<Point2f>& imagePoints,
- Mat& dpdrot, Mat& dpdt, Mat& dpdf,
- Mat& dpdc, Mat& dpddist,
- double aspectRatio=0 );
+ virtual void project( const Mat& objectPoints,
+ const Mat& rvec, const Mat& tvec,
+ const Mat& cameraMatrix,
+ const Mat& distCoeffs,
+ vector<Point2f>& imagePoints,
+ Mat& dpdrot, Mat& dpdt, Mat& dpdf,
+ Mat& dpdc, Mat& dpddist,
+ double aspectRatio=0 );
};
void CV_ProjectPointsTest_C::project( const Mat& opoints, const Mat& rvec, const Mat& tvec,
- const Mat& cameraMatrix, const Mat& distCoeffs, vector<Point2f>& ipoints,
- Mat& dpdrot, Mat& dpdt, Mat& dpdf, Mat& dpdc, Mat& dpddist, double aspectRatio)
+ const Mat& cameraMatrix, const Mat& distCoeffs, vector<Point2f>& ipoints,
+ Mat& dpdrot, Mat& dpdt, Mat& dpdf, Mat& dpdc, Mat& dpddist, double aspectRatio)
{
int npoints = opoints.cols*opoints.rows*opoints.channels()/3;
ipoints.resize(npoints);
CvMat _rvec = rvec, _tvec = tvec, _cameraMatrix = cameraMatrix, _distCoeffs = distCoeffs;
CvMat _dpdrot = dpdrot, _dpdt = dpdt, _dpdf = dpdf, _dpdc = dpdc, _dpddist = dpddist;
- cvProjectPoints2( &_objectPoints, &_rvec, &_tvec, &_cameraMatrix, &_distCoeffs,
+ cvProjectPoints2( &_objectPoints, &_rvec, &_tvec, &_cameraMatrix, &_distCoeffs,
&_imagePoints, &_dpdrot, &_dpdt, &_dpdf, &_dpdc, &_dpddist, aspectRatio );
}
class CV_ProjectPointsTest_CPP : public CV_ProjectPointsTest
{
public:
- CV_ProjectPointsTest_CPP() {}
+ CV_ProjectPointsTest_CPP() {}
protected:
- virtual void project( const Mat& objectPoints,
- const Mat& rvec, const Mat& tvec,
- const Mat& cameraMatrix,
- const Mat& distCoeffs,
- vector<Point2f>& imagePoints,
- Mat& dpdrot, Mat& dpdt, Mat& dpdf,
- Mat& dpdc, Mat& dpddist,
- double aspectRatio=0 );
+ virtual void project( const Mat& objectPoints,
+ const Mat& rvec, const Mat& tvec,
+ const Mat& cameraMatrix,
+ const Mat& distCoeffs,
+ vector<Point2f>& imagePoints,
+ Mat& dpdrot, Mat& dpdt, Mat& dpdf,
+ Mat& dpdc, Mat& dpddist,
+ double aspectRatio=0 );
};
void CV_ProjectPointsTest_CPP::project( const Mat& objectPoints, const Mat& rvec, const Mat& tvec,
- const Mat& cameraMatrix, const Mat& distCoeffs, vector<Point2f>& imagePoints,
- Mat& dpdrot, Mat& dpdt, Mat& dpdf, Mat& dpdc, Mat& dpddist, double aspectRatio)
+ const Mat& cameraMatrix, const Mat& distCoeffs, vector<Point2f>& imagePoints,
+ Mat& dpdrot, Mat& dpdt, Mat& dpdf, Mat& dpdc, Mat& dpddist, double aspectRatio)
{
Mat J;
- projectPoints( objectPoints, rvec, tvec, cameraMatrix, distCoeffs, imagePoints, J, aspectRatio);
+ projectPoints( objectPoints, rvec, tvec, cameraMatrix, distCoeffs, imagePoints, J, aspectRatio);
J.colRange(0, 3).copyTo(dpdrot);
J.colRange(3, 6).copyTo(dpdt);
J.colRange(6, 8).copyTo(dpdf);
class CV_StereoCalibrationTest : public cvtest::BaseTest
{
public:
- CV_StereoCalibrationTest();
- ~CV_StereoCalibrationTest();
- void clear();
+ CV_StereoCalibrationTest();
+ ~CV_StereoCalibrationTest();
+ void clear();
protected:
- bool checkPandROI( int test_case_idx,
- const Mat& M, const Mat& D, const Mat& R,
- const Mat& P, Size imgsize, Rect roi );
-
- // covers of tested functions
- virtual double calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
- const vector<vector<Point2f> >& imagePoints1,
- const vector<vector<Point2f> >& imagePoints2,
- Mat& cameraMatrix1, Mat& distCoeffs1,
- Mat& cameraMatrix2, Mat& distCoeffs2,
- Size imageSize, Mat& R, Mat& T,
- Mat& E, Mat& F, TermCriteria criteria, int flags ) = 0;
- virtual void rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
- const Mat& cameraMatrix2, const Mat& distCoeffs2,
- Size imageSize, const Mat& R, const Mat& T,
- Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
- double alpha, Size newImageSize,
- Rect* validPixROI1, Rect* validPixROI2, int flags ) = 0;
- virtual bool rectifyUncalibrated( const Mat& points1,
- const Mat& points2, const Mat& F, Size imgSize,
- Mat& H1, Mat& H2, double threshold=5 ) = 0;
- virtual void triangulate( const Mat& P1, const Mat& P2,
+ bool checkPandROI( int test_case_idx,
+ const Mat& M, const Mat& D, const Mat& R,
+ const Mat& P, Size imgsize, Rect roi );
+
+ // covers of tested functions
+ virtual double calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
+ const vector<vector<Point2f> >& imagePoints1,
+ const vector<vector<Point2f> >& imagePoints2,
+ Mat& cameraMatrix1, Mat& distCoeffs1,
+ Mat& cameraMatrix2, Mat& distCoeffs2,
+ Size imageSize, Mat& R, Mat& T,
+ Mat& E, Mat& F, TermCriteria criteria, int flags ) = 0;
+ virtual void rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
+ const Mat& cameraMatrix2, const Mat& distCoeffs2,
+ Size imageSize, const Mat& R, const Mat& T,
+ Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
+ double alpha, Size newImageSize,
+ Rect* validPixROI1, Rect* validPixROI2, int flags ) = 0;
+ virtual bool rectifyUncalibrated( const Mat& points1,
+ const Mat& points2, const Mat& F, Size imgSize,
+ Mat& H1, Mat& H2, double threshold=5 ) = 0;
+ virtual void triangulate( const Mat& P1, const Mat& P2,
const Mat &points1, const Mat &points2,
Mat &points4D ) = 0;
- virtual void correct( const Mat& F,
+ virtual void correct( const Mat& F,
const Mat &points1, const Mat &points2,
Mat &newPoints1, Mat &newPoints2 ) = 0;
- void run(int);
+ void run(int);
};
CV_StereoCalibrationTest::~CV_StereoCalibrationTest()
{
- clear();
+ clear();
}
void CV_StereoCalibrationTest::clear()
{
- cvtest::BaseTest::clear();
+ cvtest::BaseTest::clear();
}
bool CV_StereoCalibrationTest::checkPandROI( int test_case_idx, const Mat& M, const Mat& D, const Mat& R,
- const Mat& P, Size imgsize, Rect roi )
+ const Mat& P, Size imgsize, Rect roi )
{
- const double eps = 0.05;
- const int N = 21;
- int x, y, k;
- vector<Point2f> pts, upts;
-
- // step 1. check that all the original points belong to the destination image
- for( y = 0; y < N; y++ )
- for( x = 0; x < N; x++ )
- pts.push_back(Point2f((float)x*imgsize.width/(N-1), (float)y*imgsize.height/(N-1)));
-
- undistortPoints(Mat(pts), upts, M, D, R, P );
- for( k = 0; k < N*N; k++ )
- if( upts[k].x < -imgsize.width*eps || upts[k].x > imgsize.width*(1+eps) ||
- upts[k].y < -imgsize.height*eps || upts[k].y > imgsize.height*(1+eps) )
- {
- ts->printf(cvtest::TS::LOG, "Test #%d. The point (%g, %g) was mapped to (%g, %g) which is out of image\n",
- test_case_idx, pts[k].x, pts[k].y, upts[k].x, upts[k].y);
- return false;
- }
-
- // step 2. check that all the points inside ROI belong to the original source image
- Mat temp(imgsize, CV_8U), utemp, map1, map2;
- temp = Scalar::all(1);
- initUndistortRectifyMap(M, D, R, P, imgsize, CV_16SC2, map1, map2);
- remap(temp, utemp, map1, map2, INTER_LINEAR);
-
- if(roi.x < 0 || roi.y < 0 || roi.x + roi.width > imgsize.width || roi.y + roi.height > imgsize.height)
- {
- ts->printf(cvtest::TS::LOG, "Test #%d. The ROI=(%d, %d, %d, %d) is outside of the imge rectangle\n",
- test_case_idx, roi.x, roi.y, roi.width, roi.height);
- return false;
- }
- double s = sum(utemp(roi))[0];
- if( s > roi.area() || roi.area() - s > roi.area()*(1-eps) )
- {
- ts->printf(cvtest::TS::LOG, "Test #%d. The ratio of black pixels inside the valid ROI (~%g%%) is too large\n",
- test_case_idx, s*100./roi.area());
- return false;
- }
-
- return true;
+ const double eps = 0.05;
+ const int N = 21;
+ int x, y, k;
+ vector<Point2f> pts, upts;
+
+ // step 1. check that all the original points belong to the destination image
+ for( y = 0; y < N; y++ )
+ for( x = 0; x < N; x++ )
+ pts.push_back(Point2f((float)x*imgsize.width/(N-1), (float)y*imgsize.height/(N-1)));
+
+ undistortPoints(Mat(pts), upts, M, D, R, P );
+ for( k = 0; k < N*N; k++ )
+ if( upts[k].x < -imgsize.width*eps || upts[k].x > imgsize.width*(1+eps) ||
+ upts[k].y < -imgsize.height*eps || upts[k].y > imgsize.height*(1+eps) )
+ {
+ ts->printf(cvtest::TS::LOG, "Test #%d. The point (%g, %g) was mapped to (%g, %g) which is out of image\n",
+ test_case_idx, pts[k].x, pts[k].y, upts[k].x, upts[k].y);
+ return false;
+ }
+
+ // step 2. check that all the points inside ROI belong to the original source image
+ Mat temp(imgsize, CV_8U), utemp, map1, map2;
+ temp = Scalar::all(1);
+ initUndistortRectifyMap(M, D, R, P, imgsize, CV_16SC2, map1, map2);
+ remap(temp, utemp, map1, map2, INTER_LINEAR);
+
+ if(roi.x < 0 || roi.y < 0 || roi.x + roi.width > imgsize.width || roi.y + roi.height > imgsize.height)
+ {
+ ts->printf(cvtest::TS::LOG, "Test #%d. The ROI=(%d, %d, %d, %d) is outside of the imge rectangle\n",
+ test_case_idx, roi.x, roi.y, roi.width, roi.height);
+ return false;
+ }
+ double s = sum(utemp(roi))[0];
+ if( s > roi.area() || roi.area() - s > roi.area()*(1-eps) )
+ {
+ ts->printf(cvtest::TS::LOG, "Test #%d. The ratio of black pixels inside the valid ROI (~%g%%) is too large\n",
+ test_case_idx, s*100./roi.area());
+ return false;
+ }
+
+ return true;
}
void CV_StereoCalibrationTest::run( int )
{
- const int ntests = 1;
- const double maxReprojErr = 2;
- const double maxScanlineDistErr_c = 3;
- const double maxScanlineDistErr_uc = 4;
- FILE* f = 0;
-
- for(int testcase = 1; testcase <= ntests; testcase++)
- {
- char filepath[1000];
- char buf[1000];
- sprintf( filepath, "%sstereo/case%d/stereo_calib.txt", ts->get_data_path().c_str(), testcase );
- f = fopen(filepath, "rt");
- Size patternSize;
- vector<string> imglist;
-
- if( !f || !fgets(buf, sizeof(buf)-3, f) || sscanf(buf, "%d%d", &patternSize.width, &patternSize.height) != 2 )
- {
- ts->printf( cvtest::TS::LOG, "The file %s can not be opened or has invalid content\n", filepath );
- ts->set_failed_test_info( f ? cvtest::TS::FAIL_INVALID_TEST_DATA : cvtest::TS::FAIL_MISSING_TEST_DATA );
- return;
- }
-
- for(;;)
- {
- if( !fgets( buf, sizeof(buf)-3, f ))
- break;
- size_t len = strlen(buf);
- while( len > 0 && isspace(buf[len-1]))
- buf[--len] = '\0';
- if( buf[0] == '#')
- continue;
- sprintf(filepath, "%sstereo/case%d/%s", ts->get_data_path().c_str(), testcase, buf );
- imglist.push_back(string(filepath));
- }
- fclose(f);
-
- if( imglist.size() == 0 || imglist.size() % 2 != 0 )
- {
- ts->printf( cvtest::TS::LOG, "The number of images is 0 or an odd number in the case #%d\n", testcase );
- ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
- return;
- }
-
- int nframes = (int)(imglist.size()/2);
- int npoints = patternSize.width*patternSize.height;
- vector<vector<Point3f> > objpt(nframes);
- vector<vector<Point2f> > imgpt1(nframes);
- vector<vector<Point2f> > imgpt2(nframes);
- Size imgsize;
- int total = 0;
-
- for( int i = 0; i < nframes; i++ )
- {
- Mat left = imread(imglist[i*2]);
- Mat right = imread(imglist[i*2+1]);
- if(!left.data || !right.data)
- {
- ts->printf( cvtest::TS::LOG, "Can not load images %s and %s, testcase %d\n",
- imglist[i*2].c_str(), imglist[i*2+1].c_str(), testcase );
- ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
- return;
- }
- imgsize = left.size();
- bool found1 = findChessboardCorners(left, patternSize, imgpt1[i]);
- bool found2 = findChessboardCorners(right, patternSize, imgpt2[i]);
- if(!found1 || !found2)
- {
- ts->printf( cvtest::TS::LOG, "The function could not detect boards on the images %s and %s, testcase %d\n",
- imglist[i*2].c_str(), imglist[i*2+1].c_str(), testcase );
- ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
- return;
- }
- total += (int)imgpt1[i].size();
- for( int j = 0; j < npoints; j++ )
- objpt[i].push_back(Point3f((float)(j%patternSize.width), (float)(j/patternSize.width), 0.f));
- }
-
- // rectify (calibrated)
- Mat M1 = Mat::eye(3,3,CV_64F), M2 = Mat::eye(3,3,CV_64F), D1(5,1,CV_64F), D2(5,1,CV_64F), R, T, E, F;
- M1.at<double>(0,2) = M2.at<double>(0,2)=(imgsize.width-1)*0.5;
- M1.at<double>(1,2) = M2.at<double>(1,2)=(imgsize.height-1)*0.5;
- D1 = Scalar::all(0);
- D2 = Scalar::all(0);
- double err = calibrateStereoCamera(objpt, imgpt1, imgpt2, M1, D1, M2, D2, imgsize, R, T, E, F,
- TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 1e-6),
- CV_CALIB_SAME_FOCAL_LENGTH
- //+ CV_CALIB_FIX_ASPECT_RATIO
- + CV_CALIB_FIX_PRINCIPAL_POINT
- + CV_CALIB_ZERO_TANGENT_DIST
+ const int ntests = 1;
+ const double maxReprojErr = 2;
+ const double maxScanlineDistErr_c = 3;
+ const double maxScanlineDistErr_uc = 4;
+ FILE* f = 0;
+
+ for(int testcase = 1; testcase <= ntests; testcase++)
+ {
+ char filepath[1000];
+ char buf[1000];
+ sprintf( filepath, "%sstereo/case%d/stereo_calib.txt", ts->get_data_path().c_str(), testcase );
+ f = fopen(filepath, "rt");
+ Size patternSize;
+ vector<string> imglist;
+
+ if( !f || !fgets(buf, sizeof(buf)-3, f) || sscanf(buf, "%d%d", &patternSize.width, &patternSize.height) != 2 )
+ {
+ ts->printf( cvtest::TS::LOG, "The file %s can not be opened or has invalid content\n", filepath );
+ ts->set_failed_test_info( f ? cvtest::TS::FAIL_INVALID_TEST_DATA : cvtest::TS::FAIL_MISSING_TEST_DATA );
+ return;
+ }
+
+ for(;;)
+ {
+ if( !fgets( buf, sizeof(buf)-3, f ))
+ break;
+ size_t len = strlen(buf);
+ while( len > 0 && isspace(buf[len-1]))
+ buf[--len] = '\0';
+ if( buf[0] == '#')
+ continue;
+ sprintf(filepath, "%sstereo/case%d/%s", ts->get_data_path().c_str(), testcase, buf );
+ imglist.push_back(string(filepath));
+ }
+ fclose(f);
+
+ if( imglist.size() == 0 || imglist.size() % 2 != 0 )
+ {
+ ts->printf( cvtest::TS::LOG, "The number of images is 0 or an odd number in the case #%d\n", testcase );
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
+ return;
+ }
+
+ int nframes = (int)(imglist.size()/2);
+ int npoints = patternSize.width*patternSize.height;
+ vector<vector<Point3f> > objpt(nframes);
+ vector<vector<Point2f> > imgpt1(nframes);
+ vector<vector<Point2f> > imgpt2(nframes);
+ Size imgsize;
+ int total = 0;
+
+ for( int i = 0; i < nframes; i++ )
+ {
+ Mat left = imread(imglist[i*2]);
+ Mat right = imread(imglist[i*2+1]);
+ if(!left.data || !right.data)
+ {
+ ts->printf( cvtest::TS::LOG, "Can not load images %s and %s, testcase %d\n",
+ imglist[i*2].c_str(), imglist[i*2+1].c_str(), testcase );
+ ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
+ return;
+ }
+ imgsize = left.size();
+ bool found1 = findChessboardCorners(left, patternSize, imgpt1[i]);
+ bool found2 = findChessboardCorners(right, patternSize, imgpt2[i]);
+ if(!found1 || !found2)
+ {
+ ts->printf( cvtest::TS::LOG, "The function could not detect boards on the images %s and %s, testcase %d\n",
+ imglist[i*2].c_str(), imglist[i*2+1].c_str(), testcase );
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+ return;
+ }
+ total += (int)imgpt1[i].size();
+ for( int j = 0; j < npoints; j++ )
+ objpt[i].push_back(Point3f((float)(j%patternSize.width), (float)(j/patternSize.width), 0.f));
+ }
+
+ // rectify (calibrated)
+ Mat M1 = Mat::eye(3,3,CV_64F), M2 = Mat::eye(3,3,CV_64F), D1(5,1,CV_64F), D2(5,1,CV_64F), R, T, E, F;
+ M1.at<double>(0,2) = M2.at<double>(0,2)=(imgsize.width-1)*0.5;
+ M1.at<double>(1,2) = M2.at<double>(1,2)=(imgsize.height-1)*0.5;
+ D1 = Scalar::all(0);
+ D2 = Scalar::all(0);
+ double err = calibrateStereoCamera(objpt, imgpt1, imgpt2, M1, D1, M2, D2, imgsize, R, T, E, F,
+ TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 1e-6),
+ CV_CALIB_SAME_FOCAL_LENGTH
+ //+ CV_CALIB_FIX_ASPECT_RATIO
+ + CV_CALIB_FIX_PRINCIPAL_POINT
+ + CV_CALIB_ZERO_TANGENT_DIST
+ CV_CALIB_FIX_K3
+ CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5 //+ CV_CALIB_FIX_K6
- );
- err /= nframes*npoints;
- if( err > maxReprojErr )
- {
- ts->printf( cvtest::TS::LOG, "The average reprojection error is too big (=%g), testcase %d\n", err, testcase);
- ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
- return;
- }
-
- Mat R1, R2, P1, P2, Q;
- Rect roi1, roi2;
- rectify(M1, D1, M2, D2, imgsize, R, T, R1, R2, P1, P2, Q, 1, imgsize, &roi1, &roi2, 0);
- Mat eye33 = Mat::eye(3,3,CV_64F);
- Mat R1t = R1.t(), R2t = R2.t();
-
- if( norm(R1t*R1 - eye33) > 0.01 ||
- norm(R2t*R2 - eye33) > 0.01 ||
- abs(determinant(F)) > 0.01)
- {
- ts->printf( cvtest::TS::LOG, "The computed (by rectify) R1 and R2 are not orthogonal,"
- "or the computed (by calibrate) F is not singular, testcase %d\n", testcase);
- ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
- return;
- }
-
- if(!checkPandROI(testcase, M1, D1, R1, P1, imgsize, roi1))
- {
- ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
- return;
- }
-
- if(!checkPandROI(testcase, M2, D2, R2, P2, imgsize, roi2))
- {
- ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
- return;
- }
+ );
+ err /= nframes*npoints;
+ if( err > maxReprojErr )
+ {
+ ts->printf( cvtest::TS::LOG, "The average reprojection error is too big (=%g), testcase %d\n", err, testcase);
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+ return;
+ }
+
+ Mat R1, R2, P1, P2, Q;
+ Rect roi1, roi2;
+ rectify(M1, D1, M2, D2, imgsize, R, T, R1, R2, P1, P2, Q, 1, imgsize, &roi1, &roi2, 0);
+ Mat eye33 = Mat::eye(3,3,CV_64F);
+ Mat R1t = R1.t(), R2t = R2.t();
+
+ if( norm(R1t*R1 - eye33) > 0.01 ||
+ norm(R2t*R2 - eye33) > 0.01 ||
+ abs(determinant(F)) > 0.01)
+ {
+ ts->printf( cvtest::TS::LOG, "The computed (by rectify) R1 and R2 are not orthogonal,"
+ "or the computed (by calibrate) F is not singular, testcase %d\n", testcase);
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+ return;
+ }
+
+ if(!checkPandROI(testcase, M1, D1, R1, P1, imgsize, roi1))
+ {
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ return;
+ }
+
+ if(!checkPandROI(testcase, M2, D2, R2, P2, imgsize, roi2))
+ {
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ return;
+ }
//check that Tx after rectification is equal to distance between cameras
double tx = fabs(P2.at<double>(0, 3) / P2.at<double>(0, 0));
if (fabs(tx - norm(T)) > 1e-5)
{
- ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
- return;
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ return;
}
//check that Q reprojects points before the camera
CV_Assert(reprojectedTestPoint.type() == CV_64FC1);
if( reprojectedTestPoint.at<double>(2) / reprojectedTestPoint.at<double>(3) < 0 )
{
- ts->printf( cvtest::TS::LOG, "A point after rectification is reprojected behind the camera, testcase %d\n", testcase);
- ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+ ts->printf( cvtest::TS::LOG, "A point after rectification is reprojected behind the camera, testcase %d\n", testcase);
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
//check that Q reprojects the same points as reconstructed by triangulation
if (norm(triangulatedPoints - reprojectedPoints) / sqrt((double)pointsCount) > requiredAccuracy)
{
- ts->printf( cvtest::TS::LOG, "Points reprojected with a matrix Q and points reconstructed by triangulation are different, testcase %d\n", testcase);
- ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+ ts->printf( cvtest::TS::LOG, "Points reprojected with a matrix Q and points reconstructed by triangulation are different, testcase %d\n", testcase);
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
}
//check correctMatches
}
}
- // rectifyUncalibrated
- CV_Assert( imgpt1.size() == imgpt2.size() );
- Mat _imgpt1( total, 1, CV_32FC2 ), _imgpt2( total, 1, CV_32FC2 );
- vector<vector<Point2f> >::const_iterator iit1 = imgpt1.begin();
- vector<vector<Point2f> >::const_iterator iit2 = imgpt2.begin();
- for( int pi = 0; iit1 != imgpt1.end(); ++iit1, ++iit2 )
- {
- vector<Point2f>::const_iterator pit1 = iit1->begin();
- vector<Point2f>::const_iterator pit2 = iit2->begin();
- CV_Assert( iit1->size() == iit2->size() );
- for( ; pit1 != iit1->end(); ++pit1, ++pit2, pi++ )
- {
- _imgpt1.at<Point2f>(pi,0) = Point2f( pit1->x, pit1->y );
- _imgpt2.at<Point2f>(pi,0) = Point2f( pit2->x, pit2->y );
- }
- }
-
- Mat _M1, _M2, _D1, _D2;
- vector<Mat> _R1, _R2, _T1, _T2;
- calibrateCamera( objpt, imgpt1, imgsize, _M1, _D1, _R1, _T1, 0 );
- calibrateCamera( objpt, imgpt2, imgsize, _M2, _D2, _R2, _T1, 0 );
- undistortPoints( _imgpt1, _imgpt1, _M1, _D1, Mat(), _M1 );
- undistortPoints( _imgpt2, _imgpt2, _M2, _D2, Mat(), _M2 );
-
- Mat matF, _H1, _H2;
- matF = findFundamentalMat( _imgpt1, _imgpt2 );
- rectifyUncalibrated( _imgpt1, _imgpt2, matF, imgsize, _H1, _H2 );
-
- Mat rectifPoints1, rectifPoints2;
- perspectiveTransform( _imgpt1, rectifPoints1, _H1 );
- perspectiveTransform( _imgpt2, rectifPoints2, _H2 );
-
- bool verticalStereo = abs(P2.at<double>(0,3)) < abs(P2.at<double>(1,3));
- double maxDiff_c = 0, maxDiff_uc = 0;
- for( int i = 0, k = 0; i < nframes; i++ )
- {
- vector<Point2f> temp[2];
- undistortPoints(Mat(imgpt1[i]), temp[0], M1, D1, R1, P1);
- undistortPoints(Mat(imgpt2[i]), temp[1], M2, D2, R2, P2);
-
- for( int j = 0; j < npoints; j++, k++ )
- {
- double diff_c = verticalStereo ? abs(temp[0][j].x - temp[1][j].x) : abs(temp[0][j].y - temp[1][j].y);
- Point2f d = rectifPoints1.at<Point2f>(k,0) - rectifPoints2.at<Point2f>(k,0);
- double diff_uc = verticalStereo ? abs(d.x) : abs(d.y);
- maxDiff_c = max(maxDiff_c, diff_c);
- maxDiff_uc = max(maxDiff_uc, diff_uc);
- if( maxDiff_c > maxScanlineDistErr_c )
- {
- ts->printf( cvtest::TS::LOG, "The distance between %s coordinates is too big(=%g) (used calibrated stereo), testcase %d\n",
- verticalStereo ? "x" : "y", diff_c, testcase);
- ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
- return;
- }
- if( maxDiff_uc > maxScanlineDistErr_uc )
- {
- ts->printf( cvtest::TS::LOG, "The distance between %s coordinates is too big(=%g) (used uncalibrated stereo), testcase %d\n",
- verticalStereo ? "x" : "y", diff_uc, testcase);
- ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
- return;
- }
- }
- }
-
- ts->printf( cvtest::TS::LOG, "Testcase %d. Max distance (calibrated) =%g\n"
- "Max distance (uncalibrated) =%g\n", testcase, maxDiff_c, maxDiff_uc );
- }
+ // rectifyUncalibrated
+ CV_Assert( imgpt1.size() == imgpt2.size() );
+ Mat _imgpt1( total, 1, CV_32FC2 ), _imgpt2( total, 1, CV_32FC2 );
+ vector<vector<Point2f> >::const_iterator iit1 = imgpt1.begin();
+ vector<vector<Point2f> >::const_iterator iit2 = imgpt2.begin();
+ for( int pi = 0; iit1 != imgpt1.end(); ++iit1, ++iit2 )
+ {
+ vector<Point2f>::const_iterator pit1 = iit1->begin();
+ vector<Point2f>::const_iterator pit2 = iit2->begin();
+ CV_Assert( iit1->size() == iit2->size() );
+ for( ; pit1 != iit1->end(); ++pit1, ++pit2, pi++ )
+ {
+ _imgpt1.at<Point2f>(pi,0) = Point2f( pit1->x, pit1->y );
+ _imgpt2.at<Point2f>(pi,0) = Point2f( pit2->x, pit2->y );
+ }
+ }
+
+ Mat _M1, _M2, _D1, _D2;
+ vector<Mat> _R1, _R2, _T1, _T2;
+ calibrateCamera( objpt, imgpt1, imgsize, _M1, _D1, _R1, _T1, 0 );
+ calibrateCamera( objpt, imgpt2, imgsize, _M2, _D2, _R2, _T1, 0 );
+ undistortPoints( _imgpt1, _imgpt1, _M1, _D1, Mat(), _M1 );
+ undistortPoints( _imgpt2, _imgpt2, _M2, _D2, Mat(), _M2 );
+
+ Mat matF, _H1, _H2;
+ matF = findFundamentalMat( _imgpt1, _imgpt2 );
+ rectifyUncalibrated( _imgpt1, _imgpt2, matF, imgsize, _H1, _H2 );
+
+ Mat rectifPoints1, rectifPoints2;
+ perspectiveTransform( _imgpt1, rectifPoints1, _H1 );
+ perspectiveTransform( _imgpt2, rectifPoints2, _H2 );
+
+ bool verticalStereo = abs(P2.at<double>(0,3)) < abs(P2.at<double>(1,3));
+ double maxDiff_c = 0, maxDiff_uc = 0;
+ for( int i = 0, k = 0; i < nframes; i++ )
+ {
+ vector<Point2f> temp[2];
+ undistortPoints(Mat(imgpt1[i]), temp[0], M1, D1, R1, P1);
+ undistortPoints(Mat(imgpt2[i]), temp[1], M2, D2, R2, P2);
+
+ for( int j = 0; j < npoints; j++, k++ )
+ {
+ double diff_c = verticalStereo ? abs(temp[0][j].x - temp[1][j].x) : abs(temp[0][j].y - temp[1][j].y);
+ Point2f d = rectifPoints1.at<Point2f>(k,0) - rectifPoints2.at<Point2f>(k,0);
+ double diff_uc = verticalStereo ? abs(d.x) : abs(d.y);
+ maxDiff_c = max(maxDiff_c, diff_c);
+ maxDiff_uc = max(maxDiff_uc, diff_uc);
+ if( maxDiff_c > maxScanlineDistErr_c )
+ {
+ ts->printf( cvtest::TS::LOG, "The distance between %s coordinates is too big(=%g) (used calibrated stereo), testcase %d\n",
+ verticalStereo ? "x" : "y", diff_c, testcase);
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ return;
+ }
+ if( maxDiff_uc > maxScanlineDistErr_uc )
+ {
+ ts->printf( cvtest::TS::LOG, "The distance between %s coordinates is too big(=%g) (used uncalibrated stereo), testcase %d\n",
+ verticalStereo ? "x" : "y", diff_uc, testcase);
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ return;
+ }
+ }
+ }
+
+ ts->printf( cvtest::TS::LOG, "Testcase %d. Max distance (calibrated) =%g\n"
+ "Max distance (uncalibrated) =%g\n", testcase, maxDiff_c, maxDiff_uc );
+ }
}
//-------------------------------- CV_StereoCalibrationTest_C ------------------------------
class CV_StereoCalibrationTest_C : public CV_StereoCalibrationTest
{
public:
- CV_StereoCalibrationTest_C() {}
+ CV_StereoCalibrationTest_C() {}
protected:
- virtual double calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
- const vector<vector<Point2f> >& imagePoints1,
- const vector<vector<Point2f> >& imagePoints2,
- Mat& cameraMatrix1, Mat& distCoeffs1,
- Mat& cameraMatrix2, Mat& distCoeffs2,
- Size imageSize, Mat& R, Mat& T,
- Mat& E, Mat& F, TermCriteria criteria, int flags );
- virtual void rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
- const Mat& cameraMatrix2, const Mat& distCoeffs2,
- Size imageSize, const Mat& R, const Mat& T,
- Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
- double alpha, Size newImageSize,
- Rect* validPixROI1, Rect* validPixROI2, int flags );
- virtual bool rectifyUncalibrated( const Mat& points1,
- const Mat& points2, const Mat& F, Size imgSize,
- Mat& H1, Mat& H2, double threshold=5 );
- virtual void triangulate( const Mat& P1, const Mat& P2,
+ virtual double calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
+ const vector<vector<Point2f> >& imagePoints1,
+ const vector<vector<Point2f> >& imagePoints2,
+ Mat& cameraMatrix1, Mat& distCoeffs1,
+ Mat& cameraMatrix2, Mat& distCoeffs2,
+ Size imageSize, Mat& R, Mat& T,
+ Mat& E, Mat& F, TermCriteria criteria, int flags );
+ virtual void rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
+ const Mat& cameraMatrix2, const Mat& distCoeffs2,
+ Size imageSize, const Mat& R, const Mat& T,
+ Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
+ double alpha, Size newImageSize,
+ Rect* validPixROI1, Rect* validPixROI2, int flags );
+ virtual bool rectifyUncalibrated( const Mat& points1,
+ const Mat& points2, const Mat& F, Size imgSize,
+ Mat& H1, Mat& H2, double threshold=5 );
+ virtual void triangulate( const Mat& P1, const Mat& P2,
const Mat &points1, const Mat &points2,
Mat &points4D );
- virtual void correct( const Mat& F,
+ virtual void correct( const Mat& F,
const Mat &points1, const Mat &points2,
Mat &newPoints1, Mat &newPoints2 );
};
double CV_StereoCalibrationTest_C::calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
- const vector<vector<Point2f> >& imagePoints1,
- const vector<vector<Point2f> >& imagePoints2,
- Mat& cameraMatrix1, Mat& distCoeffs1,
- Mat& cameraMatrix2, Mat& distCoeffs2,
- Size imageSize, Mat& R, Mat& T,
- Mat& E, Mat& F, TermCriteria criteria, int flags )
+ const vector<vector<Point2f> >& imagePoints1,
+ const vector<vector<Point2f> >& imagePoints2,
+ Mat& cameraMatrix1, Mat& distCoeffs1,
+ Mat& cameraMatrix2, Mat& distCoeffs2,
+ Size imageSize, Mat& R, Mat& T,
+ Mat& E, Mat& F, TermCriteria criteria, int flags )
{
- cameraMatrix1.create( 3, 3, CV_64F );
- cameraMatrix2.create( 3, 3, CV_64F);
- distCoeffs1.create( 1, 5, CV_64F);
- distCoeffs2.create( 1, 5, CV_64F);
- R.create(3, 3, CV_64F);
- T.create(3, 1, CV_64F);
- E.create(3, 3, CV_64F);
- F.create(3, 3, CV_64F);
-
- int nimages = (int)objectPoints.size(), total = 0;
- for( int i = 0; i < nimages; i++ )
- {
- total += (int)objectPoints[i].size();
- }
-
- Mat npoints( 1, nimages, CV_32S ),
- objPt( 1, total, DataType<Point3f>::type ),
- imgPt( 1, total, DataType<Point2f>::type ),
- imgPt2( 1, total, DataType<Point2f>::type );
-
- Point2f* imgPtData2 = imgPt2.ptr<Point2f>();
- Point3f* objPtData = objPt.ptr<Point3f>();
- Point2f* imgPtData = imgPt.ptr<Point2f>();
- for( int i = 0, ni = 0, j = 0; i < nimages; i++, j += ni )
- {
- ni = (int)objectPoints[i].size();
- ((int*)npoints.data)[i] = ni;
- std::copy(objectPoints[i].begin(), objectPoints[i].end(), objPtData + j);
- std::copy(imagePoints1[i].begin(), imagePoints1[i].end(), imgPtData + j);
- std::copy(imagePoints2[i].begin(), imagePoints2[i].end(), imgPtData2 + j);
- }
- CvMat _objPt = objPt, _imgPt = imgPt, _imgPt2 = imgPt2, _npoints = npoints;
- CvMat _cameraMatrix1 = cameraMatrix1, _distCoeffs1 = distCoeffs1;
- CvMat _cameraMatrix2 = cameraMatrix2, _distCoeffs2 = distCoeffs2;
- CvMat matR = R, matT = T, matE = E, matF = F;
-
- return cvStereoCalibrate(&_objPt, &_imgPt, &_imgPt2, &_npoints, &_cameraMatrix1,
- &_distCoeffs1, &_cameraMatrix2, &_distCoeffs2, imageSize,
- &matR, &matT, &matE, &matF, criteria, flags );
+ cameraMatrix1.create( 3, 3, CV_64F );
+ cameraMatrix2.create( 3, 3, CV_64F);
+ distCoeffs1.create( 1, 5, CV_64F);
+ distCoeffs2.create( 1, 5, CV_64F);
+ R.create(3, 3, CV_64F);
+ T.create(3, 1, CV_64F);
+ E.create(3, 3, CV_64F);
+ F.create(3, 3, CV_64F);
+
+ int nimages = (int)objectPoints.size(), total = 0;
+ for( int i = 0; i < nimages; i++ )
+ {
+ total += (int)objectPoints[i].size();
+ }
+
+ Mat npoints( 1, nimages, CV_32S ),
+ objPt( 1, total, DataType<Point3f>::type ),
+ imgPt( 1, total, DataType<Point2f>::type ),
+ imgPt2( 1, total, DataType<Point2f>::type );
+
+ Point2f* imgPtData2 = imgPt2.ptr<Point2f>();
+ Point3f* objPtData = objPt.ptr<Point3f>();
+ Point2f* imgPtData = imgPt.ptr<Point2f>();
+ for( int i = 0, ni = 0, j = 0; i < nimages; i++, j += ni )
+ {
+ ni = (int)objectPoints[i].size();
+ ((int*)npoints.data)[i] = ni;
+ std::copy(objectPoints[i].begin(), objectPoints[i].end(), objPtData + j);
+ std::copy(imagePoints1[i].begin(), imagePoints1[i].end(), imgPtData + j);
+ std::copy(imagePoints2[i].begin(), imagePoints2[i].end(), imgPtData2 + j);
+ }
+ CvMat _objPt = objPt, _imgPt = imgPt, _imgPt2 = imgPt2, _npoints = npoints;
+ CvMat _cameraMatrix1 = cameraMatrix1, _distCoeffs1 = distCoeffs1;
+ CvMat _cameraMatrix2 = cameraMatrix2, _distCoeffs2 = distCoeffs2;
+ CvMat matR = R, matT = T, matE = E, matF = F;
+
+ return cvStereoCalibrate(&_objPt, &_imgPt, &_imgPt2, &_npoints, &_cameraMatrix1,
+ &_distCoeffs1, &_cameraMatrix2, &_distCoeffs2, imageSize,
+ &matR, &matT, &matE, &matF, criteria, flags );
}
void CV_StereoCalibrationTest_C::rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
- const Mat& cameraMatrix2, const Mat& distCoeffs2,
- Size imageSize, const Mat& R, const Mat& T,
- Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
- double alpha, Size newImageSize,
- Rect* validPixROI1, Rect* validPixROI2, int flags )
+ const Mat& cameraMatrix2, const Mat& distCoeffs2,
+ Size imageSize, const Mat& R, const Mat& T,
+ Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
+ double alpha, Size newImageSize,
+ Rect* validPixROI1, Rect* validPixROI2, int flags )
{
- int rtype = CV_64F;
- R1.create(3, 3, rtype);
- R2.create(3, 3, rtype);
- P1.create(3, 4, rtype);
- P2.create(3, 4, rtype);
- Q.create(4, 4, rtype);
- CvMat _cameraMatrix1 = cameraMatrix1, _distCoeffs1 = distCoeffs1;
- CvMat _cameraMatrix2 = cameraMatrix2, _distCoeffs2 = distCoeffs2;
- CvMat matR = R, matT = T, _R1 = R1, _R2 = R2, _P1 = P1, _P2 = P2, matQ = Q;
- cvStereoRectify( &_cameraMatrix1, &_cameraMatrix2, &_distCoeffs1, &_distCoeffs2,
- imageSize, &matR, &matT, &_R1, &_R2, &_P1, &_P2, &matQ, flags,
- alpha, newImageSize, (CvRect*)validPixROI1, (CvRect*)validPixROI2);
+ int rtype = CV_64F;
+ R1.create(3, 3, rtype);
+ R2.create(3, 3, rtype);
+ P1.create(3, 4, rtype);
+ P2.create(3, 4, rtype);
+ Q.create(4, 4, rtype);
+ CvMat _cameraMatrix1 = cameraMatrix1, _distCoeffs1 = distCoeffs1;
+ CvMat _cameraMatrix2 = cameraMatrix2, _distCoeffs2 = distCoeffs2;
+ CvMat matR = R, matT = T, _R1 = R1, _R2 = R2, _P1 = P1, _P2 = P2, matQ = Q;
+ cvStereoRectify( &_cameraMatrix1, &_cameraMatrix2, &_distCoeffs1, &_distCoeffs2,
+ imageSize, &matR, &matT, &_R1, &_R2, &_P1, &_P2, &matQ, flags,
+ alpha, newImageSize, (CvRect*)validPixROI1, (CvRect*)validPixROI2);
}
bool CV_StereoCalibrationTest_C::rectifyUncalibrated( const Mat& points1,
- const Mat& points2, const Mat& F, Size imgSize, Mat& H1, Mat& H2, double threshold )
+ const Mat& points2, const Mat& F, Size imgSize, Mat& H1, Mat& H2, double threshold )
{
- H1.create(3, 3, CV_64F);
- H2.create(3, 3, CV_64F);
- CvMat _pt1 = points1, _pt2 = points2, matF, *pF=0, _H1 = H1, _H2 = H2;
- if( F.size() == Size(3, 3) )
- pF = &(matF = F);
- return cvStereoRectifyUncalibrated(&_pt1, &_pt2, pF, imgSize, &_H1, &_H2, threshold) > 0;
+ H1.create(3, 3, CV_64F);
+ H2.create(3, 3, CV_64F);
+ CvMat _pt1 = points1, _pt2 = points2, matF, *pF=0, _H1 = H1, _H2 = H2;
+ if( F.size() == Size(3, 3) )
+ pF = &(matF = F);
+ return cvStereoRectifyUncalibrated(&_pt1, &_pt2, pF, imgSize, &_H1, &_H2, threshold) > 0;
}
void CV_StereoCalibrationTest_C::triangulate( const Mat& P1, const Mat& P2,
class CV_StereoCalibrationTest_CPP : public CV_StereoCalibrationTest
{
public:
- CV_StereoCalibrationTest_CPP() {}
+ CV_StereoCalibrationTest_CPP() {}
protected:
- virtual double calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
- const vector<vector<Point2f> >& imagePoints1,
- const vector<vector<Point2f> >& imagePoints2,
- Mat& cameraMatrix1, Mat& distCoeffs1,
- Mat& cameraMatrix2, Mat& distCoeffs2,
- Size imageSize, Mat& R, Mat& T,
- Mat& E, Mat& F, TermCriteria criteria, int flags );
- virtual void rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
- const Mat& cameraMatrix2, const Mat& distCoeffs2,
- Size imageSize, const Mat& R, const Mat& T,
- Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
- double alpha, Size newImageSize,
- Rect* validPixROI1, Rect* validPixROI2, int flags );
- virtual bool rectifyUncalibrated( const Mat& points1,
- const Mat& points2, const Mat& F, Size imgSize,
- Mat& H1, Mat& H2, double threshold=5 );
- virtual void triangulate( const Mat& P1, const Mat& P2,
+ virtual double calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
+ const vector<vector<Point2f> >& imagePoints1,
+ const vector<vector<Point2f> >& imagePoints2,
+ Mat& cameraMatrix1, Mat& distCoeffs1,
+ Mat& cameraMatrix2, Mat& distCoeffs2,
+ Size imageSize, Mat& R, Mat& T,
+ Mat& E, Mat& F, TermCriteria criteria, int flags );
+ virtual void rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
+ const Mat& cameraMatrix2, const Mat& distCoeffs2,
+ Size imageSize, const Mat& R, const Mat& T,
+ Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
+ double alpha, Size newImageSize,
+ Rect* validPixROI1, Rect* validPixROI2, int flags );
+ virtual bool rectifyUncalibrated( const Mat& points1,
+ const Mat& points2, const Mat& F, Size imgSize,
+ Mat& H1, Mat& H2, double threshold=5 );
+ virtual void triangulate( const Mat& P1, const Mat& P2,
const Mat &points1, const Mat &points2,
Mat &points4D );
virtual void correct( const Mat& F,
};
double CV_StereoCalibrationTest_CPP::calibrateStereoCamera( const vector<vector<Point3f> >& objectPoints,
- const vector<vector<Point2f> >& imagePoints1,
- const vector<vector<Point2f> >& imagePoints2,
- Mat& cameraMatrix1, Mat& distCoeffs1,
- Mat& cameraMatrix2, Mat& distCoeffs2,
- Size imageSize, Mat& R, Mat& T,
- Mat& E, Mat& F, TermCriteria criteria, int flags )
+ const vector<vector<Point2f> >& imagePoints1,
+ const vector<vector<Point2f> >& imagePoints2,
+ Mat& cameraMatrix1, Mat& distCoeffs1,
+ Mat& cameraMatrix2, Mat& distCoeffs2,
+ Size imageSize, Mat& R, Mat& T,
+ Mat& E, Mat& F, TermCriteria criteria, int flags )
{
- return stereoCalibrate( objectPoints, imagePoints1, imagePoints2,
- cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
- imageSize, R, T, E, F, criteria, flags );
+ return stereoCalibrate( objectPoints, imagePoints1, imagePoints2,
+ cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
+ imageSize, R, T, E, F, criteria, flags );
}
void CV_StereoCalibrationTest_CPP::rectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
- const Mat& cameraMatrix2, const Mat& distCoeffs2,
- Size imageSize, const Mat& R, const Mat& T,
- Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
- double alpha, Size newImageSize,
- Rect* validPixROI1, Rect* validPixROI2, int flags )
+ const Mat& cameraMatrix2, const Mat& distCoeffs2,
+ Size imageSize, const Mat& R, const Mat& T,
+ Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
+ double alpha, Size newImageSize,
+ Rect* validPixROI1, Rect* validPixROI2, int flags )
{
- stereoRectify( cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
- imageSize, R, T, R1, R2, P1, P2, Q, flags, alpha, newImageSize,validPixROI1, validPixROI2 );
+ stereoRectify( cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
+ imageSize, R, T, R1, R2, P1, P2, Q, flags, alpha, newImageSize,validPixROI1, validPixROI2 );
}
bool CV_StereoCalibrationTest_CPP::rectifyUncalibrated( const Mat& points1,
- const Mat& points2, const Mat& F, Size imgSize, Mat& H1, Mat& H2, double threshold )
+ const Mat& points2, const Mat& F, Size imgSize, Mat& H1, Mat& H2, double threshold )
{
- return stereoRectifyUncalibrated( points1, points2, F, imgSize, H1, H2, threshold );
+ return stereoRectifyUncalibrated( points1, points2, F, imgSize, H1, H2, threshold );
}
void CV_StereoCalibrationTest_CPP::triangulate( const Mat& P1, const Mat& P2,
using namespace std;
//template<class T> ostream& operator<<(ostream& out, const Mat_<T>& mat)
-//{
+//{
// for(Mat_<T>::const_iterator pos = mat.begin(), end = mat.end(); pos != end; ++pos)
// out << *pos << " ";
// return out;
//}
-//ostream& operator<<(ostream& out, const Mat& mat) { return out << Mat_<double>(mat); }
+//ostream& operator<<(ostream& out, const Mat& mat) { return out << Mat_<double>(mat); }
Mat calcRvec(const vector<Point3f>& points, const Size& cornerSize)
-{
+{
Point3f p00 = points[0];
Point3f p10 = points[1];
- Point3f p01 = points[cornerSize.width];
+ Point3f p01 = points[cornerSize.width];
Vec3d ex(p10.x - p00.x, p10.y - p00.y, p10.z - p00.z);
- Vec3d ey(p01.x - p00.x, p01.y - p00.y, p01.z - p00.z);
- Vec3d ez = ex.cross(ey);
+ Vec3d ey(p01.x - p00.x, p01.y - p00.y, p01.z - p00.z);
+ Vec3d ez = ex.cross(ey);
Mat rot(3, 3, CV_64F);
*rot.ptr<Vec3d>(0) = ex;
{
}
~CV_CalibrateCameraArtificialTest() {}
-protected:
+protected:
int r;
const static int JUST_FIND_CORNERS = 0;
{
ts->printf( cvtest::TS::LOG, "Bad shape of camera matrix returned \n");
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
- }
+ }
double fx_e = camMat_est.at<double>(0, 0), fy_e = camMat_est.at<double>(1, 1);
double cx_e = camMat_est.at<double>(0, 2), cy_e = camMat_est.at<double>(1, 2);
const double eps = 1e-2;
const double dlt = 1e-5;
- bool fail = checkErr(fx_e, fx, eps, dlt) || checkErr(fy_e, fy, eps, dlt) ||
- checkErr(cx_e, cx, eps, dlt) || checkErr(cy_e, cy, eps, dlt);
+ bool fail = checkErr(fx_e, fx, eps, dlt) || checkErr(fy_e, fy, eps, dlt) ||
+ checkErr(cx_e, cx, eps, dlt) || checkErr(cy_e, cy, eps, dlt);
if (fail)
{
- ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
- }
+ ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
+ }
ts->printf( cvtest::TS::LOG, "%d) Expected [Fx Fy Cx Cy] = [%.3f %.3f %.3f %.3f]\n", r, fx, fy, cx, cy);
- ts->printf( cvtest::TS::LOG, "%d) Estimated [Fx Fy Cx Cy] = [%.3f %.3f %.3f %.3f]\n", r, fx_e, fy_e, cx_e, cy_e);
+ ts->printf( cvtest::TS::LOG, "%d) Estimated [Fx Fy Cx Cy] = [%.3f %.3f %.3f %.3f]\n", r, fx_e, fy_e, cx_e, cy_e);
}
void compareDistCoeffs(const Mat_<double>& distCoeffs, const Mat& distCoeffs_est)
- {
+ {
const double *dt_e = distCoeffs_est.ptr<double>();
double k1_e = dt_e[0], k2_e = dt_e[1], k3_e = dt_e[4];
double p1 = distCoeffs(0, 2), p2 = distCoeffs(0, 3);
const double eps = 5e-2;
- const double dlt = 1e-3;
+ const double dlt = 1e-3;
const double eps_k3 = 5;
- const double dlt_k3 = 1e-3;
+ const double dlt_k3 = 1e-3;
- bool fail = checkErr(k1_e, k1, eps, dlt) || checkErr(k2_e, k2, eps, dlt) || checkErr(k3_e, k3, eps_k3, dlt_k3) ||
- checkErr(p1_e, p1, eps, dlt) || checkErr(p2_e, p2, eps, dlt);
+ bool fail = checkErr(k1_e, k1, eps, dlt) || checkErr(k2_e, k2, eps, dlt) || checkErr(k3_e, k3, eps_k3, dlt_k3) ||
+ checkErr(p1_e, p1, eps, dlt) || checkErr(p2_e, p2, eps, dlt);
if (fail)
{
// commented according to vp123's recomendation. TODO - improve accuaracy
- //ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ss
- }
+ //ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ss
+ }
ts->printf( cvtest::TS::LOG, "%d) DistCoeff exp=(%.2f, %.2f, %.4f, %.4f %.2f)\n", r, k1, k2, p1, p2, k3);
- ts->printf( cvtest::TS::LOG, "%d) DistCoeff est=(%.2f, %.2f, %.4f, %.4f %.2f)\n", r, k1_e, k2_e, p1_e, p2_e, k3_e);
+ ts->printf( cvtest::TS::LOG, "%d) DistCoeff est=(%.2f, %.2f, %.4f, %.4f %.2f)\n", r, k1_e, k2_e, p1_e, p2_e, k3_e);
ts->printf( cvtest::TS::LOG, "%d) AbsError = [%.5f %.5f %.5f %.5f %.5f]\n", r, fabs(k1-k1_e), fabs(k2-k2_e), fabs(p1-p1_e), fabs(p2-p2_e), fabs(k3-k3_e));
}
const Point3d& tvec = *tvecs[i].ptr<Point3d>();
const Point3d& tvec_est = *tvecs_est[i].ptr<Point3d>();
- if (norm(tvec_est - tvec) > eps* (norm(tvec) + dlt))
+ if (norm(tvec_est - tvec) > eps* (norm(tvec) + dlt))
{
if (err_count++ < errMsgNum)
{
- if (err_count == errMsgNum)
- ts->printf( cvtest::TS::LOG, "%d) ...\n", r);
- else
+ if (err_count == errMsgNum)
+ ts->printf( cvtest::TS::LOG, "%d) ...\n", r);
+ else
{
- ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned tvecs. Index = %d\n", r, i);
+ ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned tvecs. Index = %d\n", r, i);
ts->printf( cvtest::TS::LOG, "%d) norm(tvec_est - tvec) = %f, norm(tvec_exp) = %f \n", r, norm(tvec_est - tvec), norm(tvec));
}
}
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
- }
+ }
}
}
int err_count = 0;
const int errMsgNum = 4;
for(size_t i = 0; i < rvecs.size(); ++i)
- {
+ {
Rodrigues(rvecs[i], rmat);
- Rodrigues(rvecs_est[i], rmat_est);
+ Rodrigues(rvecs_est[i], rmat_est);
if (norm(rmat_est, rmat) > eps* (norm(rmat) + dlt))
{
if (err_count++ < errMsgNum)
{
if (err_count == errMsgNum)
- ts->printf( cvtest::TS::LOG, "%d) ...\n", r);
+ ts->printf( cvtest::TS::LOG, "%d) ...\n", r);
else
{
- ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned rvecs (rotation matrs). Index = %d\n", r, i);
- ts->printf( cvtest::TS::LOG, "%d) norm(rot_mat_est - rot_mat_exp) = %f, norm(rot_mat_exp) = %f \n", r, norm(rmat_est, rmat), norm(rmat));
+ ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned rvecs (rotation matrs). Index = %d\n", r, i);
+ ts->printf( cvtest::TS::LOG, "%d) norm(rot_mat_est - rot_mat_exp) = %f, norm(rot_mat_exp) = %f \n", r, norm(rmat_est, rmat), norm(rmat));
}
}
}
}
- double reprojectErrorWithoutIntrinsics(const vector<Point3f>& cb3d, const vector<Mat>& rvecs_exp, const vector<Mat>& tvecs_exp,
+ double reprojectErrorWithoutIntrinsics(const vector<Point3f>& cb3d, const vector<Mat>& _rvecs_exp, const vector<Mat>& _tvecs_exp,
const vector<Mat>& rvecs_est, const vector<Mat>& tvecs_est)
- {
+ {
const static Mat eye33 = Mat::eye(3, 3, CV_64F);
const static Mat zero15 = Mat::zeros(1, 5, CV_64F);
- Mat chessboard3D(cb3d);
+ Mat _chessboard3D(cb3d);
vector<Point2f> uv_exp, uv_est;
- double res = 0;
+ double res = 0;
- for(size_t i = 0; i < rvecs_exp.size(); ++i)
- {
- projectPoints(chessboard3D, rvecs_exp[i], tvecs_exp[i], eye33, zero15, uv_exp);
- projectPoints(chessboard3D, rvecs_est[i], tvecs_est[i], eye33, zero15, uv_est);
+ for(size_t i = 0; i < rvecs_exp.size(); ++i)
+ {
+ projectPoints(_chessboard3D, _rvecs_exp[i], _tvecs_exp[i], eye33, zero15, uv_exp);
+ projectPoints(_chessboard3D, rvecs_est[i], tvecs_est[i], eye33, zero15, uv_est);
for(size_t j = 0; j < cb3d.size(); ++j)
res += norm(uv_exp[i] - uv_est[i]);
}
Size2f sqSile;
vector<Point3f> chessboard3D;
- vector<Mat> boards, rvecs_exp, tvecs_exp, rvecs_spnp, tvecs_spnp;
+ vector<Mat> boards, rvecs_exp, tvecs_exp, rvecs_spnp, tvecs_spnp;
vector< vector<Point3f> > objectPoints;
vector< vector<Point2f> > imagePoints_art;
vector< vector<Point2f> > imagePoints_findCb;
imagePoints_findCb.clear();
vector<Point2f> corners_art, corners_fcb;
- for(size_t i = 0; i < brdsNum; ++i)
- {
+ for(size_t i = 0; i < brdsNum; ++i)
+ {
for(;;)
{
boards[i] = cbg(bg, camMat, distCoeffs, sqSile, corners_art);
- if(findChessboardCorners(boards[i], cornersSize, corners_fcb))
- break;
- }
+ if(findChessboardCorners(boards[i], cornersSize, corners_fcb))
+ break;
+ }
//cv::namedWindow("CB"); imshow("CB", boards[i]); cv::waitKey();
- imagePoints_art.push_back(corners_art);
+ imagePoints_art.push_back(corners_art);
imagePoints_findCb.push_back(corners_fcb);
tvecs_exp[i].create(1, 3, CV_64F);
*tvecs_exp[i].ptr<Point3d>() = cbg.corners3d[0];
- rvecs_exp[i] = calcRvec(cbg.corners3d, cbg.cornersSize());
+ rvecs_exp[i] = calcRvec(cbg.corners3d, cbg.cornersSize());
}
}
void runTest(const Size& imgSize, const Mat_<double>& camMat, const Mat_<double>& distCoeffs, size_t brdsNum, const Size& cornersSize, int flag = 0)
- {
+ {
const TermCriteria tc(TermCriteria::EPS|TermCriteria::MAX_ITER, 30, 0.1);
vector< vector<Point2f> > imagePoints;
case JUST_FIND_CORNERS: imagePoints = imagePoints_findCb; break;
case ARTIFICIAL_CORNERS: imagePoints = imagePoints_art; break;
- case USE_CORNERS_SUBPIX:
+ case USE_CORNERS_SUBPIX:
for(size_t i = 0; i < brdsNum; ++i)
- {
+ {
Mat gray;
cvtColor(boards[i], gray, CV_BGR2GRAY);
vector<Point2f> tmp = imagePoints_findCb[i];
break;
case USE_4QUAD_CORNERS:
for(size_t i = 0; i < brdsNum; ++i)
- {
+ {
Mat gray;
- cvtColor(boards[i], gray, CV_BGR2GRAY);
+ cvtColor(boards[i], gray, CV_BGR2GRAY);
vector<Point2f> tmp = imagePoints_findCb[i];
find4QuadCornerSubpix(gray, tmp, Size(5, 5));
imagePoints.push_back(tmp);
default:
throw std::exception();
}
-
+
Mat camMat_est = Mat::eye(3, 3, CV_64F), distCoeffs_est = Mat::zeros(1, 5, CV_64F);
vector<Mat> rvecs_est, tvecs_est;
compareCameraMatrs(camMat, camMat_est);
compareDistCoeffs(distCoeffs, distCoeffs_est);
compareShiftVecs(tvecs_exp, tvecs_est);
- compareRotationVecs(rvecs_exp, rvecs_est);
+ compareRotationVecs(rvecs_exp, rvecs_est);
- double rep_errorWOI = reprojectErrorWithoutIntrinsics(chessboard3D, rvecs_exp, tvecs_exp, rvecs_est, tvecs_est);
+ double rep_errorWOI = reprojectErrorWithoutIntrinsics(chessboard3D, rvecs_exp, tvecs_exp, rvecs_est, tvecs_est);
rep_errorWOI /= brdsNum * cornersSize.area();
const double thres2 = 0.01;
{
ts->printf( cvtest::TS::LOG, "%d) Too big reproject error without intrinsics = %f\n", r, rep_errorWOI);
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
- }
-
+ }
+
ts->printf( cvtest::TS::LOG, "%d) Testing solvePnP...\n", r);
rvecs_spnp.resize(brdsNum);
tvecs_spnp.resize(brdsNum);
solvePnP(Mat(objectPoints[i]), Mat(imagePoints[i]), camMat, distCoeffs, rvecs_spnp[i], tvecs_spnp[i]);
compareShiftVecs(tvecs_exp, tvecs_spnp);
- compareRotationVecs(rvecs_exp, rvecs_spnp);
+ compareRotationVecs(rvecs_exp, rvecs_spnp);
}
void run(int)
- {
+ {
ts->set_failed_test_info(cvtest::TS::OK);
RNG& rng = theRNG();
int progress = 0;
int repeat_num = 3;
for(r = 0; r < repeat_num; ++r)
- {
- const int brds_num = 20;
+ {
+ const int brds_num = 20;
- Mat bg(Size(640, 480), CV_8UC3);
- randu(bg, Scalar::all(32), Scalar::all(255));
+ Mat bg(Size(640, 480), CV_8UC3);
+ randu(bg, Scalar::all(32), Scalar::all(255));
GaussianBlur(bg, bg, Size(5, 5), 2);
double fx = 300 + (20 * (double)rng - 10);
Mat_<double> distCoeffs(1, 5, 0.0);
distCoeffs << k1, k2, p1, p2, k3;
- ChessBoardGenerator cbg(Size(9, 8));
+ ChessBoardGenerator cbg(Size(9, 8));
cbg.min_cos = 0.9;
cbg.cov = 0.8;
progress = update_progress(progress, r, repeat_num, 0);
- ts->printf( cvtest::TS::LOG, "\n");
+ ts->printf( cvtest::TS::LOG, "\n");
prepareForTest(bg, camMat, distCoeffs, brds_num, cbg);
- ts->printf( cvtest::TS::LOG, "artificial corners\n");
- runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), ARTIFICIAL_CORNERS);
+ ts->printf( cvtest::TS::LOG, "artificial corners\n");
+ runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), ARTIFICIAL_CORNERS);
progress = update_progress(progress, r, repeat_num, 0);
ts->printf( cvtest::TS::LOG, "findChessboard corners\n");
- runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), JUST_FIND_CORNERS);
+ runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), JUST_FIND_CORNERS);
progress = update_progress(progress, r, repeat_num, 0);
ts->printf( cvtest::TS::LOG, "cornersSubPix corners\n");
progress = update_progress(progress, r, repeat_num, 0);
}
}
-};
+};
TEST(Calib3d_CalibrateCamera_CPP, accuracy_on_artificial_data) { CV_CalibrateCameraArtificialTest test; test.safe_run(); }
{
Mat rgb( gray.size(), CV_8U);
merge(vector<Mat>(3, gray), rgb);
-
+
for(size_t i = 0; i < v.size(); i++ )
- circle( rgb, v[i], 3, CV_RGB(255, 0, 0), CV_FILLED);
+ circle( rgb, v[i], 3, CV_RGB(255, 0, 0), CV_FILLED);
if( !u.empty() )
{
}
if (!v.empty())
{
- Mat corners((int)v.size(), 1, CV_32FC2, (void*)&v[0]);
+ Mat corners((int)v.size(), 1, CV_32FC2, (void*)&v[0]);
drawChessboardCorners( rgb, pattern_size, corners, was_found );
}
//namedWindow( "test", 0 ); imshow( "test", rgb ); waitKey(0);
//printf("\n");
err = min(err, err1);
}
-
+
#if defined(_L2_ERR)
err = sqrt(err/count_exp);
#endif //_L2_ERR
-
+
return err;
}
/* ///////////////////// chess_corner_test ///////////////////////// */
void CV_ChessboardDetectorTest::run( int /*start_from */)
{
- cvtest::TS& ts = *this->ts;
- ts.set_failed_test_info( cvtest::TS::OK );
+ ts->set_failed_test_info( cvtest::TS::OK );
/*if (!checkByGenerator())
return;*/
{
case CHESSBOARD:
checkByGenerator();
- if (ts.get_err_code() != cvtest::TS::OK)
+ if (ts->get_err_code() != cvtest::TS::OK)
{
break;
}
run_batch("negative_list.dat");
- if (ts.get_err_code() != cvtest::TS::OK)
+ if (ts->get_err_code() != cvtest::TS::OK)
{
break;
}
run_batch("chessboard_list.dat");
- if (ts.get_err_code() != cvtest::TS::OK)
+ if (ts->get_err_code() != cvtest::TS::OK)
{
break;
}
-
+
run_batch("chessboard_list_subpixel.dat");
break;
case CIRCLES_GRID:
void CV_ChessboardDetectorTest::run_batch( const string& filename )
{
- cvtest::TS& ts = *this->ts;
-
- ts.printf(cvtest::TS::LOG, "\nRunning batch %s\n", filename.c_str());
+ ts->printf(cvtest::TS::LOG, "\nRunning batch %s\n", filename.c_str());
//#define WRITE_POINTS 1
-#ifndef WRITE_POINTS
+#ifndef WRITE_POINTS
double max_rough_error = 0, max_precise_error = 0;
#endif
string folder;
switch( pattern )
{
case CHESSBOARD:
- folder = string(ts.get_data_path()) + "cameracalibration/";
+ folder = string(ts->get_data_path()) + "cameracalibration/";
break;
case CIRCLES_GRID:
- folder = string(ts.get_data_path()) + "cameracalibration/circles/";
+ folder = string(ts->get_data_path()) + "cameracalibration/circles/";
break;
case ASYMMETRIC_CIRCLES_GRID:
- folder = string(ts.get_data_path()) + "cameracalibration/asymmetric_circles/";
+ folder = string(ts->get_data_path()) + "cameracalibration/asymmetric_circles/";
break;
}
FileStorage fs( folder + filename, FileStorage::READ );
FileNode board_list = fs["boards"];
-
+
if( !fs.isOpened() || board_list.empty() || !board_list.isSeq() || board_list.size() % 2 != 0 )
{
- ts.printf( cvtest::TS::LOG, "%s can not be readed or is not valid\n", (folder + filename).c_str() );
- ts.printf( cvtest::TS::LOG, "fs.isOpened=%d, board_list.empty=%d, board_list.isSeq=%d,board_list.size()%2=%d\n",
+ ts->printf( cvtest::TS::LOG, "%s can not be readed or is not valid\n", (folder + filename).c_str() );
+ ts->printf( cvtest::TS::LOG, "fs.isOpened=%d, board_list.empty=%d, board_list.isSeq=%d,board_list.size()%2=%d\n",
fs.isOpened(), (int)board_list.empty(), board_list.isSeq(), board_list.size()%2);
- ts.set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
+ ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
return;
}
for(int idx = 0; idx < max_idx; ++idx )
{
- ts.update_context( this, idx, true );
-
+ ts->update_context( this, idx, true );
+
/* read the image */
- string img_file = board_list[idx * 2];
+ string img_file = board_list[idx * 2];
Mat gray = imread( folder + img_file, 0);
-
+
if( gray.empty() )
{
- ts.printf( cvtest::TS::LOG, "one of chessboard images can't be read: %s\n", img_file.c_str() );
- ts.set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
+ ts->printf( cvtest::TS::LOG, "one of chessboard images can't be read: %s\n", img_file.c_str() );
+ ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
return;
}
- string filename = folder + (string)board_list[idx * 2 + 1];
+ string _filename = folder + (string)board_list[idx * 2 + 1];
bool doesContatinChessboard;
Mat expected;
{
- FileStorage fs(filename, FileStorage::READ);
- fs["corners"] >> expected;
- fs["isFound"] >> doesContatinChessboard;
- fs.release();
- }
- size_t count_exp = static_cast<size_t>(expected.cols * expected.rows);
+ FileStorage fs1(_filename, FileStorage::READ);
+ fs1["corners"] >> expected;
+ fs1["isFound"] >> doesContatinChessboard;
+ fs1.release();
+ }
+ size_t count_exp = static_cast<size_t>(expected.cols * expected.rows);
Size pattern_size = expected.size();
vector<Point2f> v;
break;
}
show_points( gray, Mat(), v, pattern_size, result );
-
+
if( result ^ doesContatinChessboard || v.size() != count_exp )
{
- ts.printf( cvtest::TS::LOG, "chessboard is detected incorrectly in %s\n", img_file.c_str() );
- ts.set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+ ts->printf( cvtest::TS::LOG, "chessboard is detected incorrectly in %s\n", img_file.c_str() );
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
#if 1
if( err > precise_success_error_level )
{
- ts.printf( cvtest::TS::LOG, "Image %s: bad accuracy of adjusted corners %f\n", img_file.c_str(), err );
- ts.set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ ts->printf( cvtest::TS::LOG, "Image %s: bad accuracy of adjusted corners %f\n", img_file.c_str(), err );
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
#endif
- ts.printf(cvtest::TS::LOG, "Error on %s is %f\n", img_file.c_str(), err);
+ ts->printf(cvtest::TS::LOG, "Error on %s is %f\n", img_file.c_str(), err);
max_precise_error = MAX( max_precise_error, err );
-#endif
+#endif
}
#ifdef WRITE_POINTS
Mat mat_v(pattern_size, CV_32FC2, (void*)&v[0]);
- FileStorage fs(filename, FileStorage::WRITE);
+ FileStorage fs(_filename, FileStorage::WRITE);
fs << "isFound" << result;
fs << "corners" << mat_v;
fs.release();
#endif
progress = update_progress( progress, idx, max_idx, 0 );
- }
-
+ }
+
sum_error /= count;
- ts.printf(cvtest::TS::LOG, "Average error is %f\n", sum_error);
+ ts->printf(cvtest::TS::LOG, "Average error is %f\n", sum_error);
}
double calcErrorMinError(const Size& cornSz, const vector<Point2f>& corners_found, const vector<Point2f>& corners_generated)
{
- Mat m1(cornSz, CV_32FC2, (Point2f*)&corners_generated[0]);
+ Mat m1(cornSz, CV_32FC2, (Point2f*)&corners_generated[0]);
Mat m2; flip(m1, m2, 0);
Mat m3; flip(m1, m3, 1); m3 = m3.t(); flip(m3, m3, 1);
-
+
Mat m4 = m1.t(); flip(m4, m4, 1);
- double min1 = min(calcError(corners_found, m1), calcError(corners_found, m2));
- double min2 = min(calcError(corners_found, m3), calcError(corners_found, m4));
+ double min1 = min(calcError(corners_found, m1), calcError(corners_found, m2));
+ double min2 = min(calcError(corners_found, m3), calcError(corners_found, m4));
return min(min1, min2);
}
-bool validateData(const ChessBoardGenerator& cbg, const Size& imgSz,
+bool validateData(const ChessBoardGenerator& cbg, const Size& imgSz,
const vector<Point2f>& corners_generated)
{
Size cornersSize = cbg.cornersSize();
for(int j = 1; j < mat.cols - 2; ++j)
{
const Point2f& cur = mat(i, j);
-
+
tmp = norm( cur - mat(i + 1, j + 1) );
if (tmp < minNeibDist)
tmp = minNeibDist;
const double threshold = 0.25;
double cbsize = (max(cornersSize.width, cornersSize.height) + 1) * minNeibDist;
- int imgsize = min(imgSz.height, imgSz.width);
+ int imgsize = min(imgSz.height, imgSz.width);
return imgsize * threshold < cbsize;
}
bool CV_ChessboardDetectorTest::checkByGenerator()
-{
+{
bool res = true;
//theRNG() = 0x58e6e895b9913160;
//cv::DefaultRngAuto dra;
//theRNG() = *ts->get_rng();
- Mat bg(Size(800, 600), CV_8UC3, Scalar::all(255));
- randu(bg, Scalar::all(0), Scalar::all(255));
- GaussianBlur(bg, bg, Size(7,7), 3.0);
-
+ Mat bg(Size(800, 600), CV_8UC3, Scalar::all(255));
+ randu(bg, Scalar::all(0), Scalar::all(255));
+ GaussianBlur(bg, bg, Size(7,7), 3.0);
+
Mat_<float> camMat(3, 3);
camMat << 300.f, 0.f, bg.cols/2.f, 0, 300.f, bg.rows/2.f, 0.f, 0.f, 1.f;
-
+
Mat_<float> distCoeffs(1, 5);
distCoeffs << 1.2f, 0.2f, 0.f, 0.f, 0.f;
const Size sizes[] = { Size(6, 6), Size(8, 6), Size(11, 12), Size(5, 4) };
- const size_t sizes_num = sizeof(sizes)/sizeof(sizes[0]);
- const int test_num = 16;
+ const size_t sizes_num = sizeof(sizes)/sizeof(sizes[0]);
+ const int test_num = 16;
int progress = 0;
for(int i = 0; i < test_num; ++i)
- {
+ {
progress = update_progress( progress, i, test_num, 0 );
ChessBoardGenerator cbg(sizes[i % sizes_num]);
if(!validateData(cbg, cb.size(), corners_generated))
{
ts->printf( cvtest::TS::LOG, "Chess board skipped - too small" );
- continue;
+ continue;
}
- /*cb = cb * 0.8 + Scalar::all(30);
+ /*cb = cb * 0.8 + Scalar::all(30);
GaussianBlur(cb, cb, Size(3, 3), 0.8); */
- //cv::addWeighted(cb, 0.8, bg, 0.2, 20, cb);
+ //cv::addWeighted(cb, 0.8, bg, 0.2, 20, cb);
//cv::namedWindow("CB"); cv::imshow("CB", cb); cv::waitKey();
-
+
vector<Point2f> corners_found;
int flags = i % 8; // need to check branches for all flags
bool found = findChessboardCorners(cb, cbg.cornersSize(), corners_found, flags);
- if (!found)
- {
+ if (!found)
+ {
ts->printf( cvtest::TS::LOG, "Chess board corners not found\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
res = false;
- return res;
+ return res;
}
- double err = calcErrorMinError(cbg.cornersSize(), corners_found, corners_generated);
+ double err = calcErrorMinError(cbg.cornersSize(), corners_found, corners_generated);
if( err > rough_success_error_level )
{
ts->printf( cvtest::TS::LOG, "bad accuracy of corner guesses" );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
res = false;
return res;
- }
- }
+ }
+ }
/* ***** negative ***** */
- {
+ {
vector<Point2f> corners_found;
bool found = findChessboardCorners(bg, Size(8, 7), corners_found);
if (found)
ChessBoardGenerator cbg(Size(8, 7));
vector<Point2f> cg;
- Mat cb = cbg(bg, camMat, distCoeffs, cg);
+ Mat cb = cbg(bg, camMat, distCoeffs, cg);
found = findChessboardCorners(cb, Size(3, 4), corners_found);
if (found)
- res = false;
+ res = false;
Point2f c = std::accumulate(cg.begin(), cg.end(), Point2f(), plus<Point2f>()) * (1.f/cg.size());
Mat_<double> aff(2, 3);
aff << 1.0, 0.0, -(double)c.x, 0.0, 1.0, 0.0;
Mat sh;
- warpAffine(cb, sh, aff, cb.size());
+ warpAffine(cb, sh, aff, cb.size());
found = findChessboardCorners(sh, cbg.cornersSize(), corners_found);
if (found)
- res = false;
-
+ res = false;
+
vector< vector<Point> > cnts(1);
vector<Point>& cnt = cnts[0];
- cnt.push_back(cg[ 0]); cnt.push_back(cg[0+2]);
- cnt.push_back(cg[7+0]); cnt.push_back(cg[7+2]);
+ cnt.push_back(cg[ 0]); cnt.push_back(cg[0+2]);
+ cnt.push_back(cg[7+0]); cnt.push_back(cg[7+2]);
cv::drawContours(cb, cnts, -1, Scalar::all(128), CV_FILLED);
found = findChessboardCorners(cb, cbg.cornersSize(), corners_found);
cv::drawChessboardCorners(cb, cbg.cornersSize(), Mat(corners_found), found);
}
-
+
return res;
}
class Differential
{
-public:
- typedef Mat_<double> mat_t;
+public:
+ typedef Mat_<double> mat_t;
- Differential(double eps_, const mat_t& rv1_, const mat_t& tv1_, const mat_t& rv2_, const mat_t& tv2_)
+ Differential(double eps_, const mat_t& rv1_, const mat_t& tv1_, const mat_t& rv2_, const mat_t& tv2_)
: rv1(rv1_), tv1(tv1_), rv2(rv2_), tv2(tv2_), eps(eps_), ev(3, 1) {}
void dRv1(mat_t& dr3_dr1, mat_t& dt3_dr1)
- {
+ {
dr3_dr1.create(3, 3); dt3_dr1.create(3, 3);
-
- for(int i = 0; i < 3; ++i)
+
+ for(int i = 0; i < 3; ++i)
{
- ev.setTo(Scalar(0)); ev(i, 0) = eps;
-
- composeRT( rv1 + ev, tv1, rv2, tv2, rv3_p, tv3_p);
+ ev.setTo(Scalar(0)); ev(i, 0) = eps;
+
+ composeRT( rv1 + ev, tv1, rv2, tv2, rv3_p, tv3_p);
composeRT( rv1 - ev, tv1, rv2, tv2, rv3_m, tv3_m);
- dr3_dr1.col(i) = rv3_p - rv3_m;
- dt3_dr1.col(i) = tv3_p - tv3_m;
+ dr3_dr1.col(i) = rv3_p - rv3_m;
+ dt3_dr1.col(i) = tv3_p - tv3_m;
}
dr3_dr1 /= 2 * eps; dt3_dr1 /= 2 * eps;
}
void dRv2(mat_t& dr3_dr2, mat_t& dt3_dr2)
- {
+ {
dr3_dr2.create(3, 3); dt3_dr2.create(3, 3);
-
- for(int i = 0; i < 3; ++i)
+
+ for(int i = 0; i < 3; ++i)
{
- ev.setTo(Scalar(0)); ev(i, 0) = eps;
-
- composeRT( rv1, tv1, rv2 + ev, tv2, rv3_p, tv3_p);
+ ev.setTo(Scalar(0)); ev(i, 0) = eps;
+
+ composeRT( rv1, tv1, rv2 + ev, tv2, rv3_p, tv3_p);
composeRT( rv1, tv1, rv2 - ev, tv2, rv3_m, tv3_m);
- dr3_dr2.col(i) = rv3_p - rv3_m;
- dt3_dr2.col(i) = tv3_p - tv3_m;
+ dr3_dr2.col(i) = rv3_p - rv3_m;
+ dt3_dr2.col(i) = tv3_p - tv3_m;
}
dr3_dr2 /= 2 * eps; dt3_dr2 /= 2 * eps;
}
void dTv1(mat_t& drt3_dt1, mat_t& dt3_dt1)
- {
+ {
drt3_dt1.create(3, 3); dt3_dt1.create(3, 3);
-
- for(int i = 0; i < 3; ++i)
+
+ for(int i = 0; i < 3; ++i)
{
- ev.setTo(Scalar(0)); ev(i, 0) = eps;
-
- composeRT( rv1, tv1 + ev, rv2, tv2, rv3_p, tv3_p);
+ ev.setTo(Scalar(0)); ev(i, 0) = eps;
+
+ composeRT( rv1, tv1 + ev, rv2, tv2, rv3_p, tv3_p);
composeRT( rv1, tv1 - ev, rv2, tv2, rv3_m, tv3_m);
- drt3_dt1.col(i) = rv3_p - rv3_m;
- dt3_dt1.col(i) = tv3_p - tv3_m;
+ drt3_dt1.col(i) = rv3_p - rv3_m;
+ dt3_dt1.col(i) = tv3_p - tv3_m;
}
drt3_dt1 /= 2 * eps; dt3_dt1 /= 2 * eps;
}
void dTv2(mat_t& dr3_dt2, mat_t& dt3_dt2)
- {
+ {
dr3_dt2.create(3, 3); dt3_dt2.create(3, 3);
-
- for(int i = 0; i < 3; ++i)
+
+ for(int i = 0; i < 3; ++i)
{
- ev.setTo(Scalar(0)); ev(i, 0) = eps;
-
- composeRT( rv1, tv1, rv2, tv2 + ev, rv3_p, tv3_p);
+ ev.setTo(Scalar(0)); ev(i, 0) = eps;
+
+ composeRT( rv1, tv1, rv2, tv2 + ev, rv3_p, tv3_p);
composeRT( rv1, tv1, rv2, tv2 - ev, rv3_m, tv3_m);
- dr3_dt2.col(i) = rv3_p - rv3_m;
- dt3_dt2.col(i) = tv3_p - tv3_m;
+ dr3_dt2.col(i) = rv3_p - rv3_m;
+ dt3_dt2.col(i) = tv3_p - tv3_m;
}
dr3_dt2 /= 2 * eps; dt3_dt2 /= 2 * eps;
}
-
+
private:
const mat_t& rv1, tv1, rv2, tv2;
double eps;
Mat_<double> ev;
-
+
Differential& operator=(const Differential&);
- Mat rv3_m, tv3_m, rv3_p, tv3_p;
+ Mat rv3_m, tv3_m, rv3_p, tv3_p;
};
class CV_composeRT_Test : public cvtest::BaseTest
public:
CV_composeRT_Test() {}
~CV_composeRT_Test() {}
-protected:
-
+protected:
+
void run(int)
{
- cvtest::TS& ts = *this->ts;
- ts.set_failed_test_info(cvtest::TS::OK);
-
- Mat_<double> rvec1(3, 1), tvec1(3, 1), rvec2(3, 1), tvec2(3, 1);
+ ts->set_failed_test_info(cvtest::TS::OK);
+
+ Mat_<double> rvec1(3, 1), tvec1(3, 1), rvec2(3, 1), tvec2(3, 1);
randu(rvec1, Scalar(0), Scalar(6.29));
randu(rvec2, Scalar(0), Scalar(6.29));
randu(tvec1, Scalar(-2), Scalar(2));
randu(tvec2, Scalar(-2), Scalar(2));
-
+
Mat rvec3, tvec3;
composeRT(rvec1, tvec1, rvec2, tvec2, rvec3, tvec3);
-
+
Mat rvec3_exp, tvec3_exp;
Mat rmat1, rmat2;
const double thres = 1e-5;
if (norm(rvec3_exp, rvec3) > thres || norm(tvec3_exp, tvec3) > thres)
- ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
+ ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
const double eps = 1e-3;
Differential diff(eps, rvec1, tvec1, rvec2, tvec2);
-
+
Mat dr3dr1, dr3dt1, dr3dr2, dr3dt2, dt3dr1, dt3dt1, dt3dr2, dt3dt2;
- composeRT(rvec1, tvec1, rvec2, tvec2, rvec3, tvec3,
+ composeRT(rvec1, tvec1, rvec2, tvec2, rvec3, tvec3,
dr3dr1, dr3dt1, dr3dr2, dr3dt2, dt3dr1, dt3dt1, dt3dr2, dt3dt2);
-
+
Mat_<double> dr3_dr1, dt3_dr1;
diff.dRv1(dr3_dr1, dt3_dr1);
if (norm(dr3_dr1, dr3dr1) > thres || norm(dt3_dr1, dt3dr1) > thres)
- {
- ts.printf( cvtest::TS::LOG, "Invalid derivates by r1\n" );
- ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
+ {
+ ts->printf( cvtest::TS::LOG, "Invalid derivates by r1\n" );
+ ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
}
Mat_<double> dr3_dr2, dt3_dr2;
diff.dRv2(dr3_dr2, dt3_dr2);
if (norm(dr3_dr2, dr3dr2) > thres || norm(dt3_dr2, dt3dr2) > thres)
- {
- ts.printf( cvtest::TS::LOG, "Invalid derivates by r2\n" );
- ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
+ {
+ ts->printf( cvtest::TS::LOG, "Invalid derivates by r2\n" );
+ ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
}
Mat_<double> dr3_dt1, dt3_dt1;
diff.dTv1(dr3_dt1, dt3_dt1);
if (norm(dr3_dt1, dr3dt1) > thres || norm(dt3_dt1, dt3dt1) > thres)
- {
- ts.printf( cvtest::TS::LOG, "Invalid derivates by t1\n" );
- ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
+ {
+ ts->printf( cvtest::TS::LOG, "Invalid derivates by t1\n" );
+ ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
}
-
+
Mat_<double> dr3_dt2, dt3_dt2;
diff.dTv2(dr3_dt2, dt3_dt2);
if (norm(dr3_dt2, dr3dt2) > thres || norm(dt3_dt2, dt3dt2) > thres)
- {
- ts.printf( cvtest::TS::LOG, "Invalid derivates by t2\n" );
- ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
+ {
+ ts->printf( cvtest::TS::LOG, "Invalid derivates by t2\n" );
+ ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
}
- }
-};
-
+ }
+};
+
TEST(Calib3d_ComposeRT, accuracy) { CV_composeRT_Test test; test.safe_run(); }
double sigma;\r
\r
private:\r
- float max_diff, max_2diff;\r
- bool check_matrix_size(const cv::Mat& H);\r
- bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff);\r
+ float max_diff, max_2diff;\r
+ bool check_matrix_size(const cv::Mat& H);\r
+ bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff);\r
int check_ransac_mask_1(const Mat& src, const Mat& mask);\r
- int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask);\r
-\r
- void print_information_1(int j, int N, int method, const Mat& H);\r
- void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff);\r
- void print_information_3(int j, int N, const Mat& mask);\r
- void print_information_4(int method, int j, int N, int k, int l, double diff);\r
- void print_information_5(int method, int j, int N, int l, double diff);\r
- void print_information_6(int j, int N, int k, double diff, bool value);\r
- void print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value);\r
- void print_information_8(int j, int N, int k, int l, double diff);\r
+ int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask);\r
+\r
+ void print_information_1(int j, int N, int method, const Mat& H);\r
+ void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff);\r
+ void print_information_3(int j, int N, const Mat& mask);\r
+ void print_information_4(int method, int j, int N, int k, int l, double diff);\r
+ void print_information_5(int method, int j, int N, int l, double diff);\r
+ void print_information_6(int j, int N, int k, double diff, bool value);\r
+ void print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value);\r
+ void print_information_8(int j, int N, int k, int l, double diff);\r
};\r
\r
CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2f), max_2diff(2e-2f)\r
\r
CV_HomographyTest::~CV_HomographyTest() {}\r
\r
-bool CV_HomographyTest::check_matrix_size(const cv::Mat& H) \r
+bool CV_HomographyTest::check_matrix_size(const cv::Mat& H)\r
{\r
return (H.rows == 3) && (H.cols == 3);\r
}\r
return 0;\r
}\r
\r
-void CV_HomographyTest::print_information_1(int j, int N, int method, const Mat& H)\r
+void CV_HomographyTest::print_information_1(int j, int N, int _method, const Mat& H)\r
{\r
cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;\r
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";\r
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;\r
cout << "Count of points: " << N << endl; cout << endl;\r
- cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;\r
+ cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;\r
cout << "Homography matrix:" << endl; cout << endl;\r
cout << H << endl; cout << endl;\r
cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl;\r
}\r
\r
-void CV_HomographyTest::print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff)\r
+void CV_HomographyTest::print_information_2(int j, int N, int _method, const Mat& H, const Mat& H_res, int k, double diff)\r
{\r
cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl;\r
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";\r
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;\r
cout << "Count of points: " << N << endl; cout << endl;\r
- cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;\r
+ cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;\r
cout << "Original matrix:" << endl; cout << endl;\r
cout << H << endl; cout << endl;\r
cout << "Found matrix:" << endl; cout << endl;\r
cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl;\r
}\r
\r
-void CV_HomographyTest::print_information_4(int method, int j, int N, int k, int l, double diff)\r
+void CV_HomographyTest::print_information_4(int _method, int j, int N, int k, int l, double diff)\r
{\r
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;\r
- cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;\r
+ cout << "Method: "; if (_method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;\r
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";\r
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;\r
cout << "Sigma of normal noise: " << sigma << endl;\r
cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl;\r
}\r
\r
-void CV_HomographyTest::print_information_5(int method, int j, int N, int l, double diff)\r
-{ \r
+void CV_HomographyTest::print_information_5(int _method, int j, int N, int l, double diff)\r
+{\r
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;\r
- cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;\r
+ cout << "Method: "; if (_method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;\r
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";\r
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;\r
cout << "Sigma of normal noise: " << sigma << endl;\r
if (code)\r
{\r
print_information_3(j, N, mask[j]);\r
- \r
+\r
switch (code)\r
{\r
case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; }\r
\r
default: break;\r
}\r
- \r
+\r
return;\r
}\r
\r
{\r
case 0:\r
case CV_LMEDS:\r
- {\r
+ {\r
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f),\r
cv::findHomography(src_mat_2f, dst_vec),\r
cv::findHomography(src_vec, dst_mat_2f),\r
}\r
\r
continue;\r
- }\r
+ }\r
case CV_RANSAC:\r
{\r
cv::Mat mask_res [4];\r
}\r
}\r
}\r
- \r
+\r
continue;\r
}\r
\r
}
}
- virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* eps, double& maxError)
+ virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* epsilon, double& maxError)
{
Mat rvec, tvec;
vector<int> inliers;
bool isTestSuccess = inliers.size() >= points.size()*0.95;
double rvecDiff = norm(rvec-trueRvec), tvecDiff = norm(tvec-trueTvec);
- isTestSuccess = isTestSuccess && rvecDiff < eps[method] && tvecDiff < eps[method];
+ isTestSuccess = isTestSuccess && rvecDiff < epsilon[method] && tvecDiff < epsilon[method];
double error = rvecDiff > tvecDiff ? rvecDiff : tvecDiff;
//cout << error << " " << inliers.size() << " " << eps[method] << endl;
if (error > maxError)
void run(int)
{
- cvtest::TS& ts = *this->ts;
- ts.set_failed_test_info(cvtest::TS::OK);
+ ts->set_failed_test_info(cvtest::TS::OK);
vector<Point3f> points;
const int pointsCount = 500;
const int methodsCount = 3;
- RNG rng = ts.get_rng();
+ RNG rng = ts->get_rng();
for (int mode = 0; mode < 2; mode++)
//cout << maxError << " " << successfulTestsCount << endl;
if (successfulTestsCount < 0.7*totalTestsCount)
{
- ts.printf( cvtest::TS::LOG, "Invalid accuracy for method %d, failed %d tests from %d, maximum error equals %f, distortion mode equals %d\n",
+ ts->printf( cvtest::TS::LOG, "Invalid accuracy for method %d, failed %d tests from %d, maximum error equals %f, distortion mode equals %d\n",
method, totalTestsCount - successfulTestsCount, totalTestsCount, maxError, mode);
- ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
+ ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
}
}
}
~CV_solvePnP_Test() {}
protected:
- virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* eps, double& maxError)
+ virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* epsilon, double& maxError)
{
Mat rvec, tvec;
Mat trueRvec, trueTvec;
false, method);
double rvecDiff = norm(rvec-trueRvec), tvecDiff = norm(tvec-trueTvec);
- bool isTestSuccess = rvecDiff < eps[method] && tvecDiff < eps[method];
+ bool isTestSuccess = rvecDiff < epsilon[method] && tvecDiff < epsilon[method];
double error = rvecDiff > tvecDiff ? rvecDiff : tvecDiff;
if (error > maxError)
ts->set_failed_test_info( code );
return;
}
-
+
string fullResultFilename = dataPath + ALGORITHMS_DIR + algorithmName + RESULT_FILE;
FileStorage resFS( fullResultFilename, FileStorage::READ );
bool isWrite = true; // write or compare results
assert(fn.isSeq());
for( int i = 0; i < (int)fn.size(); i+=3 )
{
- string name = fn[i];
+ string _name = fn[i];
DatasetParams params;
string sf = fn[i+1]; params.dispScaleFactor = atoi(sf.c_str());
string uv = fn[i+2]; params.dispUnknVal = atoi(uv.c_str());
- datasetsParams[name] = params;
+ datasetsParams[_name] = params;
}
return cvtest::TS::OK;
}
public:
CV_StereoSGBMTest()
{
- name = "stereosgbm";
+ name = "stereosgbm";
fill(rmsEps.begin(), rmsEps.end(), 0.25f);
fill(fracEps.begin(), fracEps.end(), 0.01f);
}
GSD_INTENSITY_LT = 15,
GSD_INTENSITY_UT = 250
};
-
+
class CV_EXPORTS Histogram
{
private:
enum {
HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
};
-
+
protected:
int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
-
+
public:
CvHistogram *fHistogram;
Histogram();
virtual ~Histogram();
-
+
void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
void mergeWith(Histogram *source, double weight);
};
-
+
int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;
double fHistogramMergeFactor, fHuePercentCovered;
Histogram histogramHueMotion, skinHueHistogram;
IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;
IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;
-
+
protected:
void initData(IplImage *src, int widthDivider, int heightDivider);
void adaptiveFilter();
-
+
public:
-
+
enum {
MORPHING_METHOD_NONE = 0,
MORPHING_METHOD_ERODE = 1,
MORPHING_METHOD_ERODE_ERODE = 2,
MORPHING_METHOD_ERODE_DILATE = 3
};
-
+
CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
virtual ~CvAdaptiveSkinDetector();
-
+
virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
};
class CV_EXPORTS CvFuzzyPoint {
public:
double x, y, value;
-
+
CvFuzzyPoint(double _x, double _y);
};
private:
std::vector<CvFuzzyPoint> points;
double value, centre;
-
+
bool between(double x, double x1, double x2);
-
+
public:
CvFuzzyCurve();
~CvFuzzyCurve();
-
+
void setCentre(double _centre);
double getCentre();
void clear();
class CV_EXPORTS CvFuzzyFunction {
public:
std::vector<CvFuzzyCurve> curves;
-
+
CvFuzzyFunction();
~CvFuzzyFunction();
void addCurve(CvFuzzyCurve *curve, double value = 0);
FuzzyResizer();
int calcOutput(double edgeDensity, double density);
};
-
+
class SearchWindow
{
public:
double density;
unsigned int depthLow, depthHigh;
int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
-
+
SearchWindow();
~SearchWindow();
void setSize(int _x, int _y, int _width, int _height);
void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);
};
-
+
public:
enum TrackingState
{
tsSetWindow = 3,
tsDisabled = 10
};
-
+
enum ResizeMethod {
rmEdgeDensityLinear = 0,
rmEdgeDensityFuzzy = 1,
rmInnerDensity = 2
};
-
+
enum {
MinKernelMass = 1000
};
-
+
SearchWindow kernel;
int searchMode;
-
+
private:
enum
{
MaxMeanShiftIteration = 5,
MaxSetSizeIteration = 5
};
-
+
void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
-
+
public:
CvFuzzyMeanShiftTracker();
~CvFuzzyMeanShiftTracker();
-
+
void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
};
namespace cv
{
-
+
class CV_EXPORTS Octree
{
public:
bool isLeaf;
int children[8];
};
-
+
Octree();
Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
virtual ~Octree();
-
+
virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
virtual void getPointsWithinSphere( const Point3f& center, float radius,
vector<Point3f>& points ) const;
int minPoints;
vector<Point3f> points;
vector<Node> nodes;
-
+
virtual void buildNext(size_t node_ind);
};
-
-
+
+
class CV_EXPORTS Mesh3D
{
public:
struct EmptyMeshException {};
-
+
Mesh3D();
Mesh3D(const vector<Point3f>& vtx);
~Mesh3D();
-
+
void buildOctree();
void clearOctree();
float estimateResolution(float tryRatio = 0.1f);
void computeNormals(float normalRadius, int minNeighbors = 20);
void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);
-
+
void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
-
+
vector<Point3f> vtx;
vector<Point3f> normals;
float resolution;
Octree octree;
-
+
const static Point3f allzero;
};
-
+
class CV_EXPORTS SpinImageModel
{
public:
-
+
/* model parameters, leave unset for default or auto estimate */
float normalRadius;
int minNeighbors;
-
+
float binSize;
int imageWidth;
-
+
float lambda;
float gamma;
-
+
float T_GeometriccConsistency;
float T_GroupingCorespondances;
-
+
/* public interface */
SpinImageModel();
explicit SpinImageModel(const Mesh3D& mesh);
~SpinImageModel();
-
+
void setLogger(std::ostream* log);
void selectRandomSubset(float ratio);
void setSubset(const vector<int>& subset);
void compute();
-
+
void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);
-
+
Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
-
+
size_t getSpinCount() const { return spinImages.rows; }
Mat getSpinImage(size_t index) const { return spinImages.row((int)index); }
const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }
const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }
-
+
const Mesh3D& getMesh() const { return mesh; }
Mesh3D& getMesh() { return mesh; }
-
+
/* static utility functions */
static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
-
+
static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
-
+
static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1,
const Point3f& pointScene2, const Point3f& normalScene2,
const Point3f& pointModel2, const Point3f& normalModel2);
-
+
static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1,
const Point3f& pointScene2, const Point3f& normalScene2,
float gamma);
protected:
void defaultParams();
-
+
void matchSpinToModel(const Mat& spin, vector<int>& indeces,
vector<float>& corrCoeffs, bool useExtremeOutliers = true) const;
-
+
void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
-
+
vector<int> subset;
Mesh3D mesh;
Mat spinImages;
std::ostream* out;
};
-
+
class CV_EXPORTS TickMeter
{
public:
TickMeter();
void start();
void stop();
-
+
int64 getTimeTicks() const;
double getTimeMicro() const;
double getTimeMilli() const;
double getTimeSec() const;
int64 getCounter() const;
-
+
void reset();
private:
int64 counter;
int64 sumTime;
int64 startTime;
};
-
+
CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
-
+
class CV_EXPORTS SelfSimDescriptor
{
public:
SelfSimDescriptor(const SelfSimDescriptor& ss);
virtual ~SelfSimDescriptor();
SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);
-
+
size_t getDescriptorSize() const;
Size getGridSize( Size imgsize, Size winStride ) const;
-
+
virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),
const vector<Point>& locations=vector<Point>()) const;
virtual void computeLogPolarMapping(Mat& mappingMask) const;
virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;
-
+
int smallSize;
int largeSize;
int startDistanceBucket;
int numberOfDistanceBuckets;
int numberOfAngles;
-
+
enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,
DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,
DEFAULT_NUM_DISTANCE_BUCKETS = 7 };
};
-
-
+
+
typedef bool (*BundleAdjustCallback)(int iteration, double norm_error, void* user_data);
-
+
class LevMarqSparse {
public:
LevMarqSparse();
Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
// 1 - point is visible for the camera, 0 - invisible
Mat& P0, // starting vector of parameters, first cameras then points
- Mat& X, // measurements, in order of visibility. non visible cases are skipped
+ Mat& X, // measurements, in order of visibility. non visible cases are skipped
TermCriteria criteria, // termination criteria
-
+
// callback for estimation of Jacobian matrices
void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
Mat& cam_params, Mat& A, Mat& B, void* data),
void* data, // user-specific data passed to the callbacks
BundleAdjustCallback cb, void* user_data
);
-
+
virtual ~LevMarqSparse();
-
+
virtual void run( int npoints, // number of points
int ncameras, // number of cameras
int nPointParams, // number of params per one point (3 in case of 3D points)
Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
// 1 - point is visible for the camera, 0 - invisible
Mat& P0, // starting vector of parameters, first cameras then points
- Mat& X, // measurements, in order of visibility. non visible cases are skipped
+ Mat& X, // measurements, in order of visibility. non visible cases are skipped
TermCriteria criteria, // termination criteria
-
+
// callback for estimation of Jacobian matrices
void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
Mat& cam_params, Mat& A, Mat& B, void* data),
Mat& cam_params, Mat& estim, void* data),
void* data // user-specific data passed to the callbacks
);
-
+
virtual void clear();
-
+
// useful function to do simple bundle adjustment tasks
static void bundleAdjust(vector<Point3d>& points, // positions of points in global coordinate system (input and output)
const vector<vector<Point2d> >& imagePoints, // projections of 3d points for every camera
- const vector<vector<int> >& visibility, // visibility of 3d points for every camera
+ const vector<vector<int> >& visibility, // visibility of 3d points for every camera
vector<Mat>& cameraMatrix, // intrinsic matrices of all cameras (input and output)
vector<Mat>& R, // rotation matrices of all cameras (input and output)
vector<Mat>& T, // translation vector of all cameras (input and output)
const TermCriteria& criteria=
TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON),
BundleAdjustCallback cb = 0, void* user_data = 0);
-
+
public:
virtual void optimize(CvMat &_vis); //main function that runs minimization
-
+
//iteratively asks for measurement for visible camera-point pairs
void ask_for_proj(CvMat &_vis,bool once=false);
//iteratively asks for Jacobians for every camera_point pair
void ask_for_projac(CvMat &_vis);
-
+
CvMat* err; //error X-hX
double prevErrNorm, errNorm;
double lambda;
CvTermCriteria criteria;
int iters;
-
+
CvMat** U; //size of array is equal to number of cameras
CvMat** V; //size of array is equal to number of points
CvMat** inv_V_star; //inverse of V*
-
+
CvMat** A;
CvMat** B;
CvMat** W;
-
- CvMat* X; //measurement
- CvMat* hX; //current measurement extimation given new parameter vector
-
- CvMat* prevP; //current already accepted parameter.
+
+ CvMat* X; //measurement
+ CvMat* hX; //current measurement extimation given new parameter vector
+
+ CvMat* prevP; //current already accepted parameter.
CvMat* P; // parameters used to evaluate function with new params
- // this parameters may be rejected
-
+ // this parameters may be rejected
+
CvMat* deltaP; //computed increase of parameters (result of normal system solution )
-
+
CvMat** ea; // sum_i AijT * e_ij , used as right part of normal equation
- // length of array is j = number of cameras
+ // length of array is j = number of cameras
CvMat** eb; // sum_j BijT * e_ij , used as right part of normal equation
// length of array is i = number of points
-
+
CvMat** Yj; //length of array is i = num_points
-
- CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params
-
+
+ CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params
+
CvMat* JtJ_diag; //diagonal of JtJ, used to backup diagonal elements before augmentation
-
+
CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
-
+
int num_cams;
int num_points;
int num_err_param;
int num_cam_param;
int num_point_param;
-
- //target function and jacobian pointers, which needs to be initialized
+
+ //target function and jacobian pointers, which needs to be initialized
void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);
void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data);
-
+
void* data;
-
+
BundleAdjustCallback cb;
void* user_data;
- };
-
+ };
+
CV_EXPORTS int chamerMatching( Mat& img, Mat& templ,
vector<vector<Point> >& results, vector<float>& cost,
double templScale=1, int maxMatches = 20,
double minMatchDistance = 1.0, int padX = 3,
int padY = 3, int scales = 5, double minScale = 0.6, double maxScale = 1.6,
double orientationWeight = 0.5, double truncate = 20);
-
-
+
+
class CV_EXPORTS StereoVar
{
public:
- // Flags
+ // Flags
enum {USE_INITIAL_DISPARITY = 1, USE_EQUALIZE_HIST = 2, USE_SMART_ID = 4, USE_AUTO_PARAMS = 8, USE_MEDIAN_FILTERING = 16};
enum {CYCLE_O, CYCLE_V};
enum {PENALIZATION_TICHONOV, PENALIZATION_CHARBONNIER, PENALIZATION_PERONA_MALIK};
-
+
//! the default constructor
CV_WRAP StereoVar();
-
+
//! the full constructor taking all the necessary algorithm parameters
CV_WRAP StereoVar(int levels, double pyrScale, int nIt, int minDisp, int maxDisp, int poly_n, double poly_sigma, float fi, float lambda, int penalization, int cycle, int flags);
-
+
//! the destructor
virtual ~StereoVar();
-
+
//! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair
CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, Mat& disp);
-
- CV_PROP_RW int levels;
- CV_PROP_RW double pyrScale;
- CV_PROP_RW int nIt;
- CV_PROP_RW int minDisp;
- CV_PROP_RW int maxDisp;
- CV_PROP_RW int poly_n;
- CV_PROP_RW double poly_sigma;
- CV_PROP_RW float fi;
- CV_PROP_RW float lambda;
- CV_PROP_RW int penalization;
- CV_PROP_RW int cycle;
- CV_PROP_RW int flags;
-
+
+ CV_PROP_RW int levels;
+ CV_PROP_RW double pyrScale;
+ CV_PROP_RW int nIt;
+ CV_PROP_RW int minDisp;
+ CV_PROP_RW int maxDisp;
+ CV_PROP_RW int poly_n;
+ CV_PROP_RW double poly_sigma;
+ CV_PROP_RW float fi;
+ CV_PROP_RW float lambda;
+ CV_PROP_RW int penalization;
+ CV_PROP_RW int cycle;
+ CV_PROP_RW int flags;
+
private:
void autoParams();
- void FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level);
+ void FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level);
void VCycle_MyFAS(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
void VariationalSolver(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
};
-
+
CV_EXPORTS void polyfit(const Mat& srcx, const Mat& srcy, Mat& dst, int order);
- class CV_EXPORTS Directory
+ class CV_EXPORTS Directory
{
- public:
- static std::vector<std::string> GetListFiles ( const std::string& path, const std::string & exten = "*", bool addPath = true );
- static std::vector<std::string> GetListFilesR ( const std::string& path, const std::string & exten = "*", bool addPath = true );
- static std::vector<std::string> GetListFolders( const std::string& path, const std::string & exten = "*", bool addPath = true );
+ public:
+ static std::vector<std::string> GetListFiles ( const std::string& path, const std::string & exten = "*", bool addPath = true );
+ static std::vector<std::string> GetListFilesR ( const std::string& path, const std::string & exten = "*", bool addPath = true );
+ static std::vector<std::string> GetListFolders( const std::string& path, const std::string & exten = "*", bool addPath = true );
};
/*
class CV_EXPORTS LogPolar_Interp
{
public:
-
+
LogPolar_Interp() {}
/**
*\param center the transformation center: where the output precision is maximal
*\param R the number of rings of the cortical image (default value 70 pixel)
*\param ro0 the radius of the blind spot (default value 3 pixel)
- *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
+ *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
* \a 0 means that the retinal image is computed within the inscribed circle.
*\param S the number of sectors of the cortical image (default value 70 pixel).
* Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
- *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
+ *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
* \a 0 means that the parameter \a S is provided by the user.
*/
LogPolar_Interp(int w, int h, Point2i center, int R=70, double ro0=3.0,
*Destructor
*/
~LogPolar_Interp();
-
+
protected:
-
+
Mat Rsri;
Mat Csri;
*More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
*/
class CV_EXPORTS LogPolar_Overlapping
- {
+ {
public:
LogPolar_Overlapping() {}
-
+
/**
*Constructor
*\param w the width of the input image
*\param center the transformation center: where the output precision is maximal
*\param R the number of rings of the cortical image (default value 70 pixel)
*\param ro0 the radius of the blind spot (default value 3 pixel)
- *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
+ *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
* \a 0 means that the retinal image is computed within the inscribed circle.
*\param S the number of sectors of the cortical image (default value 70 pixel).
* Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
- *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
+ *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
* \a 0 means that the parameter \a S is provided by the user.
*/
LogPolar_Overlapping(int w, int h, Point2i center, int R=70,
*Destructor
*/
~LogPolar_Overlapping();
-
+
protected:
-
+
Mat Rsri;
Mat Csri;
vector<int> Rsr;
{
public:
LogPolar_Adjacent() {}
-
+
/**
*Constructor
*\param w the width of the input image
*\param R the number of rings of the cortical image (default value 70 pixel)
*\param ro0 the radius of the blind spot (default value 3 pixel)
*\param smin the size of the subpixel (default value 0.25 pixel)
- *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
+ *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
* \a 0 means that the retinal image is computed within the inscribed circle.
*\param S the number of sectors of the cortical image (default value 70 pixel).
* Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
- *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
+ *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
* \a 0 means that the parameter \a S is provided by the user.
- */
+ */
LogPolar_Adjacent(int w, int h, Point2i center, int R=70, double ro0=3.0, double smin=0.25, int full=1, int S=117, int sp=1);
/**
*Transformation from Cartesian image to cortical (log-polar) image.
bool get_uv(double x, double y, int&u, int&v);
void create_map(int M, int N, int R, int S, double ro0, double smin);
};
-
+
CV_EXPORTS Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
CV_EXPORTS Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
-
+
class CV_EXPORTS LDA
{
public:
// Returns the eigenvalues of this LDA.
Mat eigenvalues() const { return _eigenvalues; }
-
+
protected:
bool _dataAsRow;
int _num_components;
void lda(InputArray src, InputArray labels);
};
-
+
class CV_EXPORTS FaceRecognizer : public Algorithm
{
public:
// Deserializes this object from a given cv::FileStorage.
virtual void load(const FileStorage& fs) = 0;
-
+
// Returns eigenvectors (if any)
virtual Mat eigenvectors() const { return Mat(); }
};
-
+
CV_EXPORTS Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components = 0);
CV_EXPORTS Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components = 0);
CV_EXPORTS Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8,
int grid_x=8, int grid_y=8);
-
+
enum
{
COLORMAP_AUTUMN = 0,
COLORMAP_MKPJ1 = 12,
COLORMAP_MKPJ2 = 13
};
-
+
CV_EXPORTS void applyColorMap(InputArray src, OutputArray dst, int colormap);
-
+
CV_EXPORTS bool initModule_contrib();
}
struct CV_EXPORTS CvFeatureTrackerParams
{
enum { SIFT = 0, SURF = 1, OPTICAL_FLOW = 2 };
- CvFeatureTrackerParams(int feature_type = 0, int window_size = 0)
+ CvFeatureTrackerParams(int featureType = 0, int windowSize = 0)
{
- feature_type = 0;
- window_size = 0;
+ featureType = 0;
+ windowSize = 0;
}
int feature_type; // Feature type to use
// 1 - point is visible for the camera, 0 - invisible
Mat& P0, // starting vector of parameters, first cameras then points
Mat& X_, // measurements, in order of visibility. non visible cases are skipped
- TermCriteria criteria, // termination criteria
+ TermCriteria _criteria, // termination criteria
// callback for estimation of Jacobian matrices
- void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
+ void (CV_CDECL * _fjac)(int i, int j, Mat& point_params,
Mat& cam_params, Mat& A, Mat& B, void* data),
// callback for estimation of backprojection errors
- void (CV_CDECL * func)(int i, int j, Mat& point_params,
+ void (CV_CDECL * _func)(int i, int j, Mat& point_params,
Mat& cam_params, Mat& estim, void* data),
- void* data, // user-specific data passed to the callbacks
+ void* _data, // user-specific data passed to the callbacks
BundleAdjustCallback _cb, void* _user_data
) {
Vis_index = X = prevP = P = deltaP = err = JtJ_diag = S = hX = NULL;
user_data = _user_data;
run(npoints, ncameras, nPointParams, nCameraParams, nErrParams, visibility,
- P0, X_, criteria, fjac, func, data);
+ P0, X_, _criteria, _fjac, _func, _data);
}
void LevMarqSparse::clear() {
} //U_j and ea_j computed for all j
// if (!(iters%100))
- int nviz = X->rows / num_err_param;
- double e2 = prevErrNorm*prevErrNorm, e2n = e2 / nviz;
- std::cerr<<"Iteration: "<<iters<<", normError: "<<e2<<" ("<<e2n<<")"<<std::endl;
+ {
+ int nviz = X->rows / num_err_param;
+ double e2 = prevErrNorm*prevErrNorm, e2n = e2 / nviz;
+ std::cerr<<"Iteration: "<<iters<<", normError: "<<e2<<" ("<<e2n<<")"<<std::endl;
+ }
if (cb)
cb(iters, prevErrNorm, user_data);
//compute V_i and eb_i
errNorm > prevErrNorm ) { //step was not accepted
//increase lambda and reject change
lambda *= 10;
- int nviz = X->rows / num_err_param;
- double e2 = errNorm*errNorm, e2_prev = prevErrNorm*prevErrNorm;
- double e2n = e2/nviz, e2n_prev = e2_prev/nviz;
- std::cerr<<"move failed: lambda = "<<lambda<<", e2 = "<<e2<<" ("<<e2n<<") > "<<e2_prev<<" ("<<e2n_prev<<")"<<std::endl;
+ {
+ int nviz = X->rows / num_err_param;
+ double e2 = errNorm*errNorm, e2_prev = prevErrNorm*prevErrNorm;
+ double e2n = e2/nviz, e2n_prev = e2_prev/nviz;
+ std::cerr<<"move failed: lambda = "<<lambda<<", e2 = "<<e2<<" ("<<e2n<<") > "<<e2_prev<<" ("<<e2n_prev<<")"<<std::endl;
+ }
//restore diagonal from backup
{
double c[4] = { g+2*p1*y_strike+4*p2*x_strike, 2*p1*x_strike,
2*p2*y_strike, g+2*p2*x_strike + 4*p1*y_strike };
- CvMat coeffmat = cvMat(2,2,CV_64F, c );
+ CvMat coeffmat2 = cvMat(2,2,CV_64F, c );
- cvMatMul(&coeffmat, dstrike_dbig, dstrike2_dbig );
+ cvMatMul(&coeffmat2, dstrike_dbig, dstrike2_dbig );
cvGEMM( &strike, dg_dbig, 1, NULL, 0, tmp, CV_GEMM_A_T );
cvAdd( dstrike2_dbig, tmp, dstrike2_dbig );
}
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
- float _a = _filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
- _filteringCoeficientsTable[1+tableOffset]=(1.0f-_a)*(1.0f-_a)*(1.0f-_a)*(1.0f-_a)/(1.0f+_beta);
+ float a = _filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
+ _filteringCoeficientsTable[1+tableOffset]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[2+tableOffset] =tau;
- //std::cout<<"BasicRetinaFilter::normal:"<<(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta)<<" -> old:"<<(1-_a)*(1-_a)*(1-_a)*(1-_a)/(1+_beta)<<std::endl;
+ //std::cout<<"BasicRetinaFilter::normal:"<<(1.0-a)*(1.0-a)*(1.0-a)*(1.0-a)/(1.0+_beta)<<" -> old:"<<(1-a)*(1-a)*(1-a)*(1-a)/(1+_beta)<<std::endl;
- //std::cout<<"BasicRetinaFilter::_a="<<_a<<", gain="<<_filteringCoeficientsTable[1+tableOffset]<<", tau="<<tau<<std::endl;
+ //std::cout<<"BasicRetinaFilter::a="<<a<<", gain="<<_filteringCoeficientsTable[1+tableOffset]<<", tau="<<tau<<std::endl;
}
void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const float beta, const float tau, const float alpha0, const unsigned int filterIndex)
float _alpha=0.8f;
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
- float _a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
- _filteringCoeficientsTable[tableOffset+1]=(1.0f-_a)*(1.0f-_a)*(1.0f-_a)*(1.0f-_a)/(1.0f+_beta);
+ float a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
+ _filteringCoeficientsTable[tableOffset+1]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau;
float commonFactor=alpha0/(float)sqrt(_halfNBcolumns*_halfNBcolumns+_halfNBrows*_halfNBrows+1.0f);
}
unsigned int tableOffset=filterIndex*3;
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
- float _a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
- _filteringCoeficientsTable[tableOffset+1]=(1.0f-_a)*(1.0f-_a)*(1.0f-_a)*(1.0f-_a)/(1.0f+_beta);
+ float a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
+ _filteringCoeficientsTable[tableOffset+1]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau;
//memset(_progressiveSpatialConstant, 255, _filterOutput.getNBpixels());
mixChannels(&hsv, 1, &hue, 1, channels, 2);
Mat roi(hue, selection);
- Mat maskroi(mask, selection);
+ Mat mskroi(mask, selection);
int ch[] = {0, 1};
int chsize[] = {32, 32};
- calcHist(&roi, 1, ch, maskroi, hist, 1, chsize, ranges);
+ calcHist(&roi, 1, ch, mskroi, hist, 1, chsize, ranges);
normalize(hist, hist, 0, 255, CV_MINMAX);
prev_trackwindow = selection;
{
using std::set;
-
+
// Reads a sequence from a FileNode::SEQ with type _Tp into a result vector.
template<typename _Tp>
inline void readFileNodeList(const FileNode& fn, vector<_Tp>& result) {
}
fs << "]";
}
-
+
static Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0)
{
// number of samples
}
return data;
}
-
+
// Removes duplicate elements in a given vector.
template<typename _Tp>
inline vector<_Tp> remove_dups(const vector<_Tp>& src) {
return elems;
}
-
+
// Turk, M., and Pentland, A. "Eigenfaces for recognition.". Journal of
// Cognitive Neuroscience 3 (1991), 71–86.
class Eigenfaces : public FaceRecognizer
// See FaceRecognizer::save.
void save(FileStorage& fs) const;
-
+
AlgorithmInfo* info() const;
};
-
+
// Belhumeur, P. N., Hespanha, J., and Kriegman, D. "Eigenfaces vs. Fisher-
// faces: Recognition using class specific linear projection.". IEEE
// Transactions on Pattern Analysis and Machine Intelligence 19, 7 (1997),
//
// radius, neighbors are used in the local binary patterns creation.
// grid_x, grid_y control the grid size of the spatial histograms.
- LBPH(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8) :
- _grid_x(grid_x),
- _grid_y(grid_y),
- _radius(radius),
- _neighbors(neighbors) {}
+ LBPH(int radius_=1, int neighbors_=8, int grid_x_=8, int grid_y_=8) :
+ _grid_x(grid_x_),
+ _grid_y(grid_y_),
+ _radius(radius_),
+ _neighbors(neighbors_) {}
// Initializes and computes this LBPH Model. The current implementation is
// rather fixed as it uses the Extended Local Binary Patterns per default.
// (grid_x=8), (grid_y=8) controls the grid size of the spatial histograms.
LBPH(InputArray src,
InputArray labels,
- int radius=1, int neighbors=8,
- int grid_x=8, int grid_y=8) :
- _grid_x(grid_x),
- _grid_y(grid_y),
- _radius(radius),
- _neighbors(neighbors) {
+ int radius_=1, int neighbors_=8,
+ int grid_x_=8, int grid_y_=8) :
+ _grid_x(grid_x_),
+ _grid_y(grid_y_),
+ _radius(radius_),
+ _neighbors(neighbors_) {
train(src, labels);
}
// get data
Mat labels = _lbls.getMat();
Mat data = asRowMatrix(src, CV_64FC1);
-
+
CV_Assert( labels.type() == CV_32S && (labels.cols == 1 || labels.rows == 1));
-
+
// dimensionality
int N = data.rows; // number of samples
//int D = data.cols; // dimension of samples
if(labels.total() != (size_t)N)
CV_Error(CV_StsUnsupportedFormat, "Labels must be given as integer (CV_32SC1).");
// compute the Fisherfaces
-
+
vector<int> ll;
labels.copyTo(ll);
int C = (int)remove_dups(ll).size(); // number of unique classes
return Mat();
}
-
+
static Mat spatial_histogram(InputArray _src, int numPatterns,
int grid_x, int grid_y, bool normed)
{
elbp(src, dst, radius, neighbors);
return dst;
}
-
+
void LBPH::load(const FileStorage& fs) {
fs["radius"] >> _radius;
fs["neighbors"] >> _neighbors;
}
return minClass;
}
-
-
+
+
Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components)
{
return new Eigenfaces(num_components);
}
-
+
Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components)
{
return new Fisherfaces(num_components);
}
-
+
Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius, int neighbors,
int grid_x, int grid_y)
{
return new LBPH(radius, neighbors, grid_x, grid_y);
}
-
+
CV_INIT_ALGORITHM(Eigenfaces, "FaceRecognizer.Eigenfaces",
obj.info()->addParam(obj, "ncomponents", obj._num_components);
obj.info()->addParam(obj, "projections", obj._projections, true);
obj.info()->addParam(obj, "labels", obj._labels, true);
obj.info()->addParam(obj, "eigenvectors", obj._eigenvectors, true);
obj.info()->addParam(obj, "eigenvalues", obj._eigenvalues, true);
- obj.info()->addParam(obj, "mean", obj._mean, true));
-
+ obj.info()->addParam(obj, "mean", obj._mean, true));
+
CV_INIT_ALGORITHM(LBPH, "FaceRecognizer.LBPH",
obj.info()->addParam(obj, "radius", obj._radius);
obj.info()->addParam(obj, "neighbors", obj._neighbors);
obj.info()->addParam(obj, "grid_y", obj._grid_y);
obj.info()->addParam(obj, "histograms", obj._histograms, true);
obj.info()->addParam(obj, "labels", obj._labels, true));
-
+
bool initModule_contrib()
{
Ptr<Algorithm> efaces = createEigenfaces(), ffaces = createFisherfaces(), lbph = createLBPH();
// Allocates memory.
template<typename _Tp>
- _Tp **alloc_2d(int m, int n) {
+ _Tp **alloc_2d(int m, int _n) {
_Tp **arr = new _Tp*[m];
for (int i = 0; i < m; i++)
- arr[i] = new _Tp[n];
+ arr[i] = new _Tp[_n];
return arr;
}
// Allocates memory.
template<typename _Tp>
- _Tp **alloc_2d(int m, int n, _Tp val) {
- _Tp **arr = alloc_2d<_Tp> (m, n);
+ _Tp **alloc_2d(int m, int _n, _Tp val) {
+ _Tp **arr = alloc_2d<_Tp> (m, _n);
for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
+ for (int j = 0; j < _n; j++) {
arr[i][j] = val;
}
}
}
void cdiv(double xr, double xi, double yr, double yi) {
- double r, d;
+ double r, dv;
if (std::abs(yr) > std::abs(yi)) {
r = yi / yr;
- d = yr + r * yi;
- cdivr = (xr + r * xi) / d;
- cdivi = (xi - r * xr) / d;
+ dv = yr + r * yi;
+ cdivr = (xr + r * xi) / dv;
+ cdivi = (xi - r * xr) / dv;
} else {
r = yr / yi;
- d = yi + r * yr;
- cdivr = (r * xr + xi) / d;
- cdivi = (r * xi - xr) / d;
+ dv = yi + r * yr;
+ cdivr = (r * xr + xi) / dv;
+ cdivi = (r * xi - xr) / dv;
}
}
// Initialize
int nn = this->n;
- int n = nn - 1;
+ int n1 = nn - 1;
int low = 0;
int high = nn - 1;
double eps = pow(2.0, -52.0);
// Outer loop over eigenvalue index
int iter = 0;
- while (n >= low) {
+ while (n1 >= low) {
// Look for single small sub-diagonal element
- int l = n;
+ int l = n1;
while (l > low) {
s = std::abs(H[l - 1][l - 1]) + std::abs(H[l][l]);
if (s == 0.0) {
// Check for convergence
// One root found
- if (l == n) {
- H[n][n] = H[n][n] + exshift;
- d[n] = H[n][n];
- e[n] = 0.0;
- n--;
+ if (l == n1) {
+ H[n1][n1] = H[n1][n1] + exshift;
+ d[n1] = H[n1][n1];
+ e[n1] = 0.0;
+ n1--;
iter = 0;
// Two roots found
- } else if (l == n - 1) {
- w = H[n][n - 1] * H[n - 1][n];
- p = (H[n - 1][n - 1] - H[n][n]) / 2.0;
+ } else if (l == n1 - 1) {
+ w = H[n1][n1 - 1] * H[n1 - 1][n1];
+ p = (H[n1 - 1][n1 - 1] - H[n1][n1]) / 2.0;
q = p * p + w;
z = sqrt(std::abs(q));
- H[n][n] = H[n][n] + exshift;
- H[n - 1][n - 1] = H[n - 1][n - 1] + exshift;
- x = H[n][n];
+ H[n1][n1] = H[n1][n1] + exshift;
+ H[n1 - 1][n1 - 1] = H[n1 - 1][n1 - 1] + exshift;
+ x = H[n1][n1];
// Real pair
} else {
z = p - z;
}
- d[n - 1] = x + z;
- d[n] = d[n - 1];
+ d[n1 - 1] = x + z;
+ d[n1] = d[n1 - 1];
if (z != 0.0) {
- d[n] = x - w / z;
+ d[n1] = x - w / z;
}
- e[n - 1] = 0.0;
- e[n] = 0.0;
- x = H[n][n - 1];
+ e[n1 - 1] = 0.0;
+ e[n1] = 0.0;
+ x = H[n1][n1 - 1];
s = std::abs(x) + std::abs(z);
p = x / s;
q = z / s;
// Row modification
- for (int j = n - 1; j < nn; j++) {
- z = H[n - 1][j];
- H[n - 1][j] = q * z + p * H[n][j];
- H[n][j] = q * H[n][j] - p * z;
+ for (int j = n1 - 1; j < nn; j++) {
+ z = H[n1 - 1][j];
+ H[n1 - 1][j] = q * z + p * H[n1][j];
+ H[n1][j] = q * H[n1][j] - p * z;
}
// Column modification
- for (int i = 0; i <= n; i++) {
- z = H[i][n - 1];
- H[i][n - 1] = q * z + p * H[i][n];
- H[i][n] = q * H[i][n] - p * z;
+ for (int i = 0; i <= n1; i++) {
+ z = H[i][n1 - 1];
+ H[i][n1 - 1] = q * z + p * H[i][n1];
+ H[i][n1] = q * H[i][n1] - p * z;
}
// Accumulate transformations
for (int i = low; i <= high; i++) {
- z = V[i][n - 1];
- V[i][n - 1] = q * z + p * V[i][n];
- V[i][n] = q * V[i][n] - p * z;
+ z = V[i][n1 - 1];
+ V[i][n1 - 1] = q * z + p * V[i][n1];
+ V[i][n1] = q * V[i][n1] - p * z;
}
// Complex pair
} else {
- d[n - 1] = x + p;
- d[n] = x + p;
- e[n - 1] = z;
- e[n] = -z;
+ d[n1 - 1] = x + p;
+ d[n1] = x + p;
+ e[n1 - 1] = z;
+ e[n1] = -z;
}
- n = n - 2;
+ n1 = n1 - 2;
iter = 0;
// No convergence yet
// Form shift
- x = H[n][n];
+ x = H[n1][n1];
y = 0.0;
w = 0.0;
- if (l < n) {
- y = H[n - 1][n - 1];
- w = H[n][n - 1] * H[n - 1][n];
+ if (l < n1) {
+ y = H[n1 - 1][n1 - 1];
+ w = H[n1][n1 - 1] * H[n1 - 1][n1];
}
// Wilkinson's original ad hoc shift
if (iter == 10) {
exshift += x;
- for (int i = low; i <= n; i++) {
+ for (int i = low; i <= n1; i++) {
H[i][i] -= x;
}
- s = std::abs(H[n][n - 1]) + std::abs(H[n - 1][n - 2]);
+ s = std::abs(H[n1][n1 - 1]) + std::abs(H[n1 - 1][n1 - 2]);
x = y = 0.75 * s;
w = -0.4375 * s * s;
}
s = -s;
}
s = x - w / ((y - x) / 2.0 + s);
- for (int i = low; i <= n; i++) {
+ for (int i = low; i <= n1; i++) {
H[i][i] -= s;
}
exshift += s;
iter = iter + 1; // (Could check iteration count here.)
// Look for two consecutive small sub-diagonal elements
- int m = n - 2;
+ int m = n1 - 2;
while (m >= l) {
z = H[m][m];
r = x - z;
m--;
}
- for (int i = m + 2; i <= n; i++) {
+ for (int i = m + 2; i <= n1; i++) {
H[i][i - 2] = 0.0;
if (i > m + 2) {
H[i][i - 3] = 0.0;
// Double QR step involving rows l:n and columns m:n
- for (int k = m; k <= n - 1; k++) {
- bool notlast = (k != n - 1);
+ for (int k = m; k <= n1 - 1; k++) {
+ bool notlast = (k != n1 - 1);
if (k != m) {
p = H[k][k - 1];
q = H[k + 1][k - 1];
// Column modification
- for (int i = 0; i <= min(n, k + 3); i++) {
+ for (int i = 0; i <= min(n1, k + 3); i++) {
p = x * H[i][k] + y * H[i][k + 1];
if (notlast) {
p = p + z * H[i][k + 2];
} // (s != 0)
} // k loop
} // check convergence
- } // while (n >= low)
+ } // while (n1 >= low)
// Backsubstitute to find vectors of upper triangular form
return;
}
- for (n = nn - 1; n >= 0; n--) {
- p = d[n];
- q = e[n];
+ for (n1 = nn - 1; n1 >= 0; n1--) {
+ p = d[n1];
+ q = e[n1];
// Real vector
if (q == 0) {
- int l = n;
- H[n][n] = 1.0;
- for (int i = n - 1; i >= 0; i--) {
+ int l = n1;
+ H[n1][n1] = 1.0;
+ for (int i = n1 - 1; i >= 0; i--) {
w = H[i][i] - p;
r = 0.0;
- for (int j = l; j <= n; j++) {
- r = r + H[i][j] * H[j][n];
+ for (int j = l; j <= n1; j++) {
+ r = r + H[i][j] * H[j][n1];
}
if (e[i] < 0.0) {
z = w;
l = i;
if (e[i] == 0.0) {
if (w != 0.0) {
- H[i][n] = -r / w;
+ H[i][n1] = -r / w;
} else {
- H[i][n] = -r / (eps * norm);
+ H[i][n1] = -r / (eps * norm);
}
// Solve real equations
y = H[i + 1][i];
q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
t = (x * s - z * r) / q;
- H[i][n] = t;
+ H[i][n1] = t;
if (std::abs(x) > std::abs(z)) {
- H[i + 1][n] = (-r - w * t) / x;
+ H[i + 1][n1] = (-r - w * t) / x;
} else {
- H[i + 1][n] = (-s - y * t) / z;
+ H[i + 1][n1] = (-s - y * t) / z;
}
}
// Overflow control
- t = std::abs(H[i][n]);
+ t = std::abs(H[i][n1]);
if ((eps * t) * t > 1) {
- for (int j = i; j <= n; j++) {
- H[j][n] = H[j][n] / t;
+ for (int j = i; j <= n1; j++) {
+ H[j][n1] = H[j][n1] / t;
}
}
}
// Complex vector
} else if (q < 0) {
- int l = n - 1;
+ int l = n1 - 1;
// Last vector component imaginary so matrix is triangular
- if (std::abs(H[n][n - 1]) > std::abs(H[n - 1][n])) {
- H[n - 1][n - 1] = q / H[n][n - 1];
- H[n - 1][n] = -(H[n][n] - p) / H[n][n - 1];
+ if (std::abs(H[n1][n1 - 1]) > std::abs(H[n1 - 1][n1])) {
+ H[n1 - 1][n1 - 1] = q / H[n1][n1 - 1];
+ H[n1 - 1][n1] = -(H[n1][n1] - p) / H[n1][n1 - 1];
} else {
- cdiv(0.0, -H[n - 1][n], H[n - 1][n - 1] - p, q);
- H[n - 1][n - 1] = cdivr;
- H[n - 1][n] = cdivi;
+ cdiv(0.0, -H[n1 - 1][n1], H[n1 - 1][n1 - 1] - p, q);
+ H[n1 - 1][n1 - 1] = cdivr;
+ H[n1 - 1][n1] = cdivi;
}
- H[n][n - 1] = 0.0;
- H[n][n] = 1.0;
- for (int i = n - 2; i >= 0; i--) {
+ H[n1][n1 - 1] = 0.0;
+ H[n1][n1] = 1.0;
+ for (int i = n1 - 2; i >= 0; i--) {
double ra, sa, vr, vi;
ra = 0.0;
sa = 0.0;
- for (int j = l; j <= n; j++) {
- ra = ra + H[i][j] * H[j][n - 1];
- sa = sa + H[i][j] * H[j][n];
+ for (int j = l; j <= n1; j++) {
+ ra = ra + H[i][j] * H[j][n1 - 1];
+ sa = sa + H[i][j] * H[j][n1];
}
w = H[i][i] - p;
l = i;
if (e[i] == 0) {
cdiv(-ra, -sa, w, q);
- H[i][n - 1] = cdivr;
- H[i][n] = cdivi;
+ H[i][n1 - 1] = cdivr;
+ H[i][n1] = cdivi;
} else {
// Solve complex equations
}
cdiv(x * r - z * ra + q * sa,
x * s - z * sa - q * ra, vr, vi);
- H[i][n - 1] = cdivr;
- H[i][n] = cdivi;
+ H[i][n1 - 1] = cdivr;
+ H[i][n1] = cdivi;
if (std::abs(x) > (std::abs(z) + std::abs(q))) {
- H[i + 1][n - 1] = (-ra - w * H[i][n - 1] + q
- * H[i][n]) / x;
- H[i + 1][n] = (-sa - w * H[i][n] - q * H[i][n
+ H[i + 1][n1 - 1] = (-ra - w * H[i][n1 - 1] + q
+ * H[i][n1]) / x;
+ H[i + 1][n1] = (-sa - w * H[i][n1] - q * H[i][n1
- 1]) / x;
} else {
- cdiv(-r - y * H[i][n - 1], -s - y * H[i][n], z,
+ cdiv(-r - y * H[i][n1 - 1], -s - y * H[i][n1], z,
q);
- H[i + 1][n - 1] = cdivr;
- H[i + 1][n] = cdivi;
+ H[i + 1][n1 - 1] = cdivr;
+ H[i + 1][n1] = cdivi;
}
}
// Overflow control
- t = max(std::abs(H[i][n - 1]), std::abs(H[i][n]));
+ t = max(std::abs(H[i][n1 - 1]), std::abs(H[i][n1]));
if ((eps * t) * t > 1) {
- for (int j = i; j <= n; j++) {
- H[j][n - 1] = H[j][n - 1] / t;
- H[j][n] = H[j][n] / t;
+ for (int j = i; j <= n1; j++) {
+ H[j][n1 - 1] = H[j][n1 - 1] / t;
+ H[j][n1] = H[j][n1] / t;
}
}
}
namespace cv
{
-
+
//------------------------------------interp-------------------------------------------
-LogPolar_Interp::LogPolar_Interp(int w, int h, Point2i center, int R, double ro0, int interp, int full, int S, int sp)
+LogPolar_Interp::LogPolar_Interp(int w, int h, Point2i center, int _R, double _ro0, int _interp, int full, int _S, int sp)
{
if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1;
if (sp){
int jc=M/2-1, ic=N/2-1;
- int romax=min(ic, jc);
- double a=exp(log((double)(romax/2-1)/(double)ro0)/(double)R);
- S=(int) floor(2*CV_PI/(a-1)+0.5);
+ int _romax=min(ic, jc);
+ double _a=exp(log((double)(_romax/2-1)/(double)ro0)/(double)R);
+ S=(int) floor(2*CV_PI/(_a-1)+0.5);
}
- this->interp=interp;
+ interp=_interp;
- create_map(M, N, R, S, ro0);
+ create_map(M, N, _R, _S, _ro0);
}
-void LogPolar_Interp::create_map(int M, int N, int R, int S, double ro0)
+void LogPolar_Interp::create_map(int _M, int _N, int _R, int _S, double _ro0)
{
- this->M=M;
- this->N=N;
- this->R=R;
- this->S=S;
- this->ro0=ro0;
+ M=_M;
+ N=_N;
+ R=_R;
+ S=_S;
+ ro0=_ro0;
int jc=N/2-1, ic=M/2-1;
romax=min(ic, jc);
for(int u=0; u<R; u++)
{
Rsri.at<float>(v,u)=(float)(ro0*pow(a,u)*sin(v/q)+jc);
- Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic);
+ Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic);
}
}
const Mat LogPolar_Interp::to_cortical(const Mat &source)
{
Mat out(S,R,CV_8UC1,Scalar(0));
-
+
Mat source_border;
copyMakeBorder(source,source_border,top,bottom,left,right,BORDER_CONSTANT,Scalar(0));
Mat out(N,M,CV_8UC1,Scalar(0));
Mat source_border;
-
+
if (interp==INTER_NEAREST || interp==INTER_LINEAR){
copyMakeBorder(source,source_border,0,1,0,0,BORDER_CONSTANT,Scalar(0));
Mat rowS0 = source_border.row(S);
//------------------------------------overlapping----------------------------------
-LogPolar_Overlapping::LogPolar_Overlapping(int w, int h, Point2i center, int R, double ro0, int full, int S, int sp)
+LogPolar_Overlapping::LogPolar_Overlapping(int w, int h, Point2i center, int _R, double _ro0, int full, int _S, int sp)
{
if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1;
if (sp){
int jc=M/2-1, ic=N/2-1;
- int romax=min(ic, jc);
- double a=exp(log((double)(romax/2-1)/(double)ro0)/(double)R);
- S=(int) floor(2*CV_PI/(a-1)+0.5);
+ int _romax=min(ic, jc);
+ double _a=exp(log((double)(_romax/2-1)/(double)ro0)/(double)R);
+ S=(int) floor(2*CV_PI/(_a-1)+0.5);
}
- create_map(M, N, R, S, ro0);
+ create_map(M, N, _R, _S, _ro0);
}
-void LogPolar_Overlapping::create_map(int M, int N, int R, int S, double ro0)
+void LogPolar_Overlapping::create_map(int _M, int _N, int _R, int _S, double _ro0)
{
- this->M=M;
- this->N=N;
- this->R=R;
- this->S=S;
- this->ro0=ro0;
+ M=_M;
+ N=_N;
+ R=_R;
+ S=_S;
+ ro0=_ro0;
int jc=N/2-1, ic=M/2-1;
romax=min(ic, jc);
for(int u=0; u<R; u++)
{
Rsri.at<float>(v,u)=(float)(ro0*pow(a,u)*sin(v/q)+jc);
- Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic);
+ Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic);
Rsr[v*R+u]=(int)floor(Rsri.at<float>(v,u));
- Csr[v*R+u]=(int)floor(Csri.at<float>(v,u));
+ Csr[v*R+u]=(int)floor(Csri.at<float>(v,u));
}
}
bool done=false;
-
+
for(int i=0; i<R; i++)
{
Wsr[i]=ro0*(a-1)*pow(a,i-1);
done =true;
}
}
-
+
for(int j=0; j<N; j++)
{
for(int i=0; i<M; i++)//mdf
theta+=2*CV_PI;
ETAyx.at<float>(j,i)=(float)(q*theta);
-
+
double ro2=(j-jc)*(j-jc)+(i-ic)*(i-ic);
CSIyx.at<float>(j,i)=(float)(0.5*log(ro2/(ro0*ro0))/log(a));
}
remap(source_border,out,CSIyx,ETAyx,INTER_LINEAR);
int wm=w_ker_2D[R-1].w;
-
+
vector<double> IMG((N+2*wm+1)*(M+2*wm+1), 0.);
vector<double> NOR((N+2*wm+1)*(M+2*wm+1), 0.);
Mat out_cropped=out(Range(top,N-1-bottom),Range(left,M-1-right));
return out_cropped;
}
-
+
LogPolar_Overlapping::~LogPolar_Overlapping()
{
}
//----------------------------------------adjacent---------------------------------------
-LogPolar_Adjacent::LogPolar_Adjacent(int w, int h, Point2i center, int R, double ro0, double smin, int full, int S, int sp)
+LogPolar_Adjacent::LogPolar_Adjacent(int w, int h, Point2i center, int _R, double _ro0, double smin, int full, int _S, int sp)
{
if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1;
if (sp){
int jc=M/2-1, ic=N/2-1;
- int romax=min(ic, jc);
- double a=exp(log((double)(romax/2-1)/(double)ro0)/(double)R);
- S=(int) floor(2*CV_PI/(a-1)+0.5);
+ int _romax=min(ic, jc);
+ double _a=exp(log((double)(_romax/2-1)/(double)ro0)/(double)R);
+ S=(int) floor(2*CV_PI/(_a-1)+0.5);
}
- create_map(M, N, R, S, ro0, smin);
+ create_map(M, N, _R, _S, _ro0, smin);
}
-void LogPolar_Adjacent::create_map(int M, int N, int R, int S, double ro0, double smin)
+void LogPolar_Adjacent::create_map(int _M, int _N, int _R, int _S, double _ro0, double smin)
{
- LogPolar_Adjacent::M=M;
- LogPolar_Adjacent::N=N;
- LogPolar_Adjacent::R=R;
- LogPolar_Adjacent::S=S;
- LogPolar_Adjacent::ro0=ro0;
+ M=_M;
+ N=_N;
+ R=_R;
+ S=_S;
+ ro0=_ro0;
romax=min(M/2.0, N/2.0);
a=exp(log(romax/ro0)/(double)R);
void LogPolar_Adjacent::subdivide_recursively(double x, double y, int i, int j, double length, double smin)
-{
+{
if(length<=smin)
{
int u, v;
for(int j=0; j<N; j++)
for(int i=0; i<M; i++)
- {
+ {
for(size_t z=0; z<(L[M*j+i]).size(); z++)
{
map[R*((L[M*j+i])[z].v)+((L[M*j+i])[z].u)]+=((L[M*j+i])[z].a)*(source_border.at<uchar>(j,i));
else
v= (int) floor(q*(theta+2*CV_PI));
return true;
- }
+ }
}
LogPolar_Adjacent::~LogPolar_Adjacent()
{
}
- Octree::Octree(const vector<Point3f>& points3d, int maxLevels, int minPoints)
+ Octree::Octree(const vector<Point3f>& points3d, int maxLevels, int _minPoints)
{
- buildTree(points3d, maxLevels, minPoints);
+ buildTree(points3d, maxLevels, _minPoints);
}
Octree::~Octree()
}
}
- void Octree::buildTree(const vector<Point3f>& points3d, int maxLevels, int minPoints)
+ void Octree::buildTree(const vector<Point3f>& points3d, int maxLevels, int _minPoints)
{
assert((size_t)maxLevels * 8 < MAX_STACK_SIZE);
points.resize(points3d.size());
std::copy(points3d.begin(), points3d.end(), points.begin());
- this->minPoints = minPoints;
+ minPoints = _minPoints;
nodes.clear();
nodes.push_back(Node());
for (size_t i = 0; i < MAX_LEAFS; i++)
root.children[i] = 0;
- if (maxLevels != 1 && (root.end - root.begin) > minPoints)
+ if (maxLevels != 1 && (root.end - root.begin) > _minPoints)
{
root.isLeaf = false;
buildNext(0);
namespace cv
{
-Retina::Retina(const cv::Size inputSize)
+Retina::Retina(const cv::Size inputSz)
{
_retinaFilter = 0;
- _init(inputSize, true, RETINA_COLOR_BAYER, false);
+ _init(inputSz, true, RETINA_COLOR_BAYER, false);
}
-Retina::Retina(const cv::Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
+Retina::Retina(const cv::Size inputSz, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
{
_retinaFilter = 0;
- _init(inputSize, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
+ _init(inputSz, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
};
Retina::~Retina()
const std::valarray<float> & Retina::getParvo() const {if (_retinaFilter->getColorMode())return _retinaFilter->getColorOutput(); /* implicite else */return _retinaFilter->getContours();}
// private method called by constructirs
-void Retina::_init(const cv::Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
+void Retina::_init(const cv::Size inputSz, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
{
// basic error check
- if (inputSize.height*inputSize.width <= 0)
+ if (inputSz.height*inputSz.width <= 0)
throw cv::Exception(-1, "Bad retina size setup : size height and with must be superior to zero", "Retina::setup", "Retina.h", 0);
- unsigned int nbPixels=inputSize.height*inputSize.width;
+ unsigned int nbPixels=inputSz.height*inputSz.width;
// resize buffers if size does not match
_inputBuffer.resize(nbPixels*3); // buffer supports gray images but also 3 channels color buffers... (larger is better...)
// allocate the retina model
if (_retinaFilter)
delete _retinaFilter;
- _retinaFilter = new RetinaFilter(inputSize.height, inputSize.width, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
+ _retinaFilter = new RetinaFilter(inputSz.height, inputSz.width, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
// prepare the default parameter XML file with default setup
setup(_retinaParameters);
}else
{
- register const float *multiplexedColorFramePTR= get_data(multiplexedColorFrame);
- for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance, ++multiplexedColorFramePTR)
+ register const float *multiplexedColorFramePTR1= get_data(multiplexedColorFrame);
+ for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance, ++multiplexedColorFramePTR1)
{
// normalize by photoreceptors density
float Cr=*(chrominancePTR)*_colorLocalDensity[indexc];
float Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()];
float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()];
*luminance=(Cr+Cg+Cb)*_pG;
- _demultiplexedTempBuffer[_colorSampling[indexc]] = *multiplexedColorFramePTR - *luminance;
+ _demultiplexedTempBuffer[_colorSampling[indexc]] = *multiplexedColorFramePTR1 - *luminance;
}
using std::min;
using std::sqrt;
}
-namespace
+namespace
{
- const static Scalar colors[] =
+ const static Scalar colors[] =
{
CV_RGB(255, 0, 0),
CV_RGB( 0, 255, 0),
template<class FwIt, class T> void iota(FwIt first, FwIt last, T value) { while(first != last) *first++ = value++; }
-void computeNormals( const Octree& Octree, const vector<Point3f>& centers, vector<Point3f>& normals,
+void computeNormals( const Octree& Octree, const vector<Point3f>& centers, vector<Point3f>& normals,
vector<uchar>& mask, float normalRadius, int minNeighbors = 20)
-{
+{
size_t normals_size = centers.size();
normals.resize(normals_size);
-
+
if (mask.size() != normals_size)
{
- size_t m = mask.size();
+ size_t m = mask.size();
mask.resize(normals_size);
if (normals_size > m)
for(; m < normals_size; ++m)
mask[m] = 1;
}
-
+
vector<Point3f> buffer;
buffer.reserve(128);
SVD svd;
mean.x /= buf_size;
mean.y /= buf_size;
mean.z /= buf_size;
-
+
double pxpx = 0;
double pypy = 0;
double pzpz = 0;
/*normals[n] = Point3f( (float)((double*)svd.vt.data)[6],
(float)((double*)svd.vt.data)[7],
- (float)((double*)svd.vt.data)[8] );*/
- normals[n] = reinterpret_cast<Point3d*>(svd.vt.data)[2];
- mask[n] = 1;
+ (float)((double*)svd.vt.data)[8] );*/
+ normals[n] = reinterpret_cast<Point3d*>(svd.vt.data)[2];
+ mask[n] = 1;
}
}
}
inline __m128i _mm_mullo_epi32_emul(const __m128i& a, __m128i& b)
-{
+{
__m128i pack = _mm_packs_epi32(a, a);
- return _mm_unpacklo_epi16(_mm_mullo_epi16(pack, b), _mm_mulhi_epi16(pack, b));
+ return _mm_unpacklo_epi16(_mm_mullo_epi16(pack, b), _mm_mulhi_epi16(pack, b));
}
#endif
-void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, const vector<Point3f>& normals,
+void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, const vector<Point3f>& normals,
vector<uchar>& mask, Mat& spinImages, int imageWidth, float binSize)
-{
+{
float pixelsPerMeter = 1.f / binSize;
- float support = imageWidth * binSize;
-
+ float support = imageWidth * binSize;
+
assert(normals.size() == points.size());
assert(mask.size() == points.size());
-
+
size_t points_size = points.size();
mask.resize(points_size);
int t = cvGetThreadNum();
vector<Point3f>& pointsInSphere = pointsInSpherePool[t];
-
+
const Point3f& center = points[i];
Octree.getPointsWithinSphere(center, searchRad, pointsInSphere);
}
const Point3f& normal = normals[i];
-
+
float rotmat[9];
initRotationMat(normal, rotmat);
Point3f new_center;
{
__m128 rotmatSSE[3];
convertTransformMatrix(rotmat, (float*)rotmatSSE);
-
+
__m128 center_x4 = _mm_set1_ps(new_center.x);
__m128 center_y4 = _mm_set1_ps(new_center.y);
__m128 center_z4 = _mm_set1_ps(new_center.z + halfSuppport);
__m128 z0 = _mm_unpackhi_ps(pt0, pt1); // z0 z1 . .
__m128 z1 = _mm_unpackhi_ps(pt2, pt3); // z2 z3 . .
__m128 beta4 = _mm_sub_ps(center_z4, _mm_movelh_ps(z0, z1)); // b0 b1 b2 b3
-
+
__m128 xy0 = _mm_unpacklo_ps(pt0, pt1); // x0 x1 y0 y1
__m128 xy1 = _mm_unpacklo_ps(pt2, pt3); // x2 x3 y2 y3
__m128 x4 = _mm_movelh_ps(xy0, xy1); // x0 x1 x2 x3
x4 = _mm_sub_ps(x4, center_x4);
y4 = _mm_sub_ps(y4, center_y4);
__m128 alpha4 = _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(x4,x4),_mm_mul_ps(y4,y4)));
-
+
__m128 n1f4 = _mm_mul_ps( beta4, ppm4); /* beta4 float */
__m128 n2f4 = _mm_mul_ps(alpha4, ppm4); /* alpha4 float */
__m128 f1 = _mm_sub_ps( n1f4, _mm_cvtepi32_ps(n1) ); /* { beta4 } */
__m128 f2 = _mm_sub_ps( n2f4, _mm_cvtepi32_ps(n2) ); /* { alpha4 } */
- __m128 f1f2 = _mm_mul_ps(f1, f2); // f1 * f2
+ __m128 f1f2 = _mm_mul_ps(f1, f2); // f1 * f2
__m128 omf1omf2 = _mm_add_ps(_mm_sub_ps(_mm_sub_ps(one4f, f2), f1), f1f2); // (1-f1) * (1-f2)
-
- __m128i mask = _mm_and_si128(
+
+ __m128i _mask = _mm_and_si128(
_mm_andnot_si128(_mm_cmpgt_epi32(zero4, n1), _mm_cmpgt_epi32(height4m1, n1)),
_mm_andnot_si128(_mm_cmpgt_epi32(zero4, n2), _mm_cmpgt_epi32(width4m1, n2)));
- __m128 maskf = _mm_cmpneq_ps(_mm_cvtepi32_ps(mask), zero4f);
-
+ __m128 maskf = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mask), zero4f);
+
__m128 v00 = _mm_and_ps( omf1omf2 , maskf); // a00 b00 c00 d00
__m128 v01 = _mm_and_ps( _mm_sub_ps( f2, f1f2 ), maskf); // a01 b01 c01 d01
__m128 v10 = _mm_and_ps( _mm_sub_ps( f1, f1f2 ), maskf); // a10 b10 c10 d10
__m128 v11 = _mm_and_ps( f1f2 , maskf); // a11 b11 c11 d11
- __m128i ofs4 = _mm_and_si128(_mm_add_epi32(_mm_mullo_epi32_emul(n1, step4), n2), mask);
+ __m128i ofs4 = _mm_and_si128(_mm_add_epi32(_mm_mullo_epi32_emul(n1, step4), n2), _mask);
_mm_store_si128((__m128i*)o, ofs4);
__m128 t0 = _mm_unpacklo_ps(v00, v01); // a00 a01 b00 b01
if (beta >= support || beta < 0)
continue;
- alpha = sqrt( (new_center.x - pt.x) * (new_center.x - pt.x) +
- (new_center.y - pt.y) * (new_center.y - pt.y) );
-
+ alpha = sqrt( (new_center.x - pt.x) * (new_center.x - pt.x) +
+ (new_center.y - pt.y) * (new_center.y - pt.y) );
+
float n1f = beta * pixelsPerMeter;
float n2f = alpha * pixelsPerMeter;
float f1 = n1f - n1;
float f2 = n2f - n2;
- if ((unsigned)n1 >= (unsigned)(spinImage.rows-1) ||
+ if ((unsigned)n1 >= (unsigned)(spinImage.rows-1) ||
(unsigned)n2 >= (unsigned)(spinImage.cols-1))
continue;
vector<double> dist(tryNum * neighbors);
vector<int> inds(tryNum * neighbors);
- vector<Point3f> query;
+ vector<Point3f> query;
- RNG& rng = theRNG();
+ RNG& rng = theRNG();
for(int i = 0; i < tryNum; ++i)
query.push_back(vtx[rng.next() % vtx.size()]);
-
+
CvMat cvinds = cvMat( (int)tryNum, neighbors, CV_32S, &inds[0] );
- CvMat cvdist = cvMat( (int)tryNum, neighbors, CV_64F, &dist[0] );
+ CvMat cvdist = cvMat( (int)tryNum, neighbors, CV_64F, &dist[0] );
CvMat cvquery = cvMat( (int)tryNum, 3, CV_32F, &query[0] );
- cvFindFeatures(tr, &cvquery, &cvinds, &cvdist, neighbors, 50);
+ cvFindFeatures(tr, &cvquery, &cvinds, &cvdist, neighbors, 50);
cvReleaseFeatureTree(tr);
- const int invalid_dist = -2;
+ const int invalid_dist = -2;
for(int i = 0; i < tryNum; ++i)
if (inds[i] == -1)
dist[i] = invalid_dist;
dist.resize(remove(dist.begin(), dist.end(), invalid_dist) - dist.begin());
-
+
sort(dist, less<double>());
-
+
return resolution = (float)dist[ dist.size() / 2 ];
#else
CV_Error(CV_StsNotImplemented, "");
{
buildOctree();
vector<uchar> mask(vtx.size(), 0);
- for(size_t i = 0; i < subset.size(); ++i)
+ for(size_t i = 0; i < subset.size(); ++i)
mask[subset[i]] = 1;
::computeNormals(octree, vtx, normals, mask, normalRadius, minNeighbors);
}
ofstream ofs(file.c_str());
ofs << "#VRML V2.0 utf8" << endl;
- ofs << "Shape" << std::endl << "{" << endl;
- ofs << "geometry PointSet" << endl << "{" << endl;
- ofs << "coord Coordinate" << endl << "{" << endl;
- ofs << "point[" << endl;
+ ofs << "Shape" << std::endl << "{" << endl;
+ ofs << "geometry PointSet" << endl << "{" << endl;
+ ofs << "coord Coordinate" << endl << "{" << endl;
+ ofs << "point[" << endl;
for(size_t i = 0; i < vtx.size(); ++i)
ofs << vtx[i].x << " " << vtx[i].y << " " << vtx[i].z << endl;
-
- ofs << "]" << endl; //point[
- ofs << "}" << endl; //Coordinate{
+
+ ofs << "]" << endl; //point[
+ ofs << "}" << endl; //Coordinate{
if (vtx.size() == _colors.size())
{
ofs << "color Color" << endl << "{" << endl;
ofs << "color[" << endl;
-
+
for(size_t i = 0; i < _colors.size(); ++i)
ofs << (float)_colors[i][2] << " " << (float)_colors[i][1] << " " << (float)_colors[i][0] << endl;
-
+
ofs << "]" << endl; //color[
- ofs << "}" << endl; //color Color{
+ ofs << "}" << endl; //color Color{
}
- ofs << "}" << endl; //PointSet{
- ofs << "}" << endl; //Shape{
+ ofs << "}" << endl; //PointSet{
+ ofs << "}" << endl; //Shape{
}
bool cv::SpinImageModel::spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result)
{
struct Math { static double atanh(double x) { return 0.5 * std::log( (1 + x) / (1 - x) ); } };
-
+
const float* s1 = spin1.ptr<float>();
const float* s2 = spin2.ptr<float>();
- int spin_sz = spin1.cols * spin1.rows;
+ int spin_sz = spin1.cols * spin1.rows;
double sum1 = 0.0, sum2 = 0.0, sum12 = 0.0, sum11 = 0.0, sum22 = 0.0;
int N = 0;
int i = 0;
#if CV_SSE2//____________TEMPORARY_DISABLED_____________
- float CV_DECL_ALIGNED(16) su1[4], su2[4], su11[4], su22[4], su12[4], n[4];
-
+ float CV_DECL_ALIGNED(16) su1[4], su2[4], su11[4], su22[4], su12[4], n[4];
+
__m128 zerof4 = _mm_setzero_ps();
__m128 onef4 = _mm_set1_ps(1.f);
- __m128 Nf4 = zerof4;
+ __m128 Nf4 = zerof4;
__m128 sum1f4 = zerof4;
__m128 sum2f4 = zerof4;
__m128 sum11f4 = zerof4;
__m128 sum22f4 = zerof4;
- __m128 sum12f4 = zerof4;
+ __m128 sum12f4 = zerof4;
for(; i < spin_sz - 5; i += 4)
{
- __m128 v1f4 = _mm_loadu_ps(s1 + i);
- __m128 v2f4 = _mm_loadu_ps(s2 + i);
+ __m128 v1f4 = _mm_loadu_ps(s1 + i);
+ __m128 v2f4 = _mm_loadu_ps(s2 + i);
__m128 mskf4 = _mm_and_ps(_mm_cmpneq_ps(v1f4, zerof4), _mm_cmpneq_ps(v2f4, zerof4));
- if( !_mm_movemask_ps(mskf4) )
+ if( !_mm_movemask_ps(mskf4) )
continue;
-
+
Nf4 = _mm_add_ps(Nf4, _mm_and_ps(onef4, mskf4));
v1f4 = _mm_and_ps(v1f4, mskf4);
v2f4 = _mm_and_ps(v2f4, mskf4);
-
+
sum1f4 = _mm_add_ps(sum1f4, v1f4);
sum2f4 = _mm_add_ps(sum2f4, v2f4);
sum11f4 = _mm_add_ps(sum11f4, _mm_mul_ps(v1f4, v1f4));
sum22f4 = _mm_add_ps(sum22f4, _mm_mul_ps(v2f4, v2f4));
- sum12f4 = _mm_add_ps(sum12f4, _mm_mul_ps(v1f4, v2f4));
+ sum12f4 = _mm_add_ps(sum12f4, _mm_mul_ps(v1f4, v2f4));
}
_mm_store_ps( su1, sum1f4 );
_mm_store_ps( su2, sum2f4 );
if( !v1 || !v2 )
continue;
N++;
-
- sum1 += v1;
- sum2 += v2;
- sum11 += v1 * v1;
- sum22 += v2 * v2;
+
+ sum1 += v1;
+ sum2 += v2;
+ sum11 += v1 * v1;
+ sum22 += v2 * v2;
sum12 += v1 * v2;
}
if( N < 4 )
double corr = (Nsum12 - sum1 * sum2) / sqrt( (Nsum11 - sum1sum1) * (Nsum22 - sum2sum2) );
double atanh = Math::atanh(corr);
result = (float)( atanh * atanh - lambda * ( 1.0 / (N - 3) ) );
- return true;
+ return true;
}
inline Point2f cv::SpinImageModel::calcSpinMapCoo(const Point3f& p, const Point3f& v, const Point3f& n)
-{
- /*Point3f PmV(p.x - v.x, p.y - v.y, p.z - v.z);
- float normalNorm = (float)norm(n);
+{
+ /*Point3f PmV(p.x - v.x, p.y - v.y, p.z - v.z);
+ float normalNorm = (float)norm(n);
float beta = PmV.dot(n) / normalNorm;
float pmcNorm = (float)norm(PmV);
float alpha = sqrt( pmcNorm * pmcNorm - beta * beta);
float pmv_x = p.x - v.x, pmv_y = p.y - v.y, pmv_z = p.z - v.z;
float beta = (pmv_x * n.x + pmv_y + n.y + pmv_z * n.z) / sqrt(n.x * n.x + n.y * n.y + n.z * n.z);
- float alpha = sqrt( pmv_x * pmv_x + pmv_y * pmv_y + pmv_z * pmv_z - beta * beta);
+ float alpha = sqrt( pmv_x * pmv_x + pmv_y * pmv_y + pmv_z * pmv_z - beta * beta);
return Point2f(alpha, beta);
}
inline float cv::SpinImageModel::geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1,
- const Point3f& pointScene2, const Point3f& normalScene2,
+ const Point3f& pointScene2, const Point3f& normalScene2,
const Point3f& pointModel2, const Point3f& normalModel2)
-{
+{
Point2f Sm2_to_m1, Ss2_to_s1;
Point2f Sm1_to_m2, Ss1_to_s2;
double n_Sm2_to_m1 = norm(Sm2_to_m1 = calcSpinMapCoo(pointModel2, pointModel1, normalModel1));
- double n_Ss2_to_s1 = norm(Ss2_to_s1 = calcSpinMapCoo(pointScene2, pointScene1, normalScene1));
+ double n_Ss2_to_s1 = norm(Ss2_to_s1 = calcSpinMapCoo(pointScene2, pointScene1, normalScene1));
double gc21 = 2 * norm(Sm2_to_m1 - Ss2_to_s1) / (n_Sm2_to_m1 + n_Ss2_to_s1 ) ;
-
+
double n_Sm1_to_m2 = norm(Sm1_to_m2 = calcSpinMapCoo(pointModel1, pointModel2, normalModel2));
double n_Ss1_to_s2 = norm(Ss1_to_s2 = calcSpinMapCoo(pointScene1, pointScene2, normalScene2));
inline float cv::SpinImageModel::groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1,
- const Point3f& pointScene2, const Point3f& normalScene2,
- const Point3f& pointModel2, const Point3f& normalModel2,
+ const Point3f& pointScene2, const Point3f& normalScene2,
+ const Point3f& pointModel2, const Point3f& normalModel2,
float gamma)
-{
+{
Point2f Sm2_to_m1, Ss2_to_s1;
Point2f Sm1_to_m2, Ss1_to_s2;
double gc21 = 2 * norm(Sm2_to_m1 - Ss2_to_s1) / (n_Sm2_to_m1 + n_Ss2_to_s1 );
double wgc21 = gc21 / (1 - exp( -(n_Sm2_to_m1 + n_Ss2_to_s1) * gamma05_inv ) );
-
+
double n_Sm1_to_m2 = norm(Sm1_to_m2 = calcSpinMapCoo(pointModel1, pointModel2, normalModel2));
double n_Ss1_to_s2 = norm(Ss1_to_s2 = calcSpinMapCoo(pointScene1, pointScene2, normalScene2));
cv::SpinImageModel::SpinImageModel(const Mesh3D& _mesh) : mesh(_mesh) , out(0)
-{
+{
if (mesh.vtx.empty())
throw Mesh3D::EmptyMeshException();
- defaultParams();
+ defaultParams();
}
cv::SpinImageModel::SpinImageModel() : out(0) { defaultParams(); }
cv::SpinImageModel::~SpinImageModel() {}
minNeighbors = 20;
binSize = 0.f; /* autodetect according to mesh resolution */
- imageWidth = 32;
-
+ imageWidth = 32;
+
lambda = 0.f; /* autodetect according to medan non zero images bin */
gamma = 0.f; /* autodetect according to mesh resolution */
if (num == 0)
return Mat();
- RNG& rng = theRNG();
+ RNG& rng = theRNG();
vector<Mat> spins;
for(int i = 0; i < num; ++i)
- spins.push_back(getSpinImage( rng.next() % spinNum ).reshape(1, imageWidth));
-
+ spins.push_back(getSpinImage( rng.next() % spinNum ).reshape(1, imageWidth));
+
if (separateScale)
for(int i = 0; i < num; ++i)
{
double max;
Mat spin8u;
- minMaxLoc(spins[i], 0, &max);
+ minMaxLoc(spins[i], 0, &max);
spins[i].convertTo(spin8u, CV_8U, -255.0/max, 255.0);
spins[i] = spin8u;
}
else
- {
+ {
double totalMax = 0;
for(int i = 0; i < num; ++i)
{
double m;
- minMaxLoc(spins[i], 0, &m);
+ minMaxLoc(spins[i], 0, &m);
totalMax = max(m, totalMax);
}
int sz = spins.front().cols;
- Mat result((int)(yCount * sz + (yCount - 1)), (int)(xCount * sz + (xCount - 1)), CV_8UC3);
+ Mat result((int)(yCount * sz + (yCount - 1)), (int)(xCount * sz + (xCount - 1)), CV_8UC3);
result = colors[(static_cast<int64>(cvGetTickCount()/cvGetTickFrequency())/1000) % colors_mum];
int pos = 0;
for(int y = 0; y < (int)yCount; ++y)
- for(int x = 0; x < (int)xCount; ++x)
+ for(int x = 0; x < (int)xCount; ++x)
if (pos < num)
{
int starty = (y + 0) * sz + y;
cvtColor(spins[pos++], color, CV_GRAY2BGR);
Mat roi = result(Range(starty, endy), Range(startx, endx));
color.copyTo(roi);
- }
+ }
return result;
}
int pos = rnd.next() % left.size();
subset[i] = (int)left[pos];
- left[pos] = left.back();
- left.resize(left.size() - 1);
+ left[pos] = left.back();
+ left.resize(left.size() - 1);
}
sort(subset, less<int>());
}
subset = ss;
}
-void cv::SpinImageModel::repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc) const
-{
+void cv::SpinImageModel::repackSpinImages(const vector<uchar>& mask, Mat& _spinImages, bool reAlloc) const
+{
if (reAlloc)
{
size_t spinCount = mask.size() - count(mask.begin(), mask.end(), (uchar)0);
- Mat newImgs((int)spinCount, spinImages.cols, spinImages.type());
+ Mat newImgs((int)spinCount, _spinImages.cols, _spinImages.type());
int pos = 0;
for(size_t t = 0; t < mask.size(); ++t)
if (mask[t])
{
Mat row = newImgs.row(pos++);
- spinImages.row((int)t).copyTo(row);
+ _spinImages.row((int)t).copyTo(row);
}
- spinImages = newImgs;
+ _spinImages = newImgs;
}
else
{
int first = dest + 1;
for (; first != last; ++first)
- if (mask[first] != 0)
+ if (mask[first] != 0)
{
- Mat row = spinImages.row(dest);
- spinImages.row(first).copyTo(row);
+ Mat row = _spinImages.row(dest);
+ _spinImages.row(first).copyTo(row);
++dest;
}
- spinImages = spinImages.rowRange(0, dest);
+ _spinImages = _spinImages.rowRange(0, dest);
}
}
if (binSize == 0.f)
{
if (mesh.resolution == -1.f)
- mesh.estimateResolution();
+ mesh.estimateResolution();
binSize = mesh.resolution;
}
- /* estimate normalRadius */
- normalRadius = normalRadius != 0.f ? normalRadius : binSize * imageWidth / 2;
+ /* estimate normalRadius */
+ normalRadius = normalRadius != 0.f ? normalRadius : binSize * imageWidth / 2;
- mesh.buildOctree();
+ mesh.buildOctree();
if (subset.empty())
{
mesh.computeNormals(normalRadius, minNeighbors);
else
mesh.computeNormals(subset, normalRadius, minNeighbors);
- vector<uchar> mask(mesh.vtx.size(), 0);
+ vector<uchar> mask(mesh.vtx.size(), 0);
for(size_t i = 0; i < subset.size(); ++i)
- if (mesh.normals[subset[i]] == Mesh3D::allzero)
- subset[i] = -1;
+ if (mesh.normals[subset[i]] == Mesh3D::allzero)
+ subset[i] = -1;
else
mask[subset[i]] = 1;
subset.resize( remove(subset.begin(), subset.end(), -1) - subset.begin() );
-
+
vector<Point3f> vtx;
- vector<Point3f> normals;
+ vector<Point3f> normals;
for(size_t i = 0; i < mask.size(); ++i)
if(mask[i])
{
for(size_t i = 0; i < mask.size(); ++i)
if(mask[i])
if (spinMask[mask_pos++] == 0)
- subset.resize( remove(subset.begin(), subset.end(), (int)i) - subset.begin() );
+ subset.resize( remove(subset.begin(), subset.end(), (int)i) - subset.begin() );
}
void cv::SpinImageModel::matchSpinToModel(const Mat& spin, vector<int>& indeces, vector<float>& corrCoeffs, bool useExtremeOutliers) const
vector<uchar> masks(model.spinImages.rows);
vector<float> cleanCorrs;
cleanCorrs.reserve(model.spinImages.rows);
-
+
for(int i = 0; i < model.spinImages.rows; ++i)
{
- masks[i] = spinCorrelation(spin, model.spinImages.row(i), model.lambda, corrs[i]);
+ masks[i] = spinCorrelation(spin, model.spinImages.row(i), model.lambda, corrs[i]);
if (masks[i])
cleanCorrs.push_back(corrs[i]);
}
-
+
/* Filtering by measure histogram */
size_t total = cleanCorrs.size();
if(total < 5)
return;
sort(cleanCorrs, less<float>());
-
+
float lower_fourth = cleanCorrs[(1 * total) / 4 - 1];
float upper_fourth = cleanCorrs[(3 * total) / 4 - 0];
float fourth_spread = upper_fourth - lower_fourth;
//extreme or moderate?
- float coef = useExtremeOutliers ? 3.0f : 1.5f;
+ float coef = useExtremeOutliers ? 3.0f : 1.5f;
+
+ float histThresHi = upper_fourth + coef * fourth_spread;
+ //float histThresLo = lower_fourth - coef * fourth_spread;
- float histThresHi = upper_fourth + coef * fourth_spread;
- //float histThresLo = lower_fourth - coef * fourth_spread;
-
for(size_t i = 0; i < corrs.size(); ++i)
if (masks[i])
if (/* corrs[i] < histThresLo || */ corrs[i] > histThresHi)
{
indeces.push_back((int)i);
- corrCoeffs.push_back(corrs[i]);
+ corrCoeffs.push_back(corrs[i]);
}
-}
+}
-namespace
+namespace
{
struct Match
{
- int sceneInd;
+ int sceneInd;
int modelInd;
float measure;
{
const float* wgcLine = mat.ptr<float>((int)corespInd);
float maximum = numeric_limits<float>::min();
-
+
for(citer pos = group.begin(); pos != group.end(); ++pos)
maximum = max(wgcLine[*pos], maximum);
}
void cv::SpinImageModel::match(const SpinImageModel& scene, vector< vector<Vec2i> >& result)
-{
+{
if (mesh.vtx.empty())
throw Mesh3D::EmptyMeshException();
SpinImageModel& model = *this;
const float infinity = numeric_limits<float>::infinity();
const float float_max = numeric_limits<float>::max();
-
+
/* estimate gamma */
if (model.gamma == 0.f)
{
if (model.mesh.resolution == -1.f)
- model.mesh.estimateResolution();
+ model.mesh.estimateResolution();
model.gamma = 4 * model.mesh.resolution;
}
/* estimate lambda */
if (model.lambda == 0.f)
{
- vector<int> nonzero(model.spinImages.rows);
+ vector<int> nonzero(model.spinImages.rows);
for(int i = 0; i < model.spinImages.rows; ++i)
nonzero[i] = countNonZero(model.spinImages.row(i));
sort(nonzero, less<int>());
model.lambda = static_cast<float>( nonzero[ nonzero.size()/2 ] ) / 2;
- }
-
+ }
+
TickMeter corr_timer;
corr_timer.start();
vector<Match> allMatches;
{
vector<int> indeces;
vector<float> coeffs;
- matchSpinToModel(scene.spinImages.row(i), indeces, coeffs);
+ matchSpinToModel(scene.spinImages.row(i), indeces, coeffs);
for(size_t t = 0; t < indeces.size(); ++t)
- allMatches.push_back(Match(i, indeces[t], coeffs[t]));
+ allMatches.push_back(Match(i, indeces[t], coeffs[t]));
- if (out) if (i % 100 == 0) *out << "Comparing scene spinimage " << i << " of " << scene.spinImages.rows << endl;
+ if (out) if (i % 100 == 0) *out << "Comparing scene spinimage " << i << " of " << scene.spinImages.rows << endl;
}
corr_timer.stop();
if (out) *out << "Spin correlation time = " << corr_timer << endl;
if (out) *out << "Matches number = " << allMatches.size() << endl;
- if(allMatches.empty())
+ if(allMatches.empty())
return;
-
+
/* filtering by similarity measure */
const float fraction = 0.5f;
- float maxMeasure = max_element(allMatches.begin(), allMatches.end(), less<float>())->measure;
+ float maxMeasure = max_element(allMatches.begin(), allMatches.end(), less<float>())->measure;
allMatches.erase(
- remove_if(allMatches.begin(), allMatches.end(), bind2nd(less<float>(), maxMeasure * fraction)),
+ remove_if(allMatches.begin(), allMatches.end(), bind2nd(less<float>(), maxMeasure * fraction)),
allMatches.end());
if (out) *out << "Matches number [filtered by similarity measure] = " << allMatches.size() << endl;
int matchesSize = (int)allMatches.size();
if(matchesSize == 0)
return;
-
- /* filtering by geometric consistency */
+
+ /* filtering by geometric consistency */
for(int i = 0; i < matchesSize; ++i)
{
int consistNum = 1;
float gc = float_max;
-
+
for(int j = 0; j < matchesSize; ++j)
if (i != j)
{
{
const Point3f& pointSceneI = scene.getSpinVertex(mi.sceneInd);
const Point3f& normalSceneI = scene.getSpinNormal(mi.sceneInd);
-
+
const Point3f& pointModelI = model.getSpinVertex(mi.modelInd);
const Point3f& normalModelI = model.getSpinNormal(mi.modelInd);
-
+
const Point3f& pointSceneJ = scene.getSpinVertex(mj.sceneInd);
const Point3f& normalSceneJ = scene.getSpinNormal(mj.sceneInd);
-
+
const Point3f& pointModelJ = model.getSpinVertex(mj.modelInd);
const Point3f& normalModelJ = model.getSpinNormal(mj.modelInd);
-
+
gc = geometricConsistency(pointSceneI, normalSceneI, pointModelI, normalModelI,
- pointSceneJ, normalSceneJ, pointModelJ, normalModelJ);
+ pointSceneJ, normalSceneJ, pointModelJ, normalModelJ);
}
if (gc < model.T_GeometriccConsistency)
++consistNum;
}
-
-
+
+
if (consistNum < matchesSize / 4) /* failed consistensy test */
- allMatches[i].measure = infinity;
+ allMatches[i].measure = infinity;
}
allMatches.erase(
- remove_if(allMatches.begin(), allMatches.end(), bind2nd(equal_to<float>(), infinity)),
- allMatches.end());
+ remove_if(allMatches.begin(), allMatches.end(), bind2nd(equal_to<float>(), infinity)),
+ allMatches.end());
if (out) *out << "Matches number [filtered by geometric consistency] = " << allMatches.size() << endl;
if (out) *out << "grouping ..." << endl;
Mat groupingMat((int)matchesSize, (int)matchesSize, CV_32F);
- groupingMat = Scalar(0);
-
+ groupingMat = Scalar(0);
+
/* grouping */
for(int j = 0; j < matchesSize; ++j)
- for(int i = j + 1; i < matchesSize; ++i)
+ for(int i = j + 1; i < matchesSize; ++i)
{
const Match& mi = allMatches[i];
const Match& mj = allMatches[j];
const Point3f& pointSceneI = scene.getSpinVertex(mi.sceneInd);
const Point3f& normalSceneI = scene.getSpinNormal(mi.sceneInd);
-
+
const Point3f& pointModelI = model.getSpinVertex(mi.modelInd);
const Point3f& normalModelI = model.getSpinNormal(mi.modelInd);
-
+
const Point3f& pointSceneJ = scene.getSpinVertex(mj.sceneInd);
const Point3f& normalSceneJ = scene.getSpinNormal(mj.sceneInd);
-
+
const Point3f& pointModelJ = model.getSpinVertex(mj.modelInd);
const Point3f& normalModelJ = model.getSpinNormal(mj.modelInd);
float wgc = groupingCreteria(pointSceneI, normalSceneI, pointModelI, normalModelI,
pointSceneJ, normalSceneJ, pointModelJ, normalModelJ,
- model.gamma);
-
+ model.gamma);
+
groupingMat.ptr<float>(i)[j] = wgc;
groupingMat.ptr<float>(j)[i] = wgc;
}
group_t allMatchesInds;
for(int i = 0; i < matchesSize; ++i)
allMatchesInds.insert(i);
-
+
vector<float> buf(matchesSize);
float *buf_beg = &buf[0];
vector<group_t> groups;
-
+
for(int g = 0; g < matchesSize; ++g)
- {
+ {
if (out) if (g % 100 == 0) *out << "G = " << g << endl;
group_t left = allMatchesInds;
group_t group;
-
+
left.erase(g);
group.insert(g);
-
+
for(;;)
{
size_t left_size = left.size();
if (left_size == 0)
break;
-
+
std::transform(left.begin(), left.end(), buf_beg, WgcHelper(group, groupingMat));
size_t minInd = min_element(buf_beg, buf_beg + left_size) - buf_beg;
-
+
if (buf[minInd] < model.T_GroupingCorespondances) /* can add corespondance to group */
{
iter pos = left.begin();
advance(pos, minInd);
-
+
group.insert(*pos);
left.erase(pos);
}
{
const Match& m = allMatches[*pos];
outgrp.push_back(Vec2i(subset[m.modelInd], scene.subset[m.sceneInd]));
- }
+ }
result.push_back(outgrp);
- }
+ }
}
cv::TickMeter::TickMeter() { reset(); }
int64 cv::TickMeter::getTimeTicks() const { return sumTime; }
double cv::TickMeter::getTimeMicro() const { return (double)getTimeTicks()/cvGetTickFrequency(); }
double cv::TickMeter::getTimeMilli() const { return getTimeMicro()*1e-3; }
-double cv::TickMeter::getTimeSec() const { return getTimeMilli()*1e-3; }
+double cv::TickMeter::getTimeSec() const { return getTimeMilli()*1e-3; }
int64 cv::TickMeter::getCounter() const { return counter; }
void cv::TickMeter::reset() {startTime = 0; sumTime = 0; counter = 0; }
Proceedings of the 5th International Symposium on Visual Computing, Vegas, USA
This code is written by Sergey G. Kosov for "Visir PX" application as part of Project X (www.project-10.de)
- */
+ */
#include "precomp.hpp"
#include <limits.h>
-namespace cv
+namespace cv
{
-StereoVar::StereoVar() : levels(3), pyrScale(0.5), nIt(5), minDisp(0), maxDisp(16), poly_n(3), poly_sigma(0), fi(25.0f), lambda(0.03f), penalization(PENALIZATION_TICHONOV), cycle(CYCLE_V), flags(USE_SMART_ID | USE_AUTO_PARAMS)
+StereoVar::StereoVar() : levels(3), pyrScale(0.5), nIt(5), minDisp(0), maxDisp(16), poly_n(3), poly_sigma(0), fi(25.0f), lambda(0.03f), penalization(PENALIZATION_TICHONOV), cycle(CYCLE_V), flags(USE_SMART_ID | USE_AUTO_PARAMS)
{
}
static Mat diffX(Mat &src)
{
- register int x, y, cols = src.cols - 1;
- Mat dst(src.size(), src.type());
- for(y = 0; y < src.rows; y++){
+ register int x, y, cols = src.cols - 1;
+ Mat dst(src.size(), src.type());
+ for(y = 0; y < src.rows; y++){
const float* pSrc = src.ptr<float>(y);
float* pDst = dst.ptr<float>(y);
#if CV_SSE2
static Mat getGradient(Mat &src)
{
- register int x, y;
- Mat dst(src.size(), src.type());
- dst.setTo(0);
- for (y = 0; y < src.rows - 1; y++) {
- float *pSrc = src.ptr<float>(y);
- float *pSrcF = src.ptr<float>(y + 1);
- float *pDst = dst.ptr<float>(y);
- for (x = 0; x < src.cols - 1; x++)
- pDst[x] = fabs(pSrc[x + 1] - pSrc[x]) + fabs(pSrcF[x] - pSrc[x]);
- }
- return dst;
+ register int x, y;
+ Mat dst(src.size(), src.type());
+ dst.setTo(0);
+ for (y = 0; y < src.rows - 1; y++) {
+ float *pSrc = src.ptr<float>(y);
+ float *pSrcF = src.ptr<float>(y + 1);
+ float *pDst = dst.ptr<float>(y);
+ for (x = 0; x < src.cols - 1; x++)
+ pDst[x] = fabs(pSrc[x + 1] - pSrc[x]) + fabs(pSrcF[x] - pSrc[x]);
+ }
+ return dst;
}
static Mat getG_c(Mat &src, float l)
{
- Mat dst(src.size(), src.type());
- for (register int y = 0; y < src.rows; y++) {
- float *pSrc = src.ptr<float>(y);
- float *pDst = dst.ptr<float>(y);
- for (register int x = 0; x < src.cols; x++)
- pDst[x] = 0.5f*l / sqrtf(l*l + pSrc[x]*pSrc[x]);
- }
- return dst;
+ Mat dst(src.size(), src.type());
+ for (register int y = 0; y < src.rows; y++) {
+ float *pSrc = src.ptr<float>(y);
+ float *pDst = dst.ptr<float>(y);
+ for (register int x = 0; x < src.cols; x++)
+ pDst[x] = 0.5f*l / sqrtf(l*l + pSrc[x]*pSrc[x]);
+ }
+ return dst;
}
static Mat getG_p(Mat &src, float l)
{
- Mat dst(src.size(), src.type());
- for (register int y = 0; y < src.rows; y++) {
- float *pSrc = src.ptr<float>(y);
- float *pDst = dst.ptr<float>(y);
- for (register int x = 0; x < src.cols; x++)
- pDst[x] = 0.5f*l*l / (l*l + pSrc[x]*pSrc[x]);
- }
- return dst;
+ Mat dst(src.size(), src.type());
+ for (register int y = 0; y < src.rows; y++) {
+ float *pSrc = src.ptr<float>(y);
+ float *pDst = dst.ptr<float>(y);
+ for (register int x = 0; x < src.cols; x++)
+ pDst[x] = 0.5f*l*l / (l*l + pSrc[x]*pSrc[x]);
+ }
+ return dst;
}
void StereoVar::VariationalSolver(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level)
{
- register int n, x, y;
- float gl = 1, gr = 1, gu = 1, gd = 1, gc = 4;
- Mat g_c, g_p;
- Mat U;
- u.copyTo(U);
-
- int N = nIt;
- float l = lambda;
- float Fi = fi;
-
-
- if (flags & USE_SMART_ID) {
- double scale = pow(pyrScale, (double) level) * (1 + pyrScale);
- N = (int) (N / scale);
- }
-
- double scale = pow(pyrScale, (double) level);
- Fi /= (float) scale;
- l *= (float) scale;
-
- int width = u.cols - 1;
- int height = u.rows - 1;
- for (n = 0; n < N; n++) {
- if (penalization != PENALIZATION_TICHONOV) {
- Mat gradient = getGradient(U);
- switch (penalization) {
- case PENALIZATION_CHARBONNIER: g_c = getG_c(gradient, l); break;
- case PENALIZATION_PERONA_MALIK: g_p = getG_p(gradient, l); break;
- }
- gradient.release();
- }
- for (y = 1 ; y < height; y++) {
- float *pU = U.ptr<float>(y);
- float *pUu = U.ptr<float>(y + 1);
- float *pUd = U.ptr<float>(y - 1);
- float *pu = u.ptr<float>(y);
- float *pI1 = I1.ptr<float>(y);
- float *pI2 = I2.ptr<float>(y);
- float *pI2x = I2x.ptr<float>(y);
- float *pG_c = NULL, *pG_cu = NULL, *pG_cd = NULL;
- float *pG_p = NULL, *pG_pu = NULL, *pG_pd = NULL;
- switch (penalization) {
- case PENALIZATION_CHARBONNIER:
- pG_c = g_c.ptr<float>(y);
- pG_cu = g_c.ptr<float>(y + 1);
- pG_cd = g_c.ptr<float>(y - 1);
- break;
- case PENALIZATION_PERONA_MALIK:
- pG_p = g_p.ptr<float>(y);
- pG_pu = g_p.ptr<float>(y + 1);
- pG_pd = g_p.ptr<float>(y - 1);
- break;
- }
- for (x = 1; x < width; x++) {
- switch (penalization) {
- case PENALIZATION_CHARBONNIER:
- gc = pG_c[x];
- gl = gc + pG_c[x - 1];
- gr = gc + pG_c[x + 1];
- gu = gc + pG_cu[x];
- gd = gc + pG_cd[x];
- gc = gl + gr + gu + gd;
- break;
- case PENALIZATION_PERONA_MALIK:
- gc = pG_p[x];
- gl = gc + pG_p[x - 1];
- gr = gc + pG_p[x + 1];
- gu = gc + pG_pu[x];
- gd = gc + pG_pd[x];
- gc = gl + gr + gu + gd;
- break;
- }
-
- float fi = Fi;
- if (maxDisp > minDisp) {
- if (pU[x] > maxDisp * scale) {fi *= 1000; pU[x] = static_cast<float>(maxDisp * scale);}
- if (pU[x] < minDisp * scale) {fi *= 1000; pU[x] = static_cast<float>(minDisp * scale);}
- }
-
- int A = static_cast<int>(pU[x]);
- int neg = 0; if (pU[x] <= 0) neg = -1;
-
- if (x + A > width)
- pu[x] = pU[width - A];
- else if (x + A + neg < 0)
- pu[x] = pU[- A + 2];
- else {
- pu[x] = A + (pI2x[x + A + neg] * (pI1[x] - pI2[x + A])
- + fi * (gr * pU[x + 1] + gl * pU[x - 1] + gu * pUu[x] + gd * pUd[x] - gc * A))
- / (pI2x[x + A + neg] * pI2x[x + A + neg] + gc * fi) ;
- }
- }// x
- pu[0] = pu[1];
- pu[width] = pu[width - 1];
- }// y
- for (x = 0; x <= width; x++) {
- u.at<float>(0, x) = u.at<float>(1, x);
- u.at<float>(height, x) = u.at<float>(height - 1, x);
- }
- u.copyTo(U);
- if (!g_c.empty()) g_c.release();
- if (!g_p.empty()) g_p.release();
- }//n
+ register int n, x, y;
+ float gl = 1, gr = 1, gu = 1, gd = 1, gc = 4;
+ Mat g_c, g_p;
+ Mat U;
+ u.copyTo(U);
+
+ int N = nIt;
+ float l = lambda;
+ float Fi = fi;
+
+
+ if (flags & USE_SMART_ID) {
+ double scale = pow(pyrScale, (double) level) * (1 + pyrScale);
+ N = (int) (N / scale);
+ }
+
+ double scale = pow(pyrScale, (double) level);
+ Fi /= (float) scale;
+ l *= (float) scale;
+
+ int width = u.cols - 1;
+ int height = u.rows - 1;
+ for (n = 0; n < N; n++) {
+ if (penalization != PENALIZATION_TICHONOV) {
+ Mat gradient = getGradient(U);
+ switch (penalization) {
+ case PENALIZATION_CHARBONNIER: g_c = getG_c(gradient, l); break;
+ case PENALIZATION_PERONA_MALIK: g_p = getG_p(gradient, l); break;
+ }
+ gradient.release();
+ }
+ for (y = 1 ; y < height; y++) {
+ float *pU = U.ptr<float>(y);
+ float *pUu = U.ptr<float>(y + 1);
+ float *pUd = U.ptr<float>(y - 1);
+ float *pu = u.ptr<float>(y);
+ float *pI1 = I1.ptr<float>(y);
+ float *pI2 = I2.ptr<float>(y);
+ float *pI2x = I2x.ptr<float>(y);
+ float *pG_c = NULL, *pG_cu = NULL, *pG_cd = NULL;
+ float *pG_p = NULL, *pG_pu = NULL, *pG_pd = NULL;
+ switch (penalization) {
+ case PENALIZATION_CHARBONNIER:
+ pG_c = g_c.ptr<float>(y);
+ pG_cu = g_c.ptr<float>(y + 1);
+ pG_cd = g_c.ptr<float>(y - 1);
+ break;
+ case PENALIZATION_PERONA_MALIK:
+ pG_p = g_p.ptr<float>(y);
+ pG_pu = g_p.ptr<float>(y + 1);
+ pG_pd = g_p.ptr<float>(y - 1);
+ break;
+ }
+ for (x = 1; x < width; x++) {
+ switch (penalization) {
+ case PENALIZATION_CHARBONNIER:
+ gc = pG_c[x];
+ gl = gc + pG_c[x - 1];
+ gr = gc + pG_c[x + 1];
+ gu = gc + pG_cu[x];
+ gd = gc + pG_cd[x];
+ gc = gl + gr + gu + gd;
+ break;
+ case PENALIZATION_PERONA_MALIK:
+ gc = pG_p[x];
+ gl = gc + pG_p[x - 1];
+ gr = gc + pG_p[x + 1];
+ gu = gc + pG_pu[x];
+ gd = gc + pG_pd[x];
+ gc = gl + gr + gu + gd;
+ break;
+ }
+
+ float _fi = Fi;
+ if (maxDisp > minDisp) {
+ if (pU[x] > maxDisp * scale) {_fi *= 1000; pU[x] = static_cast<float>(maxDisp * scale);}
+ if (pU[x] < minDisp * scale) {_fi *= 1000; pU[x] = static_cast<float>(minDisp * scale);}
+ }
+
+ int A = static_cast<int>(pU[x]);
+ int neg = 0; if (pU[x] <= 0) neg = -1;
+
+ if (x + A > width)
+ pu[x] = pU[width - A];
+ else if (x + A + neg < 0)
+ pu[x] = pU[- A + 2];
+ else {
+ pu[x] = A + (pI2x[x + A + neg] * (pI1[x] - pI2[x + A])
+ + _fi * (gr * pU[x + 1] + gl * pU[x - 1] + gu * pUu[x] + gd * pUd[x] - gc * A))
+ / (pI2x[x + A + neg] * pI2x[x + A + neg] + gc * _fi) ;
+ }
+ }// x
+ pu[0] = pu[1];
+ pu[width] = pu[width - 1];
+ }// y
+ for (x = 0; x <= width; x++) {
+ u.at<float>(0, x) = u.at<float>(1, x);
+ u.at<float>(height, x) = u.at<float>(height - 1, x);
+ }
+ u.copyTo(U);
+ if (!g_c.empty()) g_c.release();
+ if (!g_p.empty()) g_p.release();
+ }//n
}
void StereoVar::VCycle_MyFAS(Mat &I1, Mat &I2, Mat &I2x, Mat &_u, int level)
{
- CvSize imgSize = _u.size();
- CvSize frmSize = cvSize((int) (imgSize.width * pyrScale + 0.5), (int) (imgSize.height * pyrScale + 0.5));
- Mat I1_h, I2_h, I2x_h, u_h, U, U_h;
+ CvSize imgSize = _u.size();
+ CvSize frmSize = cvSize((int) (imgSize.width * pyrScale + 0.5), (int) (imgSize.height * pyrScale + 0.5));
+ Mat I1_h, I2_h, I2x_h, u_h, U, U_h;
- //PRE relaxation
- VariationalSolver(I1, I2, I2x, _u, level);
+ //PRE relaxation
+ VariationalSolver(I1, I2, I2x, _u, level);
- if (level >= levels - 1) return;
- level ++;
+ if (level >= levels - 1) return;
+ level ++;
- //scaling DOWN
- resize(I1, I1_h, frmSize, 0, 0, INTER_AREA);
- resize(I2, I2_h, frmSize, 0, 0, INTER_AREA);
- resize(_u, u_h, frmSize, 0, 0, INTER_AREA);
- u_h.convertTo(u_h, u_h.type(), pyrScale);
- I2x_h = diffX(I2_h);
+ //scaling DOWN
+ resize(I1, I1_h, frmSize, 0, 0, INTER_AREA);
+ resize(I2, I2_h, frmSize, 0, 0, INTER_AREA);
+ resize(_u, u_h, frmSize, 0, 0, INTER_AREA);
+ u_h.convertTo(u_h, u_h.type(), pyrScale);
+ I2x_h = diffX(I2_h);
- //Next level
- U_h = u_h.clone();
- VCycle_MyFAS(I1_h, I2_h, I2x_h, U_h, level);
+ //Next level
+ U_h = u_h.clone();
+ VCycle_MyFAS(I1_h, I2_h, I2x_h, U_h, level);
- subtract(U_h, u_h, U_h);
- U_h.convertTo(U_h, U_h.type(), 1.0 / pyrScale);
+ subtract(U_h, u_h, U_h);
+ U_h.convertTo(U_h, U_h.type(), 1.0 / pyrScale);
- //scaling UP
- resize(U_h, U, imgSize);
+ //scaling UP
+ resize(U_h, U, imgSize);
- //correcting the solution
- add(_u, U, _u);
+ //correcting the solution
+ add(_u, U, _u);
- //POST relaxation
- VariationalSolver(I1, I2, I2x, _u, level - 1);
+ //POST relaxation
+ VariationalSolver(I1, I2, I2x, _u, level - 1);
- if (flags & USE_MEDIAN_FILTERING) medianBlur(_u, _u, 3);
+ if (flags & USE_MEDIAN_FILTERING) medianBlur(_u, _u, 3);
- I1_h.release();
- I2_h.release();
- I2x_h.release();
- u_h.release();
- U.release();
- U_h.release();
+ I1_h.release();
+ I2_h.release();
+ I2x_h.release();
+ u_h.release();
+ U.release();
+ U_h.release();
}
void StereoVar::FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level)
{
- double scale = pow(pyrScale, (double) level);
- CvSize frmSize = cvSize((int) (u.cols * scale + 0.5), (int) (u.rows * scale + 0.5));
- Mat I1_h, I2_h, I2x_h, u_h;
-
- //scaling DOWN
- resize(I1, I1_h, frmSize, 0, 0, INTER_AREA);
- resize(I2, I2_h, frmSize, 0, 0, INTER_AREA);
- resize(u, u_h, frmSize, 0, 0, INTER_AREA);
- u_h.convertTo(u_h, u_h.type(), scale);
- I2x_h = diffX(I2_h);
-
- switch (cycle) {
- case CYCLE_O:
- VariationalSolver(I1_h, I2_h, I2x_h, u_h, level);
- break;
- case CYCLE_V:
- VCycle_MyFAS(I1_h, I2_h, I2x_h, u_h, level);
- break;
- }
-
- u_h.convertTo(u_h, u_h.type(), 1.0 / scale);
-
- //scaling UP
- resize(u_h, u, u.size(), 0, 0, INTER_CUBIC);
-
- I1_h.release();
- I2_h.release();
- I2x_h.release();
- u_h.release();
-
- level--;
- if ((flags & USE_AUTO_PARAMS) && (level < levels / 3)) {
- penalization = PENALIZATION_PERONA_MALIK;
- fi *= 100;
- flags -= USE_AUTO_PARAMS;
- autoParams();
- }
- if (flags & USE_MEDIAN_FILTERING) medianBlur(u, u, 3);
- if (level >= 0) FMG(I1, I2, I2x, u, level);
+ double scale = pow(pyrScale, (double) level);
+ CvSize frmSize = cvSize((int) (u.cols * scale + 0.5), (int) (u.rows * scale + 0.5));
+ Mat I1_h, I2_h, I2x_h, u_h;
+
+ //scaling DOWN
+ resize(I1, I1_h, frmSize, 0, 0, INTER_AREA);
+ resize(I2, I2_h, frmSize, 0, 0, INTER_AREA);
+ resize(u, u_h, frmSize, 0, 0, INTER_AREA);
+ u_h.convertTo(u_h, u_h.type(), scale);
+ I2x_h = diffX(I2_h);
+
+ switch (cycle) {
+ case CYCLE_O:
+ VariationalSolver(I1_h, I2_h, I2x_h, u_h, level);
+ break;
+ case CYCLE_V:
+ VCycle_MyFAS(I1_h, I2_h, I2x_h, u_h, level);
+ break;
+ }
+
+ u_h.convertTo(u_h, u_h.type(), 1.0 / scale);
+
+ //scaling UP
+ resize(u_h, u, u.size(), 0, 0, INTER_CUBIC);
+
+ I1_h.release();
+ I2_h.release();
+ I2x_h.release();
+ u_h.release();
+
+ level--;
+ if ((flags & USE_AUTO_PARAMS) && (level < levels / 3)) {
+ penalization = PENALIZATION_PERONA_MALIK;
+ fi *= 100;
+ flags -= USE_AUTO_PARAMS;
+ autoParams();
+ }
+ if (flags & USE_MEDIAN_FILTERING) medianBlur(u, u, 3);
+ if (level >= 0) FMG(I1, I2, I2x, u, level);
}
void StereoVar::autoParams()
-{
- int maxD = MAX(labs(maxDisp), labs(minDisp));
-
- if (!maxD) pyrScale = 0.85;
- else if (maxD < 8) pyrScale = 0.5;
- else if (maxD < 64) pyrScale = 0.5 + static_cast<double>(maxD - 8) * 0.00625;
- else pyrScale = 0.85;
-
- if (maxD) {
- levels = 0;
- while ( pow(pyrScale, levels) * maxD > 1.5) levels ++;
- levels++;
- }
-
- switch(penalization) {
- case PENALIZATION_TICHONOV: cycle = CYCLE_V; break;
- case PENALIZATION_CHARBONNIER: cycle = CYCLE_O; break;
- case PENALIZATION_PERONA_MALIK: cycle = CYCLE_O; break;
- }
+{
+ int maxD = MAX(labs(maxDisp), labs(minDisp));
+
+ if (!maxD) pyrScale = 0.85;
+ else if (maxD < 8) pyrScale = 0.5;
+ else if (maxD < 64) pyrScale = 0.5 + static_cast<double>(maxD - 8) * 0.00625;
+ else pyrScale = 0.85;
+
+ if (maxD) {
+ levels = 0;
+ while ( pow(pyrScale, levels) * maxD > 1.5) levels ++;
+ levels++;
+ }
+
+ switch(penalization) {
+ case PENALIZATION_TICHONOV: cycle = CYCLE_V; break;
+ case PENALIZATION_CHARBONNIER: cycle = CYCLE_O; break;
+ case PENALIZATION_PERONA_MALIK: cycle = CYCLE_O; break;
+ }
}
void StereoVar::operator ()( const Mat& left, const Mat& right, Mat& disp )
{
- CV_Assert(left.size() == right.size() && left.type() == right.type());
- CvSize imgSize = left.size();
- int MaxD = MAX(labs(minDisp), labs(maxDisp));
- int SignD = 1; if (MIN(minDisp, maxDisp) < 0) SignD = -1;
- if (minDisp >= maxDisp) {MaxD = 256; SignD = 1;}
-
- Mat u;
- if ((flags & USE_INITIAL_DISPARITY) && (!disp.empty())) {
- CV_Assert(disp.size() == left.size() && disp.type() == CV_8UC1);
- disp.convertTo(u, CV_32FC1, static_cast<double>(SignD * MaxD) / 256);
- } else {
- u.create(imgSize, CV_32FC1);
- u.setTo(0);
- }
-
- // Preprocessing
- Mat leftgray, rightgray;
- if (left.type() != CV_8UC1) {
- cvtColor(left, leftgray, CV_BGR2GRAY);
- cvtColor(right, rightgray, CV_BGR2GRAY);
- } else {
- left.copyTo(leftgray);
- right.copyTo(rightgray);
- }
- if (flags & USE_EQUALIZE_HIST) {
- equalizeHist(leftgray, leftgray);
- equalizeHist(rightgray, rightgray);
- }
- if (poly_sigma > 0.0001) {
- GaussianBlur(leftgray, leftgray, cvSize(poly_n, poly_n), poly_sigma);
- GaussianBlur(rightgray, rightgray, cvSize(poly_n, poly_n), poly_sigma);
- }
-
- if (flags & USE_AUTO_PARAMS) {
- penalization = PENALIZATION_TICHONOV;
- autoParams();
- }
-
- Mat I1, I2;
- leftgray.convertTo(I1, CV_32FC1);
- rightgray.convertTo(I2, CV_32FC1);
- leftgray.release();
- rightgray.release();
-
- Mat I2x = diffX(I2);
-
- FMG(I1, I2, I2x, u, levels - 1);
-
- I1.release();
- I2.release();
- I2x.release();
-
-
- disp.create( left.size(), CV_8UC1 );
- u = abs(u);
- u.convertTo(disp, disp.type(), 256 / MaxD, 0);
-
- u.release();
+ CV_Assert(left.size() == right.size() && left.type() == right.type());
+ CvSize imgSize = left.size();
+ int MaxD = MAX(labs(minDisp), labs(maxDisp));
+ int SignD = 1; if (MIN(minDisp, maxDisp) < 0) SignD = -1;
+ if (minDisp >= maxDisp) {MaxD = 256; SignD = 1;}
+
+ Mat u;
+ if ((flags & USE_INITIAL_DISPARITY) && (!disp.empty())) {
+ CV_Assert(disp.size() == left.size() && disp.type() == CV_8UC1);
+ disp.convertTo(u, CV_32FC1, static_cast<double>(SignD * MaxD) / 256);
+ } else {
+ u.create(imgSize, CV_32FC1);
+ u.setTo(0);
+ }
+
+ // Preprocessing
+ Mat leftgray, rightgray;
+ if (left.type() != CV_8UC1) {
+ cvtColor(left, leftgray, CV_BGR2GRAY);
+ cvtColor(right, rightgray, CV_BGR2GRAY);
+ } else {
+ left.copyTo(leftgray);
+ right.copyTo(rightgray);
+ }
+ if (flags & USE_EQUALIZE_HIST) {
+ equalizeHist(leftgray, leftgray);
+ equalizeHist(rightgray, rightgray);
+ }
+ if (poly_sigma > 0.0001) {
+ GaussianBlur(leftgray, leftgray, cvSize(poly_n, poly_n), poly_sigma);
+ GaussianBlur(rightgray, rightgray, cvSize(poly_n, poly_n), poly_sigma);
+ }
+
+ if (flags & USE_AUTO_PARAMS) {
+ penalization = PENALIZATION_TICHONOV;
+ autoParams();
+ }
+
+ Mat I1, I2;
+ leftgray.convertTo(I1, CV_32FC1);
+ rightgray.convertTo(I2, CV_32FC1);
+ leftgray.release();
+ rightgray.release();
+
+ Mat I2x = diffX(I2);
+
+ FMG(I1, I2, I2x, u, levels - 1);
+
+ I1.release();
+ I2.release();
+ I2x.release();
+
+
+ disp.create( left.size(), CV_8UC1 );
+ u = abs(u);
+ u.convertTo(disp, disp.type(), 256 / MaxD, 0);
+
+ u.release();
}
} // namespace
\ No newline at end of file
if(HAVE_CUDA)
file(GLOB lib_cuda "src/cuda/*.cu")
source_group("Cuda" FILES "${lib_cuda}")
- include_directories(AFTER SYSTEM ${CUDA_INCLUDE_DIRS})
- ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/src" "${OpenCV_SOURCE_DIR}/modules/gpu/src/cuda")
+ ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/src" "${OpenCV_SOURCE_DIR}/modules/gpu/src/cuda" ${CUDA_INCLUDE_DIRS})
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
+ ocv_cuda_compile(cuda_objs ${lib_cuda})
- OCV_CUDA_COMPILE(cuda_objs ${lib_cuda})
-
set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
else()
set(lib_cuda "")
return m;\r
}\r
\r
- inline void GpuMat::assignTo(GpuMat& m, int type) const\r
+ inline void GpuMat::assignTo(GpuMat& m, int _type) const\r
{\r
- if (type < 0)\r
+ if (_type < 0)\r
m = *this;\r
else\r
- convertTo(m, type);\r
+ convertTo(m, _type);\r
}\r
\r
inline size_t GpuMat::step1() const\r
create(size_.height, size_.width, type_);\r
}\r
\r
- inline GpuMat GpuMat::operator()(Range rowRange, Range colRange) const\r
+ inline GpuMat GpuMat::operator()(Range _rowRange, Range _colRange) const\r
{\r
- return GpuMat(*this, rowRange, colRange);\r
+ return GpuMat(*this, _rowRange, _colRange);\r
}\r
\r
inline GpuMat GpuMat::operator()(Rect roi) const\r
refcount = 0;
allocator = 0;
}
-
+
inline Mat::Mat() : size(&rows)
{
initEmpty();
initEmpty();
create( _sz.height, _sz.width, _type );
}
-
+
inline Mat::Mat(Size _sz, int _type, const Scalar& _s) : size(&rows)
{
initEmpty();
create(_sz.height, _sz.width, _type);
*this = _s;
}
-
+
inline Mat::Mat(int _dims, const int* _sz, int _type) : size(&rows)
{
initEmpty();
initEmpty();
create(_dims, _sz, _type);
*this = _s;
-}
+}
inline Mat::Mat(const Mat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
else
Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
}
-
-
+
+
template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
dims(2), rows(n), cols(1), data(0), refcount(0),
datalimit = dataend = datastart + rows*step[0];
}
else
- Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
+ Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
}
-
+
template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
dims(2), rows(2), cols(1), data(0), refcount(0),
((_Tp*)data)[1] = pt.y;
}
}
-
+
template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
}
}
-
+
template<typename _Tp> inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
dims(0), rows(0), cols(0), data(0), refcount(0),
{
*this = *commaInitializer;
}
-
+
inline Mat::~Mat()
{
release();
}
return *this;
}
-
+
inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
inline Mat Mat::rowRange(int startrow, int endrow) const
return m;
}
-inline void Mat::assignTo( Mat& m, int type ) const
+inline void Mat::assignTo( Mat& m, int _type ) const
{
- if( type < 0 )
+ if( _type < 0 )
m = *this;
else
- convertTo(m, type);
+ convertTo(m, _type);
}
inline void Mat::create(int _rows, int _cols, int _type)
refcount = 0;
}
-inline Mat Mat::operator()( Range rowRange, Range colRange ) const
+inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const
{
- return Mat(*this, rowRange, colRange);
+ return Mat(*this, _rowRange, _colRange);
}
-
+
inline Mat Mat::operator()( const Rect& roi ) const
{ return Mat(*this, roi); }
inline Mat Mat::operator()(const Range* ranges) const
{
return Mat(*this, ranges);
-}
-
+}
+
inline Mat::operator CvMat() const
{
CV_DbgAssert(dims <= 2);
return (const _Tp*)(data + step.p[0]*y);
}
-
+
inline uchar* Mat::ptr(int i0, int i1)
{
CV_DbgAssert( dims >= 2 && data &&
}
inline uchar* Mat::ptr(const int* idx)
-{
+{
int i, d = dims;
uchar* p = data;
CV_DbgAssert( d >= 1 && p );
p += idx[i]*step.p[i];
}
return p;
-}
-
+}
+
template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
{
CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
return ((const _Tp*)(data + step.p[0]*i0))[i1];
}
-
+
template<typename _Tp> inline _Tp& Mat::at(Point pt)
{
CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
int i = i0/cols, j = i0 - i*cols;
return ((_Tp*)(data + step.p[0]*i))[j];
}
-
+
template<typename _Tp> inline const _Tp& Mat::at(int i0) const
{
CV_DbgAssert( dims <= 2 && data &&
int i = i0/cols, j = i0 - i*cols;
return ((const _Tp*)(data + step.p[0]*i))[j];
}
-
+
template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
{
CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
return *(const _Tp*)ptr(idx.val);
}
-
-
+
+
template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
{
CV_DbgAssert( elemSize() == sizeof(_Tp) );
{
CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
rows + cols - 1 == n && channels() == 1 );
-
+
if( isContinuous() && type() == DataType<_Tp>::type )
return Vec<_Tp, n>((_Tp*)data);
Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
convertTo(tmp, tmp.type());
return v;
}
-
+
template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
{
CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
-
+
if( isContinuous() && type() == DataType<_Tp>::type )
return Matx<_Tp, m, n>((_Tp*)data);
Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
template<typename _Tp> inline void Mat::push_back(const _Tp& elem)
{
if( !data )
- {
- *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
- return;
- }
- CV_Assert(DataType<_Tp>::type == type() && cols == 1
+ {
+ *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
+ return;
+ }
+ CV_Assert(DataType<_Tp>::type == type() && cols == 1
/* && dims == 2 (cols == 1 implies dims == 2) */);
uchar* tmp = dataend + step[0];
if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
else
push_back_(&elem);
}
-
+
template<typename _Tp> inline void Mat::push_back(const Mat_<_Tp>& m)
{
push_back((const Mat&)m);
-}
-
+}
+
inline Mat::MSize::MSize(int* _p) : p(_p) {}
inline Size Mat::MSize::operator()() const
{
- CV_DbgAssert(p[-1] <= 2);
+ CV_DbgAssert(p[-1] <= 2);
return Size(p[1], p[0]);
}
inline const int& Mat::MSize::operator[](int i) const { return p[i]; }
return false;
if( d == 2 )
return p[0] == sz.p[0] && p[1] == sz.p[1];
-
+
for( int i = 0; i < d; i++ )
if( p[i] != sz.p[i] )
return false;
return true;
-}
+}
inline bool Mat::MSize::operator != (const MSize& sz) const
{
return !(*this == sz);
}
-
+
inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; }
inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
inline const size_t& Mat::MStep::operator[](int i) const { return p[i]; }
buf[0] = s;
return *this;
}
-
+
static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
{
return cvarrToMat(arr, copyData, true, coiMode);
SVD::compute(_a, _w, _u, _vt);
CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
}
-
+
template<typename _Tp, int m, int n, int nm> inline void
SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
{
SVD::compute(_a, _w);
CV_Assert(_w.data == (uchar*)&w.val[0]);
}
-
+
template<typename _Tp, int m, int n, int nm, int nb> inline void
SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
SVD::backSubst(_w, _u, _vt, _rhs, _dst);
CV_Assert(_dst.data == (uchar*)&dst.val[0]);
}
-
+
///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
template<typename _Tp> inline Mat_<_Tp>::Mat_()
: Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols)
: Mat(_rows, _cols, DataType<_Tp>::type) {}
template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
: Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
: Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
: Mat(_dims, _sz, DataType<_Tp>::type) {}
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
: Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {}
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
: Mat(m, ranges) {}
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m)
: Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
: Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRange, const Range& colRange)
- : Mat(m, rowRange, colRange) {}
+template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
+ : Mat(m, _rowRange, _colRange) {}
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
: Mat(m, roi) {}
if( copyData )
*this = clone();
}
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
: Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
{
template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
: Mat(commaInitializer) {}
-
+
template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
: Mat(vec, copyData) {}
template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
{
Mat::create(_dims, _sz, DataType<_Tp>::type);
-}
-
-
+}
+
+
template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
{ return Mat_<_Tp>(Mat::cross(m)); }
template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
{ return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright)); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& rowRange, const Range& colRange ) const
-{ return Mat_<_Tp>(*this, rowRange, colRange); }
+template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
+{ return Mat_<_Tp>(*this, _rowRange, _colRange); }
template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
{ return Mat_<_Tp>(*this, roi); }
template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
-{ return Mat_<_Tp>(*this, ranges); }
-
+{ return Mat_<_Tp>(*this, ranges); }
+
template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
{ return (_Tp*)ptr(y); }
template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
template<typename _Tp> template<int n> inline const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
{
return Mat::at<_Tp>(idx);
-}
-
+}
+
template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
{
return this->at<_Tp>(i0);
template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
{
return this->at<_Tp>(i0);
-}
+}
template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
{
template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
{
return this->at<_Tp>(i0, i1, i2);
-}
-
-
+}
+
+
template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
{
vector<_Tp> v;
{
CV_Assert(n % DataType<_Tp>::channels == 0);
return this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
-}
+}
template<typename T1, typename T2, typename Op> inline void
process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
}
}
-
+
/////////////////////////////// Input/Output Arrays /////////////////////////////////
-
+
template<typename _Tp> inline _InputArray::_InputArray(const vector<_Tp>& vec)
: flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
: flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
template<typename _Tp> inline _InputArray::_InputArray(const vector<Mat_<_Tp> >& vec)
- : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {}
-
+ : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {}
+
template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
: flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
-
+
template<typename _Tp> inline _InputArray::_InputArray(const _Tp* vec, int n)
: flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {}
template<typename _Tp> inline _InputArray::_InputArray(const Mat_<_Tp>& m)
: flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {}
-
+
template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec)
: _InputArray(vec) {}
template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec)
: _InputArray(vec) {flags |= FIXED_SIZE;}
template<typename _Tp> inline _OutputArray::_OutputArray(const vector<Mat_<_Tp> >& vec)
: _InputArray(vec) {flags |= FIXED_SIZE;}
-
+
template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m)
: _InputArray(m) {flags |= FIXED_SIZE;}
template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
: _InputArray(mtx) {}
template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n)
: _InputArray(vec, n) {}
-
+
//////////////////////////////////// Matrix Expressions /////////////////////////////////////////
class CV_EXPORTS MatOp
-{
+{
public:
MatOp() {};
virtual ~MatOp() {};
-
+
virtual bool elementWise(const MatExpr& expr) const;
virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0;
virtual void roi(const MatExpr& expr, const Range& rowRange,
virtual void augAssignAnd(const MatExpr& expr, Mat& m) const;
virtual void augAssignOr(const MatExpr& expr, Mat& m) const;
virtual void augAssignXor(const MatExpr& expr, Mat& m) const;
-
+
virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const;
-
+
virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
-
+
virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const;
-
+
virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
virtual void divide(double s, const MatExpr& expr, MatExpr& res) const;
-
+
virtual void abs(const MatExpr& expr, MatExpr& res) const;
-
+
virtual void transpose(const MatExpr& expr, MatExpr& res) const;
virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
virtual void invert(const MatExpr& expr, int method, MatExpr& res) const;
-
+
virtual Size size(const MatExpr& expr) const;
virtual int type(const MatExpr& expr) const;
};
-
+
class CV_EXPORTS MatExpr
{
public:
op->assign(*this, m);
return m;
}
-
+
template<typename _Tp> operator Mat_<_Tp>() const
{
Mat_<_Tp> m;
op->assign(*this, m, DataType<_Tp>::type);
return m;
}
-
+
MatExpr row(int y) const;
MatExpr col(int x) const;
MatExpr diag(int d=0) const;
MatExpr operator()( const Range& rowRange, const Range& colRange ) const;
MatExpr operator()( const Rect& roi ) const;
-
+
Mat cross(const Mat& m) const;
double dot(const Mat& m) const;
-
+
MatExpr t() const;
MatExpr inv(int method = DECOMP_LU) const;
MatExpr mul(const MatExpr& e, double scale=1) const;
MatExpr mul(const Mat& m, double scale=1) const;
-
+
Size size() const;
int type() const;
-
+
const MatOp* op;
int flags;
-
+
Mat a, b, c;
double alpha, beta;
Scalar s;
};
-
+
CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator * (const MatExpr& e, double s);
CV_EXPORTS MatExpr operator * (double s, const MatExpr& e);
CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2);
-
+
CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator / (const Mat& a, double s);
CV_EXPORTS MatExpr operator / (double s, const Mat& a);
CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e);
CV_EXPORTS MatExpr operator / (const MatExpr& e, double s);
CV_EXPORTS MatExpr operator / (double s, const MatExpr& e);
-CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
+CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator < (const Mat& a, double s);
CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator > (const Mat& a, double s);
-CV_EXPORTS MatExpr operator > (double s, const Mat& a);
-
+CV_EXPORTS MatExpr operator > (double s, const Mat& a);
+
CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
CV_EXPORTS MatExpr min(const Mat& a, double s);
CV_EXPORTS MatExpr min(double s, const Mat& a);
template<typename _Tp> static inline MatExpr min(double s, const Mat_<_Tp>& a)
{
return cv::min((const Mat&)a, s);
-}
+}
template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
template<typename _Tp> static inline MatExpr max(double s, const Mat_<_Tp>& a)
{
return cv::max((const Mat&)a, s);
-}
+}
template<typename _Tp> static inline void min(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c)
{
cv::max((const Mat&)a, s, (Mat&)c);
}
-
+
CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator ~(const Mat& m);
-
+
CV_EXPORTS MatExpr abs(const Mat& m);
CV_EXPORTS MatExpr abs(const MatExpr& e);
-
+
template<typename _Tp> static inline MatExpr abs(const Mat_<_Tp>& m)
{
return cv::abs((const Mat&)m);
}
////////////////////////////// Augmenting algebraic operations //////////////////////////////////
-
+
inline Mat& Mat::operator = (const MatExpr& e)
{
e.op->assign(e, *this);
return *this;
-}
+}
template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatExpr& e)
{
{
add(a, s, (Mat&)a);
return (Mat&)a;
-}
+}
template<typename _Tp> static inline
Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
add(a, s, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
+}
static inline Mat& operator += (const Mat& a, const MatExpr& b)
{
- b.op->augAssignAdd(b, (Mat&)a);
+ b.op->augAssignAdd(b, (Mat&)a);
return (Mat&)a;
}
b.op->augAssignAdd(b, (Mat&)a);
return (Mat_<_Tp>&)a;
}
-
+
static inline Mat& operator -= (const Mat& a, const Mat& b)
{
subtract(a, b, (Mat&)a);
{
subtract(a, s, (Mat&)a);
return (Mat&)a;
-}
+}
template<typename _Tp> static inline
Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
subtract(a, s, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
+}
static inline Mat& operator -= (const Mat& a, const MatExpr& b)
{
- b.op->augAssignSubtract(b, (Mat&)a);
+ b.op->augAssignSubtract(b, (Mat&)a);
return (Mat&)a;
}
{
b.op->augAssignSubtract(b, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
+}
static inline Mat& operator *= (const Mat& a, const Mat& b)
{
{
a.convertTo((Mat&)a, -1, s);
return (Mat&)a;
-}
+}
template<typename _Tp> static inline
Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
a.convertTo((Mat&)a, -1, s);
return (Mat_<_Tp>&)a;
-}
+}
static inline Mat& operator *= (const Mat& a, const MatExpr& b)
{
- b.op->augAssignMultiply(b, (Mat&)a);
+ b.op->augAssignMultiply(b, (Mat&)a);
return (Mat&)a;
}
{
b.op->augAssignMultiply(b, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
-
+}
+
static inline Mat& operator /= (const Mat& a, const Mat& b)
{
divide(a, b, (Mat&)a);
{
a.convertTo((Mat&)a, -1, 1./s);
return (Mat&)a;
-}
+}
template<typename _Tp> static inline
Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
a.convertTo((Mat&)a, -1, 1./s);
return (Mat_<_Tp>&)a;
-}
+}
static inline Mat& operator /= (const Mat& a, const MatExpr& b)
{
- b.op->augAssignDivide(b, (Mat&)a);
+ b.op->augAssignDivide(b, (Mat&)a);
return (Mat&)a;
}
{
bitwise_and(a, s, (Mat&)a);
return (Mat&)a;
-}
+}
template<typename _Tp> static inline Mat_<_Tp>&
operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
bitwise_and(a, b, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
+}
template<typename _Tp> static inline Mat_<_Tp>&
operator &= (const Mat_<_Tp>& a, const Scalar& s)
{
bitwise_and(a, s, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
-
+}
+
static inline Mat& operator |= (const Mat& a, const Mat& b)
{
bitwise_or(a, b, (Mat&)a);
{
bitwise_or(a, s, (Mat&)a);
return (Mat&)a;
-}
+}
template<typename _Tp> static inline Mat_<_Tp>&
operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
bitwise_or(a, b, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
+}
template<typename _Tp> static inline Mat_<_Tp>&
operator |= (const Mat_<_Tp>& a, const Scalar& s)
{
bitwise_or(a, s, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
-
+}
+
static inline Mat& operator ^= (const Mat& a, const Mat& b)
{
bitwise_xor(a, b, (Mat&)a);
{
bitwise_xor(a, s, (Mat&)a);
return (Mat&)a;
-}
+}
template<typename _Tp> static inline Mat_<_Tp>&
operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
{
bitwise_xor(a, b, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
+}
template<typename _Tp> static inline Mat_<_Tp>&
operator ^= (const Mat_<_Tp>& a, const Scalar& s)
{
bitwise_xor(a, s, (Mat&)a);
return (Mat_<_Tp>&)a;
-}
+}
/////////////////////////////// Miscellaneous operations //////////////////////////////
-
+
template<typename _Tp> void split(const Mat& src, vector<Mat_<_Tp> >& mv)
{ split(src, (vector<Mat>&)mv ); }
//////////////////////////////////////////////////////////////
-
+
template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(int rows, int cols)
{
return Mat::zeros(rows, cols, DataType<_Tp>::type);
}
-
+
template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(Size sz)
{
return Mat::zeros(sz, DataType<_Tp>::type);
-}
-
+}
+
template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(int rows, int cols)
{
return Mat::ones(rows, cols, DataType<_Tp>::type);
template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(Size sz)
{
return Mat::ones(sz, DataType<_Tp>::type);
-}
-
+}
+
template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(int rows, int cols)
{
return Mat::eye(rows, cols, DataType<_Tp>::type);
template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(Size sz)
{
return Mat::eye(sz, DataType<_Tp>::type);
-}
-
+}
+
//////////////////////////////// Iterators & Comma initializers //////////////////////////////////
inline MatConstIterator::MatConstIterator()
int idx[]={_pt.y, _pt.x};
seek(idx);
}
-
+
inline MatConstIterator::MatConstIterator(const MatConstIterator& it)
: m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
{}
}
inline uchar* MatConstIterator::operator *() const { return ptr; }
-
+
inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
{
if( !m || ofs == 0 )
if( m && (ptr -= elemSize) < sliceStart )
{
ptr += elemSize;
- seek(-1, true);
+ seek(-1, true);
}
return *this;
}
if( m && (ptr += elemSize) >= sliceEnd )
{
ptr -= elemSize;
- seek(1, true);
+ seek(1, true);
}
return *this;
}
template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
: MatConstIterator_<_Tp>(_m, _pt) {}
-
+
template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
: MatConstIterator_<_Tp>(_m, _idx) {}
-
+
template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
: MatConstIterator_<_Tp>(it) {}
template<typename _Tp> static inline bool
operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
-{ return a.m != b.m || a.ptr != b.ptr; }
-
+{ return a.m != b.m || a.ptr != b.ptr; }
+
static inline bool
operator < (const MatConstIterator& a, const MatConstIterator& b)
{ return a.ptr < b.ptr; }
static inline bool
operator > (const MatConstIterator& a, const MatConstIterator& b)
{ return a.ptr > b.ptr; }
-
+
static inline bool
operator <= (const MatConstIterator& a, const MatConstIterator& b)
{ return a.ptr <= b.ptr; }
static inline MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
{ MatConstIterator b = a; return b += -ofs; }
-
+
template<typename _Tp> static inline MatConstIterator_<_Tp>
operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
template<typename _Tp> static inline MatConstIterator_<_Tp>
operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
-
+
template<typename _Tp> static inline MatConstIterator_<_Tp>
operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
{ MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatConstIterator_<_Tp>&)t; }
inline uchar* MatConstIterator::operator [](ptrdiff_t i) const
{ return *(*this + i); }
-
+
template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
{ return *(_Tp*)MatConstIterator::operator [](i); }
template<typename _Tp> static inline MatIterator_<_Tp>
operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
{ MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatIterator_<_Tp>&)t; }
-
+
template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
{ return *(*this + i); }
{
CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
return Mat_<_Tp>(*this->it.m);
-}
-
+}
+
template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
operator << (const Mat_<_Tp>& m, T2 val)
{
}
-inline void SparseMat::assignTo( SparseMat& m, int type ) const
+inline void SparseMat::assignTo( SparseMat& m, int _type ) const
{
- if( type < 0 )
+ if( _type < 0 )
m = *this;
else
- convertTo(m, type);
+ convertTo(m, _type);
}
inline void SparseMat::addref()
template<typename _Tp> inline _Tp& SparseMat::ref(int i0, size_t* hashval)
{ return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
-
+
template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
{ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
{
const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
return p ? *p : _Tp();
-}
-
+}
+
template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
{
const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
template<typename _Tp> inline const _Tp* SparseMat::find(int i0, size_t* hashval) const
{ return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); }
-
+
template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
{ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); }
inline SparseMatIterator SparseMat::end()
{ SparseMatIterator it(this); it.seekEnd(); return it; }
-
+
inline SparseMatConstIterator SparseMat::end() const
{ SparseMatConstIterator it(this); it.seekEnd(); return it; }
-
+
template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::begin()
{ return SparseMatIterator_<_Tp>(this); }
-
+
template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::begin() const
{ return SparseMatConstIterator_<_Tp>(this); }
-
+
template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::end()
{ SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::end() const
{ SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
-
-
+
+
inline SparseMatConstIterator::SparseMatConstIterator()
: m(0), hashidx(0), ptr(0)
{
return it;
}
-
+
inline void SparseMatConstIterator::seekEnd()
{
if( m && m->hdr )
ptr = 0;
}
}
-
+
inline SparseMatIterator::SparseMatIterator()
{}
template<typename _Tp> inline _Tp
SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
-{ return SparseMat::value<_Tp>(i0, hashval); }
-
+{ return SparseMat::value<_Tp>(i0, hashval); }
+
template<typename _Tp> inline _Tp&
SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
{ return SparseMat::ref<_Tp>(i0, i1, hashval); }
template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
{ SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
-
+
template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
{ SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
SparseMatConstIterator::operator ++();
return it;
}
-
+
}
#endif
\r
#include "opencv2/core/core.hpp"\r
\r
-namespace cv \r
+namespace cv\r
{\r
- //! Smart pointer for OpenGL buffer memory with reference counting.\r
- class CV_EXPORTS GlBuffer\r
+//! Smart pointer for OpenGL buffer memory with reference counting.\r
+class CV_EXPORTS GlBuffer\r
+{\r
+public:\r
+ enum Usage\r
{\r
- public:\r
- enum Usage\r
- {\r
- ARRAY_BUFFER = 0x8892, // buffer will use for OpenGL arrays (vertices, colors, normals, etc)\r
- TEXTURE_BUFFER = 0x88EC // buffer will ise for OpenGL textures\r
- };\r
-\r
- //! create empty buffer\r
- explicit GlBuffer(Usage usage);\r
-\r
- //! create buffer\r
- GlBuffer(int rows, int cols, int type, Usage usage);\r
- GlBuffer(Size size, int type, Usage usage);\r
-\r
- //! copy from host/device memory\r
- GlBuffer(InputArray mat, Usage usage);\r
-\r
- void create(int rows, int cols, int type, Usage usage);\r
- inline void create(Size size, int type, Usage usage) { create(size.height, size.width, type, usage); }\r
- inline void create(int rows, int cols, int type) { create(rows, cols, type, usage()); }\r
- inline void create(Size size, int type) { create(size.height, size.width, type, usage()); }\r
-\r
- void release();\r
-\r
- //! copy from host/device memory\r
- void copyFrom(InputArray mat);\r
-\r
- void bind() const;\r
- void unbind() const;\r
-\r
- //! map to host memory\r
- Mat mapHost();\r
- void unmapHost();\r
-\r
- //! map to device memory\r
- gpu::GpuMat mapDevice();\r
- void unmapDevice();\r
- \r
- inline int rows() const { return rows_; }\r
- inline int cols() const { return cols_; }\r
- inline Size size() const { return Size(cols_, rows_); }\r
- inline bool empty() const { return rows_ == 0 || cols_ == 0; }\r
-\r
- inline int type() const { return type_; }\r
- inline int depth() const { return CV_MAT_DEPTH(type_); }\r
- inline int channels() const { return CV_MAT_CN(type_); }\r
- inline int elemSize() const { return CV_ELEM_SIZE(type_); }\r
- inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }\r
-\r
- inline Usage usage() const { return usage_; }\r
-\r
- class Impl;\r
- private:\r
- int rows_;\r
- int cols_;\r
- int type_;\r
- Usage usage_;\r
-\r
- Ptr<Impl> impl_;\r
+ ARRAY_BUFFER = 0x8892, // buffer will use for OpenGL arrays (vertices, colors, normals, etc)\r
+ TEXTURE_BUFFER = 0x88EC // buffer will ise for OpenGL textures\r
};\r
\r
- template <> CV_EXPORTS void Ptr<GlBuffer::Impl>::delete_obj();\r
+ //! create empty buffer\r
+ explicit GlBuffer(Usage usage);\r
+\r
+ //! create buffer\r
+ GlBuffer(int rows, int cols, int type, Usage usage);\r
+ GlBuffer(Size size, int type, Usage usage);\r
+\r
+ //! copy from host/device memory\r
+ GlBuffer(InputArray mat, Usage usage);\r
+\r
+ void create(int rows, int cols, int type, Usage usage);\r
+ void create(Size size, int type, Usage usage);\r
+ void create(int rows, int cols, int type);\r
+ void create(Size size, int type);\r
+\r
+ void release();\r
+\r
+ //! copy from host/device memory\r
+ void copyFrom(InputArray mat);\r
+\r
+ void bind() const;\r
+ void unbind() const;\r
+\r
+ //! map to host memory\r
+ Mat mapHost();\r
+ void unmapHost();\r
+\r
+ //! map to device memory\r
+ gpu::GpuMat mapDevice();\r
+ void unmapDevice();\r
+\r
+ inline int rows() const { return rows_; }\r
+ inline int cols() const { return cols_; }\r
+ inline Size size() const { return Size(cols_, rows_); }\r
+ inline bool empty() const { return rows_ == 0 || cols_ == 0; }\r
+\r
+ inline int type() const { return type_; }\r
+ inline int depth() const { return CV_MAT_DEPTH(type_); }\r
+ inline int channels() const { return CV_MAT_CN(type_); }\r
+ inline int elemSize() const { return CV_ELEM_SIZE(type_); }\r
+ inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }\r
+\r
+ inline Usage usage() const { return usage_; }\r
+\r
+ class Impl;\r
+private:\r
+ int rows_;\r
+ int cols_;\r
+ int type_;\r
+ Usage usage_;\r
+\r
+ Ptr<Impl> impl_;\r
+};\r
+\r
+template <> CV_EXPORTS void Ptr<GlBuffer::Impl>::delete_obj();\r
+\r
+//! Smart pointer for OpenGL 2d texture memory with reference counting.\r
+class CV_EXPORTS GlTexture\r
+{\r
+public:\r
+ //! create empty texture\r
+ GlTexture();\r
+\r
+ //! create texture\r
+ GlTexture(int rows, int cols, int type);\r
+ GlTexture(Size size, int type);\r
+\r
+ //! copy from host/device memory\r
+ explicit GlTexture(InputArray mat, bool bgra = true);\r
+\r
+ void create(int rows, int cols, int type);\r
+ void create(Size size, int type);\r
+ void release();\r
+\r
+ //! copy from host/device memory\r
+ void copyFrom(InputArray mat, bool bgra = true);\r
+\r
+ void bind() const;\r
+ void unbind() const;\r
+\r
+ inline int rows() const { return rows_; }\r
+ inline int cols() const { return cols_; }\r
+ inline Size size() const { return Size(cols_, rows_); }\r
+ inline bool empty() const { return rows_ == 0 || cols_ == 0; }\r
\r
- //! Smart pointer for OpenGL 2d texture memory with reference counting.\r
- class CV_EXPORTS GlTexture\r
+ inline int type() const { return type_; }\r
+ inline int depth() const { return CV_MAT_DEPTH(type_); }\r
+ inline int channels() const { return CV_MAT_CN(type_); }\r
+ inline int elemSize() const { return CV_ELEM_SIZE(type_); }\r
+ inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }\r
+\r
+ class Impl;\r
+private:\r
+ int rows_;\r
+ int cols_;\r
+ int type_;\r
+\r
+ Ptr<Impl> impl_;\r
+ GlBuffer buf_;\r
+};\r
+\r
+template <> CV_EXPORTS void Ptr<GlTexture::Impl>::delete_obj();\r
+\r
+//! OpenGL Arrays\r
+class CV_EXPORTS GlArrays\r
+{\r
+public:\r
+ inline GlArrays()\r
+ : vertex_(GlBuffer::ARRAY_BUFFER), color_(GlBuffer::ARRAY_BUFFER), bgra_(true), normal_(GlBuffer::ARRAY_BUFFER), texCoord_(GlBuffer::ARRAY_BUFFER)\r
{\r
- public:\r
- //! create empty texture\r
- GlTexture();\r
-\r
- //! create texture\r
- GlTexture(int rows, int cols, int type);\r
- GlTexture(Size size, int type);\r
-\r
- //! copy from host/device memory\r
- explicit GlTexture(InputArray mat, bool bgra = true);\r
-\r
- void create(int rows, int cols, int type);\r
- inline void create(Size size, int type) { create(size.height, size.width, type); }\r
- void release();\r
-\r
- //! copy from host/device memory\r
- void copyFrom(InputArray mat, bool bgra = true);\r
-\r
- void bind() const;\r
- void unbind() const;\r
-\r
- inline int rows() const { return rows_; }\r
- inline int cols() const { return cols_; }\r
- inline Size size() const { return Size(cols_, rows_); }\r
- inline bool empty() const { return rows_ == 0 || cols_ == 0; }\r
-\r
- inline int type() const { return type_; }\r
- inline int depth() const { return CV_MAT_DEPTH(type_); }\r
- inline int channels() const { return CV_MAT_CN(type_); }\r
- inline int elemSize() const { return CV_ELEM_SIZE(type_); }\r
- inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }\r
-\r
- class Impl;\r
- private:\r
- int rows_;\r
- int cols_;\r
- int type_;\r
-\r
- Ptr<Impl> impl_;\r
- GlBuffer buf_;\r
- };\r
+ }\r
+\r
+ void setVertexArray(InputArray vertex);\r
+ inline void resetVertexArray() { vertex_.release(); }\r
+\r
+ void setColorArray(InputArray color, bool bgra = true);\r
+ inline void resetColorArray() { color_.release(); }\r
+\r
+ void setNormalArray(InputArray normal);\r
+ inline void resetNormalArray() { normal_.release(); }\r
+\r
+ void setTexCoordArray(InputArray texCoord);\r
+ inline void resetTexCoordArray() { texCoord_.release(); }\r
+\r
+ void bind() const;\r
+ void unbind() const;\r
\r
- template <> CV_EXPORTS void Ptr<GlTexture::Impl>::delete_obj();\r
+ inline int rows() const { return vertex_.rows(); }\r
+ inline int cols() const { return vertex_.cols(); }\r
+ inline Size size() const { return vertex_.size(); }\r
+ inline bool empty() const { return vertex_.empty(); }\r
\r
- //! OpenGL Arrays\r
- class CV_EXPORTS GlArrays\r
+private:\r
+ GlBuffer vertex_;\r
+ GlBuffer color_;\r
+ bool bgra_;\r
+ GlBuffer normal_;\r
+ GlBuffer texCoord_;\r
+};\r
+\r
+//! OpenGL Font\r
+class CV_EXPORTS GlFont\r
+{\r
+public:\r
+ enum Weight\r
{\r
- public:\r
- inline GlArrays() \r
- : vertex_(GlBuffer::ARRAY_BUFFER), color_(GlBuffer::ARRAY_BUFFER), bgra_(true), normal_(GlBuffer::ARRAY_BUFFER), texCoord_(GlBuffer::ARRAY_BUFFER)\r
- {\r
- }\r
-\r
- void setVertexArray(InputArray vertex);\r
- inline void resetVertexArray() { vertex_.release(); }\r
-\r
- void setColorArray(InputArray color, bool bgra = true);\r
- inline void resetColorArray() { color_.release(); }\r
- \r
- void setNormalArray(InputArray normal);\r
- inline void resetNormalArray() { normal_.release(); }\r
- \r
- void setTexCoordArray(InputArray texCoord);\r
- inline void resetTexCoordArray() { texCoord_.release(); }\r
-\r
- void bind() const;\r
- void unbind() const;\r
-\r
- inline int rows() const { return vertex_.rows(); }\r
- inline int cols() const { return vertex_.cols(); }\r
- inline Size size() const { return vertex_.size(); }\r
- inline bool empty() const { return vertex_.empty(); }\r
-\r
- private:\r
- GlBuffer vertex_;\r
- GlBuffer color_;\r
- bool bgra_;\r
- GlBuffer normal_;\r
- GlBuffer texCoord_;\r
+ WEIGHT_LIGHT = 300,\r
+ WEIGHT_NORMAL = 400,\r
+ WEIGHT_SEMIBOLD = 600,\r
+ WEIGHT_BOLD = 700,\r
+ WEIGHT_BLACK = 900\r
};\r
\r
- //! OpenGL Font\r
- class CV_EXPORTS GlFont\r
+ enum Style\r
{\r
- public:\r
- enum Weight \r
- {\r
- WEIGHT_LIGHT = 300,\r
- WEIGHT_NORMAL = 400,\r
- WEIGHT_SEMIBOLD = 600,\r
- WEIGHT_BOLD = 700,\r
- WEIGHT_BLACK = 900\r
- };\r
-\r
- enum Style \r
- { \r
- STYLE_NORMAL = 0,\r
- STYLE_ITALIC = 1,\r
- STYLE_UNDERLINE = 2\r
- };\r
-\r
- static Ptr<GlFont> get(const std::string& family, int height = 12, Weight weight = WEIGHT_NORMAL, Style style = STYLE_NORMAL);\r
-\r
- void draw(const char* str, size_t len) const;\r
-\r
- inline const std::string& family() const { return family_; }\r
- inline int height() const { return height_; }\r
- inline Weight weight() const { return weight_; }\r
- inline Style style() const { return style_; }\r
-\r
- private:\r
- GlFont(const std::string& family, int height, Weight weight, Style style);\r
-\r
- std::string family_;\r
- int height_;\r
- Weight weight_;\r
- Style style_;\r
-\r
- unsigned int base_;\r
-\r
- GlFont(const GlFont&);\r
- GlFont& operator =(const GlFont&);\r
+ STYLE_NORMAL = 0,\r
+ STYLE_ITALIC = 1,\r
+ STYLE_UNDERLINE = 2\r
};\r
\r
- //! render functions\r
-\r
- //! render texture rectangle in window\r
- CV_EXPORTS void render(const GlTexture& tex, \r
- Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0), \r
- Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));\r
-\r
- //! render mode\r
- namespace RenderMode {\r
- enum {\r
- POINTS = 0x0000,\r
- LINES = 0x0001,\r
- LINE_LOOP = 0x0002,\r
- LINE_STRIP = 0x0003,\r
- TRIANGLES = 0x0004,\r
- TRIANGLE_STRIP = 0x0005,\r
- TRIANGLE_FAN = 0x0006,\r
- QUADS = 0x0007,\r
- QUAD_STRIP = 0x0008,\r
- POLYGON = 0x0009\r
- };\r
- }\r
+ static Ptr<GlFont> get(const std::string& family, int height = 12, Weight weight = WEIGHT_NORMAL, Style style = STYLE_NORMAL);\r
+\r
+ void draw(const char* str, size_t len) const;\r
+\r
+ inline const std::string& family() const { return family_; }\r
+ inline int height() const { return height_; }\r
+ inline Weight weight() const { return weight_; }\r
+ inline Style style() const { return style_; }\r
+\r
+private:\r
+ GlFont(const std::string& family, int height, Weight weight, Style style);\r
+\r
+ std::string family_;\r
+ int height_;\r
+ Weight weight_;\r
+ Style style_;\r
+\r
+ unsigned int base_;\r
+\r
+ GlFont(const GlFont&);\r
+ GlFont& operator =(const GlFont&);\r
+};\r
+\r
+//! render functions\r
+\r
+//! render texture rectangle in window\r
+CV_EXPORTS void render(const GlTexture& tex,\r
+ Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0),\r
+ Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));\r
+\r
+//! render mode\r
+namespace RenderMode {\r
+ enum {\r
+ POINTS = 0x0000,\r
+ LINES = 0x0001,\r
+ LINE_LOOP = 0x0002,\r
+ LINE_STRIP = 0x0003,\r
+ TRIANGLES = 0x0004,\r
+ TRIANGLE_STRIP = 0x0005,\r
+ TRIANGLE_FAN = 0x0006,\r
+ QUADS = 0x0007,\r
+ QUAD_STRIP = 0x0008,\r
+ POLYGON = 0x0009\r
+ };\r
+}\r
\r
- //! render OpenGL arrays\r
- CV_EXPORTS void render(const GlArrays& arr, int mode = RenderMode::POINTS, Scalar color = Scalar::all(255));\r
+//! render OpenGL arrays\r
+CV_EXPORTS void render(const GlArrays& arr, int mode = RenderMode::POINTS, Scalar color = Scalar::all(255));\r
\r
- CV_EXPORTS void render(const std::string& str, const Ptr<GlFont>& font, Scalar color, Point2d pos);\r
+CV_EXPORTS void render(const std::string& str, const Ptr<GlFont>& font, Scalar color, Point2d pos);\r
\r
- //! OpenGL camera\r
- class CV_EXPORTS GlCamera\r
- {\r
- public:\r
- GlCamera();\r
+//! OpenGL camera\r
+class CV_EXPORTS GlCamera\r
+{\r
+public:\r
+ GlCamera();\r
\r
- void lookAt(Point3d eye, Point3d center, Point3d up);\r
- void setCameraPos(Point3d pos, double yaw, double pitch, double roll);\r
+ void lookAt(Point3d eye, Point3d center, Point3d up);\r
+ void setCameraPos(Point3d pos, double yaw, double pitch, double roll);\r
\r
- void setScale(Point3d scale);\r
+ void setScale(Point3d scale);\r
\r
- void setProjectionMatrix(const Mat& projectionMatrix, bool transpose = true);\r
- void setPerspectiveProjection(double fov, double aspect, double zNear, double zFar);\r
- void setOrthoProjection(double left, double right, double bottom, double top, double zNear, double zFar);\r
+ void setProjectionMatrix(const Mat& projectionMatrix, bool transpose = true);\r
+ void setPerspectiveProjection(double fov, double aspect, double zNear, double zFar);\r
+ void setOrthoProjection(double left, double right, double bottom, double top, double zNear, double zFar);\r
\r
- void setupProjectionMatrix() const;\r
- void setupModelViewMatrix() const;\r
+ void setupProjectionMatrix() const;\r
+ void setupModelViewMatrix() const;\r
\r
- private:\r
- Point3d eye_;\r
- Point3d center_;\r
- Point3d up_;\r
+private:\r
+ Point3d eye_;\r
+ Point3d center_;\r
+ Point3d up_;\r
\r
- Point3d pos_;\r
- double yaw_;\r
- double pitch_;\r
- double roll_;\r
+ Point3d pos_;\r
+ double yaw_;\r
+ double pitch_;\r
+ double roll_;\r
\r
- bool useLookAtParams_;\r
+ bool useLookAtParams_;\r
\r
- Point3d scale_;\r
+ Point3d scale_;\r
\r
- Mat projectionMatrix_;\r
+ Mat projectionMatrix_;\r
\r
- double fov_;\r
- double aspect_;\r
+ double fov_;\r
+ double aspect_;\r
\r
- double left_;\r
- double right_;\r
- double bottom_;\r
- double top_;\r
+ double left_;\r
+ double right_;\r
+ double bottom_;\r
+ double top_;\r
\r
- double zNear_;\r
- double zFar_;\r
+ double zNear_;\r
+ double zFar_;\r
\r
- bool perspectiveProjection_;\r
- };\r
+ bool perspectiveProjection_;\r
+};\r
\r
- namespace gpu \r
- {\r
- //! set a CUDA device to use OpenGL interoperability\r
- CV_EXPORTS void setGlDevice(int device = 0);\r
- }\r
+inline void GlBuffer::create(Size _size, int _type, Usage _usage) { create(_size.height, _size.width, _type, _usage); }\r
+inline void GlBuffer::create(int _rows, int _cols, int _type) { create(_rows, _cols, _type, usage()); }\r
+inline void GlBuffer::create(Size _size, int _type) { create(_size.height, _size.width, _type, usage()); }\r
+inline void GlTexture::create(Size _size, int _type) { create(_size.height, _size.width, _type); }\r
+\r
+namespace gpu\r
+{\r
+ //! set a CUDA device to use OpenGL interoperability\r
+ CV_EXPORTS void setGlDevice(int device = 0);\r
+}\r
} // namespace cv\r
\r
#endif // __cplusplus\r
template<typename _Tp> inline Ptr<_Tp>::~Ptr() { release(); }
-template<typename _Tp> inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& ptr)
+template<typename _Tp> inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& _ptr)
{
- obj = ptr.obj;
- refcount = ptr.refcount;
+ obj = _ptr.obj;
+ refcount = _ptr.refcount;
addref();
}
-template<typename _Tp> inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& ptr)
+template<typename _Tp> inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& _ptr)
{
- int* _refcount = ptr.refcount;
+ int* _refcount = _ptr.refcount;
if( _refcount )
CV_XADD(_refcount, 1);
release();
- obj = ptr.obj;
+ obj = _ptr.obj;
refcount = _refcount;
return *this;
}
template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator()
{ memset(this, 0, sizeof(*this)); }
-template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& seq, bool seekEnd)
+template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& _seq, bool seekEnd)
{
- cvStartReadSeq(seq.seq, this);
- index = seekEnd ? seq.seq->total : 0;
+ cvStartReadSeq(_seq.seq, this);
+ index = seekEnd ? _seq.seq->total : 0;
}
template<typename _Tp> inline void SeqIterator<_Tp>::seek(size_t pos)
return _create(name).ptr<_Tp>();
}
-template<typename _Tp> inline typename ParamType<_Tp>::member_type Algorithm::get(const string& name) const
+template<typename _Tp> inline typename ParamType<_Tp>::member_type Algorithm::get(const string& _name) const
{
typename ParamType<_Tp>::member_type value;
- info()->get(this, name.c_str(), ParamType<_Tp>::type, &value);
+ info()->get(this, _name.c_str(), ParamType<_Tp>::type, &value);
return value;
}
-template<typename _Tp> inline typename ParamType<_Tp>::member_type Algorithm::get(const char* name) const
+template<typename _Tp> inline typename ParamType<_Tp>::member_type Algorithm::get(const char* _name) const
{
typename ParamType<_Tp>::member_type value;
- info()->get(this, name, ParamType<_Tp>::type, &value);
+ info()->get(this, _name, ParamType<_Tp>::type, &value);
return value;
}
// copy or use the software.
//
//
-// License Agreement
+// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
{
using std::pair;
-
+
template<typename _KeyTp, typename _ValueTp> struct sorted_vector
{
sorted_vector() {}
size_t size() const { return vec.size(); }
_ValueTp& operator [](size_t idx) { return vec[idx]; }
const _ValueTp& operator [](size_t idx) const { return vec[idx]; }
-
+
void add(const _KeyTp& k, const _ValueTp& val)
{
pair<_KeyTp, _ValueTp> p(k, val);
std::swap(vec[i-1], vec[i]);
CV_Assert( i == 0 || vec[i].first != vec[i-1].first );
}
-
+
bool find(const _KeyTp& key, _ValueTp& value) const
{
size_t a = 0, b = vec.size();
else
b = c;
}
-
+
if( a < vec.size() && vec[a].first == key )
{
value = vec[a].second;
}
return false;
}
-
+
void get_keys(vector<_KeyTp>& keys) const
{
size_t i = 0, n = vec.size();
keys.resize(n);
-
+
for( i = 0; i < n; i++ )
keys[i] = vec[i].first;
}
-
+
vector<pair<_KeyTp, _ValueTp> > vec;
};
-
+
template<typename _ValueTp> inline const _ValueTp* findstr(const sorted_vector<string, _ValueTp>& vec,
const char* key)
{
if( !key )
return 0;
-
+
size_t a = 0, b = vec.vec.size();
while( b > a )
{
else
b = c;
}
-
+
if( strcmp(vec.vec[a].first.c_str(), key) == 0 )
return &vec.vec[a].second;
return 0;
}
-
+
Param::Param()
{
type = 0;
setter = 0;
}
-
+
Param::Param(int _type, bool _readonly, int _offset,
Algorithm::Getter _getter, Algorithm::Setter _setter,
const string& _help)
string _name;
};
-
+
static sorted_vector<string, Algorithm::Constructor>& alglist()
{
static sorted_vector<string, Algorithm::Constructor> alglist_var;
Algorithm::Algorithm()
{
}
-
+
Algorithm::~Algorithm()
{
}
-
+
string Algorithm::name() const
{
return info()->name();
}
-
-void Algorithm::set(const string& name, int value)
+
+void Algorithm::set(const string& parameter, int value)
{
- info()->set(this, name.c_str(), ParamType<int>::type, &value);
+ info()->set(this, parameter.c_str(), ParamType<int>::type, &value);
}
-void Algorithm::set(const string& name, double value)
+void Algorithm::set(const string& parameter, double value)
{
- info()->set(this, name.c_str(), ParamType<double>::type, &value);
+ info()->set(this, parameter.c_str(), ParamType<double>::type, &value);
}
-void Algorithm::set(const string& name, bool value)
+void Algorithm::set(const string& parameter, bool value)
{
- info()->set(this, name.c_str(), ParamType<bool>::type, &value);
+ info()->set(this, parameter.c_str(), ParamType<bool>::type, &value);
}
-void Algorithm::set(const string& name, const string& value)
+void Algorithm::set(const string& parameter, const string& value)
{
- info()->set(this, name.c_str(), ParamType<string>::type, &value);
+ info()->set(this, parameter.c_str(), ParamType<string>::type, &value);
}
-void Algorithm::set(const string& name, const Mat& value)
+void Algorithm::set(const string& parameter, const Mat& value)
{
- info()->set(this, name.c_str(), ParamType<Mat>::type, &value);
+ info()->set(this, parameter.c_str(), ParamType<Mat>::type, &value);
}
-void Algorithm::set(const string& name, const vector<Mat>& value)
+void Algorithm::set(const string& parameter, const vector<Mat>& value)
{
- info()->set(this, name.c_str(), ParamType<vector<Mat> >::type, &value);
-}
-
-void Algorithm::set(const string& name, const Ptr<Algorithm>& value)
+ info()->set(this, parameter.c_str(), ParamType<vector<Mat> >::type, &value);
+}
+
+void Algorithm::set(const string& parameter, const Ptr<Algorithm>& value)
{
- info()->set(this, name.c_str(), ParamType<Algorithm>::type, &value);
+ info()->set(this, parameter.c_str(), ParamType<Algorithm>::type, &value);
}
-void Algorithm::set(const char* name, int value)
+void Algorithm::set(const char* parameter, int value)
{
- info()->set(this, name, ParamType<int>::type, &value);
+ info()->set(this, parameter, ParamType<int>::type, &value);
}
-void Algorithm::set(const char* name, double value)
+void Algorithm::set(const char* parameter, double value)
{
- info()->set(this, name, ParamType<double>::type, &value);
+ info()->set(this, parameter, ParamType<double>::type, &value);
}
-void Algorithm::set(const char* name, bool value)
+void Algorithm::set(const char* parameter, bool value)
{
- info()->set(this, name, ParamType<bool>::type, &value);
+ info()->set(this, parameter, ParamType<bool>::type, &value);
}
-void Algorithm::set(const char* name, const string& value)
+void Algorithm::set(const char* parameter, const string& value)
{
- info()->set(this, name, ParamType<string>::type, &value);
+ info()->set(this, parameter, ParamType<string>::type, &value);
}
-void Algorithm::set(const char* name, const Mat& value)
+void Algorithm::set(const char* parameter, const Mat& value)
{
- info()->set(this, name, ParamType<Mat>::type, &value);
+ info()->set(this, parameter, ParamType<Mat>::type, &value);
}
-void Algorithm::set(const char* name, const vector<Mat>& value)
+void Algorithm::set(const char* parameter, const vector<Mat>& value)
{
- info()->set(this, name, ParamType<vector<Mat> >::type, &value);
-}
-
-void Algorithm::set(const char* name, const Ptr<Algorithm>& value)
+ info()->set(this, parameter, ParamType<vector<Mat> >::type, &value);
+}
+
+void Algorithm::set(const char* parameter, const Ptr<Algorithm>& value)
{
- info()->set(this, name, ParamType<Algorithm>::type, &value);
+ info()->set(this, parameter, ParamType<Algorithm>::type, &value);
}
-
-int Algorithm::getInt(const string& name) const
+
+int Algorithm::getInt(const string& parameter) const
{
- return get<int>(name);
+ return get<int>(parameter);
}
-
-double Algorithm::getDouble(const string& name) const
+
+double Algorithm::getDouble(const string& parameter) const
{
- return get<double>(name);
+ return get<double>(parameter);
}
-bool Algorithm::getBool(const string& name) const
+bool Algorithm::getBool(const string& parameter) const
{
- return get<bool>(name);
+ return get<bool>(parameter);
}
-string Algorithm::getString(const string& name) const
+string Algorithm::getString(const string& parameter) const
{
- return get<string>(name);
+ return get<string>(parameter);
}
-Mat Algorithm::getMat(const string& name) const
+Mat Algorithm::getMat(const string& parameter) const
{
- return get<Mat>(name);
+ return get<Mat>(parameter);
}
-vector<Mat> Algorithm::getMatVector(const string& name) const
+vector<Mat> Algorithm::getMatVector(const string& parameter) const
{
- return get<vector<Mat> >(name);
+ return get<vector<Mat> >(parameter);
}
-Ptr<Algorithm> Algorithm::getAlgorithm(const string& name) const
+Ptr<Algorithm> Algorithm::getAlgorithm(const string& parameter) const
{
- return get<Algorithm>(name);
+ return get<Algorithm>(parameter);
}
-
-string Algorithm::paramHelp(const string& name) const
+
+string Algorithm::paramHelp(const string& parameter) const
{
- return info()->paramHelp(name.c_str());
+ return info()->paramHelp(parameter.c_str());
}
-
-int Algorithm::paramType(const string& name) const
+
+int Algorithm::paramType(const string& parameter) const
{
- return info()->paramType(name.c_str());
+ return info()->paramType(parameter.c_str());
}
-int Algorithm::paramType(const char* name) const
+int Algorithm::paramType(const char* parameter) const
{
- return info()->paramType(name);
-}
-
+ return info()->paramType(parameter);
+}
+
void Algorithm::getParams(vector<string>& names) const
{
info()->getParams(names);
}
-
+
void Algorithm::write(FileStorage& fs) const
{
info()->write(this, fs);
}
-
+
void Algorithm::read(const FileNode& fn)
{
info()->read(this, fn);
-}
+}
+
-
AlgorithmInfo::AlgorithmInfo(const string& _name, Algorithm::Constructor create)
{
data = new AlgorithmInfoData;
AlgorithmInfo::~AlgorithmInfo()
{
delete data;
-}
-
+}
+
void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const
{
size_t i = 0, nparams = data->params.vec.size();
{
size_t i = 0, nparams = data->params.vec.size();
AlgorithmInfo* info = algo->info();
-
+
for( i = 0; i < nparams; i++ )
{
const Param& p = data->params.vec[i].second;
else
CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported parameter type");
}
-}
+}
string AlgorithmInfo::name() const
{
return data->_name;
}
-
+
union GetSetParam
{
int (Algorithm::*get_int)() const;
Mat (Algorithm::*get_mat)() const;
vector<Mat> (Algorithm::*get_mat_vector)() const;
Ptr<Algorithm> (Algorithm::*get_algo)() const;
-
+
void (Algorithm::*set_int)(int);
void (Algorithm::*set_bool)(bool);
void (Algorithm::*set_double)(double);
void (Algorithm::*set_algo)(const Ptr<Algorithm>&);
};
-void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const void* value, bool force) const
+void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, const void* value, bool force) const
{
- const Param* p = findstr(data->params, name);
+ const Param* p = findstr(data->params, parameter);
if( !p )
- CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") );
+ CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
if( !force && p->readonly )
- CV_Error_( CV_StsError, ("Parameter '%s' is readonly", name));
+ CV_Error_( CV_StsError, ("Parameter '%s' is readonly", parameter));
GetSetParam f;
f.set_int = p->setter;
else
CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type");
}
-
-void AlgorithmInfo::get(const Algorithm* algo, const char* name, int argType, void* value) const
+
+void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argType, void* value) const
{
- const Param* p = findstr(data->params, name);
+ const Param* p = findstr(data->params, parameter);
if( !p )
- CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") );
-
+ CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
+
GetSetParam f;
f.get_int = p->getter;
-
+
if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL )
{
if( p->type == Param::INT )
{
CV_Assert( argType == Param::INT || argType == Param::REAL );
int val = p->getter ? (algo->*f.get_int)() : *(int*)((uchar*)algo + p->offset);
-
+
if( argType == Param::INT )
*(int*)value = val;
else
{
CV_Assert( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL );
bool val = p->getter ? (algo->*f.get_bool)() : *(bool*)((uchar*)algo + p->offset);
-
+
if( argType == Param::INT )
*(int*)value = (int)val;
else if( argType == Param::BOOLEAN )
{
CV_Assert( argType == Param::REAL );
double val = p->getter ? (algo->*f.get_double)() : *(double*)((uchar*)algo + p->offset);
-
+
*(double*)value = val;
}
}
else if( argType == Param::STRING )
{
CV_Assert( p->type == Param::STRING );
-
+
*(string*)value = p->getter ? (algo->*f.get_string)() :
*(string*)((uchar*)algo + p->offset);
}
else if( argType == Param::MAT )
{
CV_Assert( p->type == Param::MAT );
-
+
*(Mat*)value = p->getter ? (algo->*f.get_mat)() :
*(Mat*)((uchar*)algo + p->offset);
}
else if( argType == Param::MAT_VECTOR )
{
CV_Assert( p->type == Param::MAT_VECTOR );
-
+
*(vector<Mat>*)value = p->getter ? (algo->*f.get_mat_vector)() :
*(vector<Mat>*)((uchar*)algo + p->offset);
}
else if( argType == Param::ALGORITHM )
{
CV_Assert( p->type == Param::ALGORITHM );
-
+
*(Ptr<Algorithm>*)value = p->getter ? (algo->*f.get_algo)() :
*(Ptr<Algorithm>*)((uchar*)algo + p->offset);
}
CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type");
}
-
-int AlgorithmInfo::paramType(const char* name) const
+
+int AlgorithmInfo::paramType(const char* parameter) const
{
- const Param* p = findstr(data->params, name);
+ const Param* p = findstr(data->params, parameter);
if( !p )
- CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") );
+ CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
return p->type;
}
-
-
-string AlgorithmInfo::paramHelp(const char* name) const
+
+
+string AlgorithmInfo::paramHelp(const char* parameter) const
{
- const Param* p = findstr(data->params, name);
+ const Param* p = findstr(data->params, parameter);
if( !p )
- CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") );
+ CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
return p->help;
}
{
data->params.get_keys(names);
}
-
-
-void AlgorithmInfo::addParam_(Algorithm& algo, const char* name, int argType,
- void* value, bool readOnly,
+
+
+void AlgorithmInfo::addParam_(Algorithm& algo, const char* parameter, int argType,
+ void* value, bool readOnly,
Algorithm::Getter getter, Algorithm::Setter setter,
const string& help)
{
argType == Param::REAL || argType == Param::STRING ||
argType == Param::MAT || argType == Param::MAT_VECTOR ||
argType == Param::ALGORITHM );
- data->params.add(string(name), Param(argType, readOnly,
+ data->params.add(string(parameter), Param(argType, readOnly,
(int)((size_t)value - (size_t)(void*)&algo),
getter, setter, help));
}
-
-
-void AlgorithmInfo::addParam(Algorithm& algo, const char* name,
- int& value, bool readOnly,
+
+
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+ int& value, bool readOnly,
int (Algorithm::*getter)(),
void (Algorithm::*setter)(int),
const string& help)
{
- addParam_(algo, name, ParamType<int>::type, &value, readOnly,
+ addParam_(algo, parameter, ParamType<int>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
}
-void AlgorithmInfo::addParam(Algorithm& algo, const char* name,
- bool& value, bool readOnly,
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+ bool& value, bool readOnly,
int (Algorithm::*getter)(),
void (Algorithm::*setter)(int),
const string& help)
{
- addParam_(algo, name, ParamType<bool>::type, &value, readOnly,
+ addParam_(algo, parameter, ParamType<bool>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
}
-
-void AlgorithmInfo::addParam(Algorithm& algo, const char* name,
- double& value, bool readOnly,
+
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+ double& value, bool readOnly,
double (Algorithm::*getter)(),
void (Algorithm::*setter)(double),
const string& help)
{
- addParam_(algo, name, ParamType<double>::type, &value, readOnly,
+ addParam_(algo, parameter, ParamType<double>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
}
-void AlgorithmInfo::addParam(Algorithm& algo, const char* name,
- string& value, bool readOnly,
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+ string& value, bool readOnly,
string (Algorithm::*getter)(),
void (Algorithm::*setter)(const string&),
const string& help)
{
- addParam_(algo, name, ParamType<string>::type, &value, readOnly,
+ addParam_(algo, parameter, ParamType<string>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
}
-void AlgorithmInfo::addParam(Algorithm& algo, const char* name,
- Mat& value, bool readOnly,
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+ Mat& value, bool readOnly,
Mat (Algorithm::*getter)(),
void (Algorithm::*setter)(const Mat&),
const string& help)
{
- addParam_(algo, name, ParamType<Mat>::type, &value, readOnly,
+ addParam_(algo, parameter, ParamType<Mat>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
}
-void AlgorithmInfo::addParam(Algorithm& algo, const char* name,
- vector<Mat>& value, bool readOnly,
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+ vector<Mat>& value, bool readOnly,
vector<Mat> (Algorithm::*getter)(),
void (Algorithm::*setter)(const vector<Mat>&),
const string& help)
{
- addParam_(algo, name, ParamType<vector<Mat> >::type, &value, readOnly,
+ addParam_(algo, parameter, ParamType<vector<Mat> >::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
-}
-
-void AlgorithmInfo::addParam(Algorithm& algo, const char* name,
- Ptr<Algorithm>& value, bool readOnly,
+}
+
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+ Ptr<Algorithm>& value, bool readOnly,
Ptr<Algorithm> (Algorithm::*getter)(),
void (Algorithm::*setter)(const Ptr<Algorithm>&),
const string& help)
{
- addParam_(algo, name, ParamType<Algorithm>::type, &value, readOnly,
+ addParam_(algo, parameter, ParamType<Algorithm>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
-}
+}
}
-
+
/* End of file. */
dst2[i] = src[j+2]; dst3[i] = src[j+3];
}
}
-
+
for( ; k < cn; k += 4 )
{
T *dst0 = dst[k], *dst1 = dst[k+1], *dst2 = dst[k+2], *dst3 = dst[k+3];
}
}
}
-
+
template<typename T> static void
merge_( const T** src, T* dst, int len, int cn )
{
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
-
+
for( ; k < cn; k += 4 )
{
const T *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
{
split_(src, dst, len, cn);
}
-
+
static void split64s(const int64* src, int64** dst, int len, int cn )
{
split_(src, dst, len, cn);
static void merge64s(const int64** src, int64* dst, int len, int cn )
{
merge_(src, dst, len, cn);
-}
+}
typedef void (*SplitFunc)(const uchar* src, uchar** dst, int len, int cn);
typedef void (*MergeFunc)(const uchar** src, uchar* dst, int len, int cn);
(MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge16u), (MergeFunc)GET_OPTIMIZED(merge16u),
(MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge64s), 0
};
-
+
}
-
+
void cv::split(const Mat& src, Mat* mv)
{
int k, depth = src.depth(), cn = src.channels();
SplitFunc func = splitTab[depth];
CV_Assert( func != 0 );
-
+
int esz = (int)src.elemSize(), esz1 = (int)src.elemSize1();
int blocksize0 = (BLOCK_SIZE + esz-1)/esz;
AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
const Mat** arrays = (const Mat**)(uchar*)_buf;
uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
-
+
arrays[0] = &src;
for( k = 0; k < cn; k++ )
{
mv[k].create(src.dims, src.size, depth);
arrays[k+1] = &mv[k];
}
-
+
NAryMatIterator it(arrays, ptrs, cn+1);
int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
-
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
for( int j = 0; j < total; j += blocksize )
{
int bsz = std::min(total - j, blocksize);
func( ptrs[0], &ptrs[1], bsz, cn );
-
+
if( j + blocksize < total )
{
ptrs[0] += bsz*esz;
}
}
}
-
+
void cv::split(InputArray _m, OutputArrayOfArrays _mv)
{
Mat m = _m.getMat();
Mat* dst = &_mv.getMatRef(0);
split(m, dst);
}
-
+
void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
{
CV_Assert( mv && n > 0 );
-
+
int depth = mv[0].depth();
bool allch1 = true;
int k, cn = 0;
size_t i;
-
+
for( i = 0; i < n; i++ )
{
CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth);
allch1 = allch1 && mv[i].channels() == 1;
cn += mv[i].channels();
}
-
+
CV_Assert( 0 < cn && cn <= CV_CN_MAX );
_dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn));
Mat dst = _dst.getMat();
-
+
if( n == 1 )
{
mv[0].copyTo(dst);
return;
}
-
+
if( !allch1 )
{
AutoBuffer<int> pairs(cn*2);
int j, ni=0;
-
+
for( i = 0, j = 0; i < n; i++, j += ni )
{
ni = mv[i].channels();
mixChannels( mv, n, &dst, 1, &pairs[0], cn );
return;
}
-
+
size_t esz = dst.elemSize(), esz1 = dst.elemSize1();
int blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz);
AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
const Mat** arrays = (const Mat**)(uchar*)_buf;
uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
-
+
arrays[0] = &dst;
for( k = 0; k < cn; k++ )
arrays[k+1] = &mv[k];
-
+
NAryMatIterator it(arrays, ptrs, cn+1);
int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
MergeFunc func = mergeTab[depth];
-
+
for( i = 0; i < it.nplanes; i++, ++it )
{
for( int j = 0; j < total; j += blocksize )
{
int bsz = std::min(total - j, blocksize);
func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn );
-
+
if( j + blocksize < total )
{
ptrs[0] += bsz*esz;
- for( int k = 0; k < cn; k++ )
- ptrs[k+1] += bsz*esz1;
+ for( int t = 0; t < cn; t++ )
+ ptrs[t+1] += bsz*esz1;
}
}
}
vector<Mat> mv;
_mv.getMatVector(mv);
merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst);
-}
+}
/****************************************************************************************\
* Generalized split/merge: mixing channels *
}
}
-
+
static void mixChannels8u( const uchar** src, const int* sdelta,
uchar** dst, const int* ddelta,
int len, int npairs )
{
mixChannels_(src, sdelta, dst, ddelta, len, npairs);
}
-
+
static void mixChannels64s( const int64** src, const int* sdelta,
int64** dst, const int* ddelta,
int len, int npairs )
{
mixChannels_(src, sdelta, dst, ddelta, len, npairs);
}
-
+
typedef void (*MixChannelsFunc)( const uchar** src, const int* sdelta,
uchar** dst, const int* ddelta, int len, int npairs );
{
(MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels16u,
(MixChannelsFunc)mixChannels16u, (MixChannelsFunc)mixChannels32s, (MixChannelsFunc)mixChannels32s,
- (MixChannelsFunc)mixChannels64s, 0
+ (MixChannelsFunc)mixChannels64s, 0
};
-
+
}
-
+
void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs )
{
if( npairs == 0 )
return;
CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 );
-
+
size_t i, j, k, esz1 = dst[0].elemSize1();
int depth = dst[0].depth();
uchar** dsts = (uchar**)(srcs + npairs);
int* tab = (int*)(dsts + npairs);
int *sdelta = (int*)(tab + npairs*4), *ddelta = sdelta + npairs;
-
+
for( i = 0; i < nsrcs; i++ )
arrays[i] = &src[i];
for( i = 0; i < ndsts; i++ )
arrays[i + nsrcs] = &dst[i];
ptrs[nsrcs + ndsts] = 0;
-
+
for( i = 0; i < npairs; i++ )
{
int i0 = fromTo[i*2], i1 = fromTo[i*2+1];
tab[i*4] = (int)(nsrcs + ndsts); tab[i*4+1] = 0;
sdelta[i] = 0;
}
-
+
for( j = 0; j < ndsts; i1 -= dst[j].channels(), j++ )
if( i1 < dst[j].channels() )
break;
NAryMatIterator it(arrays, ptrs, (int)(nsrcs + ndsts));
int total = (int)it.size, blocksize = std::min(total, (int)((BLOCK_SIZE + esz1-1)/esz1));
MixChannelsFunc func = mixchTab[depth];
-
+
for( i = 0; i < it.nplanes; i++, ++it )
{
for( k = 0; k < npairs; k++ )
srcs[k] = ptrs[tab[k*4]] + tab[k*4+1];
dsts[k] = ptrs[tab[k*4+2]] + tab[k*4+3];
}
-
- for( int j = 0; j < total; j += blocksize )
+
+ for( int t = 0; t < total; t += blocksize )
{
- int bsz = std::min(total - j, blocksize);
+ int bsz = std::min(total - t, blocksize);
func( srcs, sdelta, dsts, ddelta, bsz, (int)npairs );
-
- if( j + blocksize < total )
+
+ if( t + blocksize < total )
for( k = 0; k < npairs; k++ )
{
srcs[k] += blocksize*sdelta[k]*esz1;
int i;
int nsrc = src_is_mat ? 1 : (int)src.total();
int ndst = dst_is_mat ? 1 : (int)dst.total();
-
+
CV_Assert(fromTo.size()%2 == 0 && nsrc > 0 && ndst > 0);
cv::AutoBuffer<Mat> _buf(nsrc + ndst);
Mat* buf = _buf;
{
sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]);
-
+
for( ; size.height--; src += sstep, dst += dstep )
{
int x = 0;
t1 = saturate_cast<DT>(std::abs(src[x+3]*scale + shift));
dst[x+2] = t0; dst[x+3] = t1;
}
- #endif
+ #endif
for( ; x < size.width; x++ )
dst[x] = saturate_cast<DT>(std::abs(src[x]*scale + shift));
}
-}
+}
template<typename T, typename DT, typename WT> static void
{
sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]);
-
+
for( ; size.height--; src += sstep, dst += dstep )
{
int x = 0;
template<> void
cvtScale_<short, short, float>( const short* src, size_t sstep,
short* dst, size_t dstep, Size size,
- float scale, float shift )
+ float scale, float shift )
{
sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]);
- for( ; size.height--; src += sstep, dst += dstep )
+ for( ; size.height--; src += sstep, dst += dstep )
{
int x = 0;
- #if CV_SSE2
- if(USE_SSE2)
+ #if CV_SSE2
+ if(USE_SSE2)
{
__m128 scale128 = _mm_set1_ps (scale);
__m128 shift128 = _mm_set1_ps (shift);
- for(; x <= size.width - 8; x += 8 )
- {
- __m128i r0 = _mm_loadl_epi64((const __m128i*)(src + x));
+ for(; x <= size.width - 8; x += 8 )
+ {
+ __m128i r0 = _mm_loadl_epi64((const __m128i*)(src + x));
__m128i r1 = _mm_loadl_epi64((const __m128i*)(src + x + 4));
- __m128 rf0 =_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(r0, r0), 16));
+ __m128 rf0 =_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(r0, r0), 16));
__m128 rf1 =_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(r1, r1), 16));
rf0 = _mm_add_ps(_mm_mul_ps(rf0, scale128), shift128);
rf1 = _mm_add_ps(_mm_mul_ps(rf1, scale128), shift128);
- r0 = _mm_cvtps_epi32(rf0);
- r1 = _mm_cvtps_epi32(rf1);
- r0 = _mm_packs_epi32(r0, r1);
- _mm_storeu_si128((__m128i*)(dst + x), r0);
- }
- }
+ r0 = _mm_cvtps_epi32(rf0);
+ r1 = _mm_cvtps_epi32(rf1);
+ r0 = _mm_packs_epi32(r0, r1);
+ _mm_storeu_si128((__m128i*)(dst + x), r0);
+ }
+ }
#endif
for(; x < size.width; x++ )
dst[x] = saturate_cast<short>(src[x]*scale + shift);
- }
+ }
}
{
sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]);
-
+
for( ; size.height--; src += sstep, dst += dstep )
{
int x = 0;
- #if CV_ENABLE_UNROLLED
- for( ; x <= size.width - 4; x += 4 )
- {
- DT t0, t1;
- t0 = saturate_cast<DT>(src[x]);
- t1 = saturate_cast<DT>(src[x+1]);
- dst[x] = t0; dst[x+1] = t1;
- t0 = saturate_cast<DT>(src[x+2]);
- t1 = saturate_cast<DT>(src[x+3]);
- dst[x+2] = t0; dst[x+3] = t1;
- }
+ #if CV_ENABLE_UNROLLED
+ for( ; x <= size.width - 4; x += 4 )
+ {
+ DT t0, t1;
+ t0 = saturate_cast<DT>(src[x]);
+ t1 = saturate_cast<DT>(src[x+1]);
+ dst[x] = t0; dst[x+1] = t1;
+ t0 = saturate_cast<DT>(src[x+2]);
+ t1 = saturate_cast<DT>(src[x+3]);
+ dst[x+2] = t0; dst[x+3] = t1;
+ }
#endif
for( ; x < size.width; x++ )
dst[x] = saturate_cast<DT>(src[x]);
{
sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]);
-
+
for( ; size.height--; src += sstep, dst += dstep )
{
int x = 0;
- #if CV_SSE2
- if(USE_SSE2){
- for( ; x <= size.width - 8; x += 8 )
- {
- __m128 src128 = _mm_loadu_ps (src + x);
- __m128i src_int128 = _mm_cvtps_epi32 (src128);
-
- src128 = _mm_loadu_ps (src + x + 4);
- __m128i src1_int128 = _mm_cvtps_epi32 (src128);
-
- src1_int128 = _mm_packs_epi32(src_int128, src1_int128);
- _mm_storeu_si128((__m128i*)(dst + x),src1_int128);
- }
- }
+ #if CV_SSE2
+ if(USE_SSE2){
+ for( ; x <= size.width - 8; x += 8 )
+ {
+ __m128 src128 = _mm_loadu_ps (src + x);
+ __m128i src_int128 = _mm_cvtps_epi32 (src128);
+
+ src128 = _mm_loadu_ps (src + x + 4);
+ __m128i src1_int128 = _mm_cvtps_epi32 (src128);
+
+ src1_int128 = _mm_packs_epi32(src_int128, src1_int128);
+ _mm_storeu_si128((__m128i*)(dst + x),src1_int128);
+ }
+ }
#endif
for( ; x < size.width; x++ )
dst[x] = saturate_cast<short>(src[x]);
{
sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]);
-
+
for( ; size.height--; src += sstep, dst += dstep )
memcpy(dst, src, size.width*sizeof(src[0]));
}
-
+
#define DEF_CVT_SCALE_ABS_FUNC(suffix, tfunc, stype, dtype, wtype) \
static void cvtScaleAbs##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
dtype* dst, size_t dstep, Size size, double* scale) \
{ \
cvtScale_(src, sstep, dst, dstep, size, (wtype)scale[0], (wtype)scale[1]); \
}
-
-
+
+
#define DEF_CVT_FUNC(suffix, stype, dtype) \
static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
dtype* dst, size_t dstep, Size size, double*) \
{ \
cpy_(src, sstep, dst, dstep, size); \
}
-
-
+
+
DEF_CVT_SCALE_ABS_FUNC(8u, cvtScaleAbs_, uchar, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(8s8u, cvtScaleAbs_, schar, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(16u8u, cvtScaleAbs_, ushort, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(16s8u, cvtScaleAbs_, short, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(32s8u, cvtScaleAbs_, int, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(32f8u, cvtScaleAbs_, float, uchar, float);
-DEF_CVT_SCALE_ABS_FUNC(64f8u, cvtScaleAbs_, double, uchar, float);
+DEF_CVT_SCALE_ABS_FUNC(64f8u, cvtScaleAbs_, double, uchar, float);
DEF_CVT_SCALE_FUNC(8u, uchar, uchar, float);
DEF_CVT_SCALE_FUNC(8s8u, schar, uchar, float);
DEF_CVT_SCALE_FUNC(16s8u, short, uchar, float);
DEF_CVT_SCALE_FUNC(32s8u, int, uchar, float);
DEF_CVT_SCALE_FUNC(32f8u, float, uchar, float);
-DEF_CVT_SCALE_FUNC(64f8u, double, uchar, float);
+DEF_CVT_SCALE_FUNC(64f8u, double, uchar, float);
DEF_CVT_SCALE_FUNC(8u8s, uchar, schar, float);
DEF_CVT_SCALE_FUNC(8s, schar, schar, float);
DEF_CVT_SCALE_FUNC(16s8s, short, schar, float);
DEF_CVT_SCALE_FUNC(32s8s, int, schar, float);
DEF_CVT_SCALE_FUNC(32f8s, float, schar, float);
-DEF_CVT_SCALE_FUNC(64f8s, double, schar, float);
+DEF_CVT_SCALE_FUNC(64f8s, double, schar, float);
DEF_CVT_SCALE_FUNC(8u16u, uchar, ushort, float);
DEF_CVT_SCALE_FUNC(8s16u, schar, ushort, float);
DEF_CVT_SCALE_FUNC(16s16u, short, ushort, float);
DEF_CVT_SCALE_FUNC(32s16u, int, ushort, float);
DEF_CVT_SCALE_FUNC(32f16u, float, ushort, float);
-DEF_CVT_SCALE_FUNC(64f16u, double, ushort, float);
+DEF_CVT_SCALE_FUNC(64f16u, double, ushort, float);
DEF_CVT_SCALE_FUNC(8u16s, uchar, short, float);
DEF_CVT_SCALE_FUNC(8s16s, schar, short, float);
DEF_CVT_SCALE_FUNC(32s16s, int, short, float);
DEF_CVT_SCALE_FUNC(32f16s, float, short, float);
DEF_CVT_SCALE_FUNC(64f16s, double, short, float);
-
+
DEF_CVT_SCALE_FUNC(8u32s, uchar, int, float);
DEF_CVT_SCALE_FUNC(8s32s, schar, int, float);
DEF_CVT_SCALE_FUNC(16u32s, ushort, int, float);
DEF_CVT_FUNC(32s64f, int, double);
DEF_CVT_FUNC(32f64f, float, double);
DEF_CPY_FUNC(64s, int64);
-
+
static BinaryFunc cvtScaleAbsTab[] =
{
(BinaryFunc)cvtScaleAbs8u, (BinaryFunc)cvtScaleAbs8s8u, (BinaryFunc)cvtScaleAbs16u8u,
0, 0, 0, 0, 0, 0, 0, 0
}
};
-
+
BinaryFunc getConvertFunc(int sdepth, int ddepth)
{
return cvtTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)];
BinaryFunc getConvertScaleFunc(int sdepth, int ddepth)
{
return cvtScaleTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)];
-}
-
}
-
+
+}
+
void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, double beta )
{
Mat src = _src.getMat();
Mat dst = _dst.getMat();
BinaryFunc func = cvtScaleAbsTab[src.depth()];
CV_Assert( func != 0 );
-
+
if( src.dims <= 2 )
{
Size sz = getContinuousSize(src, dst, cn);
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs);
Size sz((int)it.size*cn, 1);
-
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
func( ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale );
}
}
Mat src = *this;
-
+
BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth);
double scale[] = {alpha, beta};
int cn = channels();
CV_Assert( func != 0 );
-
+
if( dims <= 2 )
{
_dst.create( size(), _type );
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs);
Size sz((int)(it.size*cn), 1);
-
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
func(ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale);
}
static void LUT8u_64f( const uchar* src, const double* lut, double* dst, int len, int cn, int lutcn )
{
LUT8u_( src, lut, dst, len, cn, lutcn );
-}
-
+}
+
typedef void (*LUTFunc)( const uchar* src, const uchar* lut, uchar* dst, int len, int cn, int lutcn );
-
+
static LUTFunc lutTab[] =
{
(LUTFunc)LUT8u_8u, (LUTFunc)LUT8u_8s, (LUTFunc)LUT8u_16u, (LUTFunc)LUT8u_16s,
};
}
-
+
void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst, int interpolation )
{
Mat src = _src.getMat(), lut = _lut.getMat();
LUTFunc func = lutTab[lut.depth()];
CV_Assert( func != 0 );
-
+
const Mat* arrays[] = {&src, &dst, 0};
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs);
int len = (int)it.size;
-
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
func(ptrs[0], lut.data, ptrs[1], len, cn, lutcn);
}
int norm_type, int rtype, InputArray _mask )
{
Mat src = _src.getMat(), mask = _mask.getMat();
-
+
double scale = 1, shift = 0;
if( norm_type == CV_MINMAX )
{
}
else
CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" );
-
+
if( rtype < 0 )
rtype = _dst.fixedType() ? _dst.depth() : src.depth();
-
+
_dst.create(src.dims, src.size, CV_MAKETYPE(rtype, src.channels()));
Mat dst = _dst.getMat();
-
+
if( !mask.data )
src.convertTo( dst, rtype, scale, shift );
else
double scale, double shift )
{
cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
-
+
CV_Assert( src.size == dst.size && src.channels() == dst.channels() );
src.convertTo(dst, dst.type(), scale, shift);
}
const T* src = (const T*)_src;
T* dst = (T*)_dst;
int x = 0;
- #if CV_ENABLE_UNROLLED
+ #if CV_ENABLE_UNROLLED
for( ; x <= size.width - 4; x += 4 )
{
if( mask[x] )
}
}
}
-
-
+
+
#define DEF_COPY_MASK(suffix, type) \
static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask, size_t mstep, \
uchar* dst, size_t dstep, Size size, void*) \
{ \
copyMask_<type>(src, sstep, mask, mstep, dst, dstep, size); \
}
-
-
+
+
DEF_COPY_MASK(8u, uchar);
DEF_COPY_MASK(16u, ushort);
DEF_COPY_MASK(8uC3, Vec3b);
DEF_COPY_MASK(32sC4, Vec4i);
DEF_COPY_MASK(32sC6, Vec6i);
DEF_COPY_MASK(32sC8, Vec8i);
-
+
BinaryFunc copyMaskTab[] =
{
0,
0, 0, 0, 0, 0, 0, 0,
copyMask32sC8
};
-
+
BinaryFunc getCopyMaskFunc(size_t esz)
{
return esz <= 32 && copyMaskTab[esz] ? copyMaskTab[esz] : copyMaskGeneric;
convertTo( _dst, dtype );
return;
}
-
+
if( empty() )
{
_dst.release();
return;
}
-
+
if( dims <= 2 )
{
_dst.create( rows, cols, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
-
+
if( rows > 0 && cols > 0 )
{
const uchar* sptr = data;
uchar* dptr = dst.data;
-
+
// to handle the copying 1xn matrix => nx1 std vector.
Size sz = size() == dst.size() ?
getContinuousSize(*this, dst) :
getContinuousSize(*this);
size_t len = sz.width*elemSize();
-
+
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, len );
}
return;
}
-
+
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
-
+
if( total() != 0 )
{
const Mat* arrays[] = { this, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
- size_t size = it.size*elemSize();
-
+ size_t sz = it.size*elemSize();
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
- memcpy(ptrs[1], ptrs[0], size);
+ memcpy(ptrs[1], ptrs[0], sz);
}
}
copyTo(_dst);
return;
}
-
+
int cn = channels(), mcn = mask.channels();
CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) );
bool colorMask = mcn > 1;
-
+
size_t esz = colorMask ? elemSize1() : elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
-
+
uchar* data0 = _dst.getMat().data;
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
-
+
if( dst.data != data0 ) // do not leave dst uninitialized
dst = Scalar(0);
-
+
if( dims <= 2 )
{
Size sz = getContinuousSize(*this, dst, mask, mcn);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return;
}
-
+
const Mat* arrays[] = { this, &dst, &mask, 0 };
uchar* ptrs[3];
NAryMatIterator it(arrays, ptrs);
Size sz((int)(it.size*mcn), 1);
-
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz);
}
Mat& Mat::operator = (const Scalar& s)
{
const Mat* arrays[] = { this };
- uchar* ptr;
- NAryMatIterator it(arrays, &ptr, 1);
- size_t size = it.size*elemSize();
-
+ uchar* dptr;
+ NAryMatIterator it(arrays, &dptr, 1);
+ size_t elsize = it.size*elemSize();
+
if( s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0 )
{
for( size_t i = 0; i < it.nplanes; i++, ++it )
- memset( ptr, 0, size );
+ memset( dptr, 0, elsize );
}
else
{
double scalar[12];
scalarToRawData(s, scalar, type(), 12);
size_t blockSize = 12*elemSize1();
-
- for( size_t j = 0; j < size; j += blockSize )
+
+ for( size_t j = 0; j < elsize; j += blockSize )
{
- size_t sz = MIN(blockSize, size - j);
- memcpy( ptr + j, scalar, sz );
+ size_t sz = MIN(blockSize, elsize - j);
+ memcpy( dptr + j, scalar, sz );
}
}
-
+
for( size_t i = 1; i < it.nplanes; i++ )
{
++it;
- memcpy( ptr, data, size );
+ memcpy( dptr, data, elsize );
}
}
return *this;
}
-
+
Mat& Mat::setTo(InputArray _value, InputArray _mask)
{
if( !data )
return *this;
-
+
Mat value = _value.getMat(), mask = _mask.getMat();
-
+
CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT ));
CV_Assert( mask.empty() || mask.type() == CV_8U );
-
+
size_t esz = elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
-
+
const Mat* arrays[] = { this, !mask.empty() ? &mask : 0, 0 };
uchar* ptrs[2]={0,0};
NAryMatIterator it(arrays, ptrs);
- int total = (int)it.size, blockSize0 = std::min(total, (int)((BLOCK_SIZE + esz-1)/esz));
+ int totalsz = (int)it.size, blockSize0 = std::min(totalsz, (int)((BLOCK_SIZE + esz-1)/esz));
AutoBuffer<uchar> _scbuf(blockSize0*esz + 32);
uchar* scbuf = alignPtr((uchar*)_scbuf, (int)sizeof(double));
convertAndUnrollScalar( value, type(), scbuf, blockSize0 );
-
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
- for( int j = 0; j < total; j += blockSize0 )
+ for( int j = 0; j < totalsz; j += blockSize0 )
{
- Size sz(std::min(blockSize0, total - j), 1);
+ Size sz(std::min(blockSize0, totalsz - j), 1);
size_t blockSize = sz.width*esz;
if( ptrs[1] )
{
int i, j, limit = (int)(((size.width + 1)/2)*esz);
AutoBuffer<int> _tab(size.width*esz);
int* tab = _tab;
-
+
for( i = 0; i < size.width; i++ )
for( size_t k = 0; k < esz; k++ )
tab[i*esz + k] = (int)((size.width - i - 1)*esz + k);
void flip( InputArray _src, OutputArray _dst, int flip_mode )
{
Mat src = _src.getMat();
-
+
CV_Assert( src.dims <= 2 );
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
flipVert( src.data, src.step, dst.data, dst.step, src.size(), esz );
else
flipHoriz( src.data, src.step, dst.data, dst.step, src.size(), esz );
-
+
if( flip_mode < 0 )
flipHoriz( dst.data, dst.step, dst.data, dst.step, dst.size(), esz );
}
{
Mat src = _src.getMat();
CV_Assert( src.dims <= 2 );
-
+
_dst.create(src.rows*ny, src.cols*nx, src.type());
Mat dst = _dst.getMat();
Size ssize = src.size(), dsize = dst.size();
}
cv::Mat src = cv::cvarrToMat(srcarr, false, true, 1), dst = cv::cvarrToMat(dstarr, false, true, 1);
CV_Assert( src.depth() == dst.depth() && src.size == dst.size );
-
+
int coi1 = 0, coi2 = 0;
if( CV_IS_IMAGE(srcarr) )
coi1 = cvGetImageCOI((const IplImage*)srcarr);
if( CV_IS_IMAGE(dstarr) )
coi2 = cvGetImageCOI((const IplImage*)dstarr);
-
+
if( coi1 || coi2 )
{
CV_Assert( (coi1 != 0 || src.channels() == 1) &&
(coi2 != 0 || dst.channels() == 1) );
-
+
int pair[] = { std::max(coi1-1, 0), std::max(coi2-1, 0) };
cv::mixChannels( &src, 1, &dst, 1, pair, 1 );
return;
}
else
CV_Assert( src.channels() == dst.channels() );
-
+
if( !maskarr )
src.copyTo(dst);
else
{
cv::Mat src = cv::cvarrToMat(srcarr);
cv::Mat dst;
-
+
if (!dstarr)
dst = src;
else
dst = cv::cvarrToMat(dstarr);
-
+
CV_Assert( src.type() == dst.type() && src.size() == dst.size() );
cv::flip( src, dst, flip_mode );
}
}
}
-
+
return allseq;
}
// both cv (CvFeatureTree) and ml (kNN).
// The algorithm is taken from:
-// J.S. Beis and D.G. Lowe. Shape indexing using approximate nearest-neighbor search
-// in highdimensional spaces. In Proc. IEEE Conf. Comp. Vision Patt. Recog.,
-// pages 1000--1006, 1997. http://citeseer.ist.psu.edu/beis97shape.html
+// J.S. Beis and D.G. Lowe. Shape indexing using approximate nearest-neighbor search
+// in highdimensional spaces. In Proc. IEEE Conf. Comp. Vision Patt. Recog.,
+// pages 1000--1006, 1997. http://citeseer.ist.psu.edu/beis97shape.html
const int MAX_TREE_DEPTH = 32;
maxDepth = -1;
normType = NORM_L2;
build(_points, _labels, _copyData);
-}
-
+}
+
struct SubTree
{
SubTree() : first(0), last(0), nodeIdx(0), depth(0) {}
else
a = i0;
}
-
+
float pivot = vals[ofs[middle]];
int less = 0, more = 0;
for( k = a0; k < middle; k++ )
}
}
-
+
void KDTree::build(InputArray _points, bool _copyData)
{
build(_points, noArray(), _copyData);
points.release();
points.create(_points.size(), _points.type());
}
-
- int i, j, n = _points.rows, dims = _points.cols, top = 0;
+
+ int i, j, n = _points.rows, ptdims = _points.cols, top = 0;
const float* data = _points.ptr<float>(0);
float* dstdata = points.ptr<float>(0);
size_t step = _points.step1();
int ptpos = 0;
labels.resize(n);
const int* _labels_data = 0;
-
+
if( !_labels.empty() )
{
int nlabels = _labels.checkVector(1, CV_32S, true);
_labels_data = (const int*)_labels.data;
}
- Mat sumstack(MAX_TREE_DEPTH*2, dims*2, CV_64F);
+ Mat sumstack(MAX_TREE_DEPTH*2, ptdims*2, CV_64F);
SubTree stack[MAX_TREE_DEPTH*2];
-
+
vector<size_t> _ptofs(n);
size_t* ptofs = &_ptofs[0];
computeSums(points, ptofs, 0, n-1, sumstack.ptr<double>(top));
stack[top++] = SubTree(0, n-1, 0, 0);
int _maxDepth = 0;
-
+
while( --top >= 0 )
{
int first = stack[top].first, last = stack[top].last;
{
const float* src = data + ptofs[first];
float* dst = dstdata + idx*dstep;
- for( j = 0; j < dims; j++ )
+ for( j = 0; j < ptdims; j++ )
dst[j] = src[j];
}
- labels[idx] = _labels_data ? _labels_data[idx0] : idx0;
+ labels[idx] = _labels_data ? _labels_data[idx0] : idx0;
_maxDepth = std::max(_maxDepth, depth);
continue;
}
// find the dimensionality with the biggest variance
- for( j = 0; j < dims; j++ )
+ for( j = 0; j < ptdims; j++ )
{
double m = sums[j*2]*invCount;
double varj = sums[j*2+1]*invCount - m*m;
nodes[nidx].boundary = medianPartition(ptofs, first, last, data + dim);
int middle = (first + last)/2;
- double *lsums = (double*)sums, *rsums = lsums + dims*2;
+ double *lsums = (double*)sums, *rsums = lsums + ptdims*2;
computeSums(points, ptofs, middle+1, last, rsums);
- for( j = 0; j < dims*2; j++ )
+ for( j = 0; j < ptdims*2; j++ )
lsums[j] = sums[j] - rsums[j];
stack[top++] = SubTree(first, middle, left, depth+1);
stack[top++] = SubTree(middle+1, last, right, depth+1);
int KDTree::findNearest(InputArray _vec, int K, int emax,
OutputArray _neighborsIdx, OutputArray _neighbors,
OutputArray _dist, OutputArray _labels) const
-
+
{
Mat vecmat = _vec.getMat();
CV_Assert( vecmat.isContinuous() && vecmat.type() == CV_32F && vecmat.total() == (size_t)points.cols );
const float* vec = vecmat.ptr<float>();
K = std::min(K, points.rows);
- int dims = points.cols;
+ int ptdims = points.cols;
CV_Assert(K > 0 && (normType == NORM_L2 || normType == NORM_L1));
{
float d, alt_d = 0.f;
int nidx;
-
+
if( e == 0 )
nidx = 0;
else
i = left;
}
}
-
+
if( ncount == K && alt_d > dist[ncount-1] )
continue;
}
if( nidx < 0 )
break;
const Node& n = nodes[nidx];
-
+
if( n.idx < 0 )
{
i = ~n.idx;
const float* row = points.ptr<float>(i);
if( normType == NORM_L2 )
- for( j = 0, d = 0.f; j < dims; j++ )
+ for( j = 0, d = 0.f; j < ptdims; j++ )
{
float t = vec[j] - row[j];
d += t*t;
}
else
- for( j = 0, d = 0.f; j < dims; j++ )
+ for( j = 0, d = 0.f; j < ptdims; j++ )
d += std::abs(vec[j] - row[j]);
-
+
dist[ncount] = d;
idx[ncount] = i;
for( i = ncount-1; i >= 0; i-- )
}
ncount += ncount < K;
e++;
- break;
+ break;
}
-
+
int alt;
if( vec[n.idx] <= n.boundary )
{
nidx = n.right;
alt = n.left;
}
-
+
d = vec[n.idx] - n.boundary;
if( normType == NORM_L2 )
d = d*d + alt_d;
OutputArray _neighbors,
OutputArray _labels ) const
{
- int dims = points.cols;
+ int ptdims = points.cols;
Mat lowerBound = _lowerBound.getMat(), upperBound = _upperBound.getMat();
CV_Assert( lowerBound.size == upperBound.size &&
lowerBound.isContinuous() &&
upperBound.isContinuous() &&
lowerBound.type() == upperBound.type() &&
lowerBound.type() == CV_32F &&
- lowerBound.total() == (size_t)dims );
+ lowerBound.total() == (size_t)ptdims );
const float* L = lowerBound.ptr<float>();
const float* R = upperBound.ptr<float>();
-
+
vector<int> idx;
AutoBuffer<int> _stack(MAX_TREE_DEPTH*2 + 1);
int* stack = _stack;
int top = 0;
-
+
stack[top++] = 0;
while( --top >= 0 )
{
int j, i = ~n.idx;
const float* row = points.ptr<float>(i);
- for( j = 0; j < dims; j++ )
+ for( j = 0; j < ptdims; j++ )
if( row[j] < L[j] || row[j] >= R[j] )
break;
- if( j == dims )
+ if( j == ptdims )
idx.push_back(i);
continue;
}
getPoints( idx, _neighbors, _labels );
}
-
+
void KDTree::getPoints(InputArray _idx, OutputArray _pts, OutputArray _labels) const
{
Mat idxmat = _idx.getMat(), pts, labelsmat;
(idxmat.cols == 1 || idxmat.rows == 1) );
const int* idx = idxmat.ptr<int>();
int* dstlabels = 0;
-
- int dims = points.cols;
+
+ int ptdims = points.cols;
int i, nidx = (int)idxmat.total();
if( nidx == 0 )
{
_labels.release();
return;
}
-
+
if( _pts.needed() )
{
- _pts.create( nidx, dims, points.type());
+ _pts.create( nidx, ptdims, points.type());
pts = _pts.getMat();
}
-
+
if(_labels.needed())
{
_labels.create(nidx, 1, CV_32S, -1, true);
dstlabels = labelsmat.ptr<int>();
}
const int* srclabels = !labels.empty() ? &labels[0] : 0;
-
+
for( i = 0; i < nidx; i++ )
{
int k = idx[i];
CV_Assert( (unsigned)k < (unsigned)points.rows );
const float* src = points.ptr<float>(k);
if( pts.data )
- std::copy(src, src + dims, pts.ptr<float>(i));
+ std::copy(src, src + ptdims, pts.ptr<float>(i));
if( dstlabels )
dstlabels[i] = srclabels ? srclabels[k] : k;
}
{
return !points.empty() ? points.cols : 0;
}
-
+
////////////////////////////////////////////////////////////////////////////////
-
+
schar* seqPush( CvSeq* seq, const void* element )
{
return cvSeqPush(seq, element);
}
int bt_pix0 = (int)img.elemSize(), bt_pix = bt_pix0;
- size_t step = img.step;
+ size_t istep = img.step;
int dx = pt2.x - pt1.x;
int dy = pt2.y - pt1.y;
bt_pix = (bt_pix ^ s) - s;
}
- ptr = (uchar*)(img.data + pt1.y * step + pt1.x * bt_pix0);
+ ptr = (uchar*)(img.data + pt1.y * istep + pt1.x * bt_pix0);
s = dy < 0 ? -1 : 0;
dy = (dy ^ s) - s;
- step = (step ^ s) - s;
+ istep = (istep ^ s) - s;
s = dy > dx ? -1 : 0;
dy ^= dx & s;
dx ^= dy & s;
- bt_pix ^= step & s;
- step ^= bt_pix & s;
- bt_pix ^= step & s;
+ bt_pix ^= istep & s;
+ istep ^= bt_pix & s;
+ bt_pix ^= istep & s;
if( connectivity == 8 )
{
err = dx - (dy + dy);
plusDelta = dx + dx;
minusDelta = -(dy + dy);
- plusStep = (int)step;
+ plusStep = (int)istep;
minusStep = bt_pix;
count = dx + 1;
}
err = 0;
plusDelta = (dx + dx) + (dy + dy);
minusDelta = -(dy + dy);
- plusStep = (int)step - bt_pix;
+ plusStep = (int)istep - bt_pix;
minusStep = bt_pix;
count = dx + dy + 1;
}
dataend += step * (rows - 1) + minstep;\r
}\r
\r
-cv::gpu::GpuMat::GpuMat(const GpuMat& m, Range rowRange, Range colRange)\r
+cv::gpu::GpuMat::GpuMat(const GpuMat& m, Range _rowRange, Range _colRange)\r
{\r
flags = m.flags;\r
step = m.step; refcount = m.refcount;\r
data = m.data; datastart = m.datastart; dataend = m.dataend;\r
\r
- if (rowRange == Range::all())\r
+ if (_rowRange == Range::all())\r
rows = m.rows;\r
else\r
{\r
- CV_Assert(0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows);\r
+ CV_Assert(0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows);\r
\r
- rows = rowRange.size();\r
- data += step*rowRange.start;\r
+ rows = _rowRange.size();\r
+ data += step*_rowRange.start;\r
}\r
\r
- if (colRange == Range::all())\r
+ if (_colRange == Range::all())\r
cols = m.cols;\r
else\r
{\r
- CV_Assert(0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols);\r
+ CV_Assert(0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols);\r
\r
- cols = colRange.size();\r
- data += colRange.start*elemSize();\r
+ cols = _colRange.size();\r
+ data += _colRange.start*elemSize();\r
flags &= cols < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;\r
}\r
\r
for( ; size.height--; src += src_step, dst += dst_step )
{
- j=0;
+ j=0;
#if CV_ENABLE_UNROLLED
for( ; j <= size.width - 4; j += 4 )
{
for( k = 0; k < n; k++, b_data += b_step )
{
WT al(a_data[k]);
- j=0;
+ j=0;
#if CV_ENABLE_UNROLLED
for(; j <= m - 4; j += 4 )
{
if( _c_data )
{
c_data = _c_data;
- j=0;
- #if CV_ENABLE_UNROLLED
+ j=0;
+ #if CV_ENABLE_UNROLLED
for(; j <= d_size.width - 4; j += 4, c_data += 4*c_step1 )
{
WT t0 = alpha*d_buf[j];
}
else
{
- j = 0;
- #if CV_ENABLE_UNROLLED
+ j = 0;
+ #if CV_ENABLE_UNROLLED
for( ; j <= d_size.width - 4; j += 4 )
{
WT t0 = alpha*d_buf[j];
d_data[j+2] = T(t0);
d_data[j+3] = T(t1);
}
- #endif
+ #endif
for( ; j < d_size.width; j++ )
d_data[j] = T(alpha*d_buf[j]);
}
alpha, beta, flags);
}
-
+
static void GEMMSingleMul_32fc( const Complexf* a_data, size_t a_step,
const Complexf* b_data, size_t b_step,
const Complexf* c_data, size_t c_step,
GEMMSingleMul<Complexd,Complexd>(a_data, a_step, b_data, b_step, c_data,
c_step, d_data, d_step, a_size, d_size,
alpha, beta, flags);
-}
+}
static void GEMMBlockMul_32f( const float* a_data, size_t a_step,
const float* b_data, size_t b_step,
}
void cv::gemm( InputArray matA, InputArray matB, double alpha,
- InputArray matC, double beta, OutputArray matD, int flags )
+ InputArray matC, double beta, OutputArray _matD, int flags )
{
const int block_lin_size = 128;
const int block_size = block_lin_size * block_lin_size;
((flags&GEMM_3_T) != 0 && C.rows == d_size.width && C.cols == d_size.height)));
}
- matD.create( d_size.height, d_size.width, type );
- Mat D = matD.getMat();
+ _matD.create( d_size.height, d_size.width, type );
+ Mat D = _matD.getMat();
if( (flags & GEMM_3_T) != 0 && C.data == D.data )
{
transpose( C, C );
t1 = src1[i+3]*alpha + src2[i+3];
dst[i+2] = t0; dst[i+3] = t1;
}
- for(; i < len; i++ )
+ for(; i < len; i++ )
dst[i] = src1[i]*alpha + src2[i];
}
}
else
#endif
- //vz why do we need unroll here?
+ //vz why do we need unroll here?
for( ; i <= len - 4; i += 4 )
{
double t0, t1;
t1 = src1[i+3]*alpha + src2[i+3];
dst[i+2] = t0; dst[i+3] = t1;
}
- for(; i < len; i++ )
+ for(; i < len; i++ )
dst[i] = src1[i]*alpha + src2[i];
}
float falpha = (float)alpha;
void* palpha = depth == CV_32F ? (void*)&falpha : (void*)α
- ScaleAddFunc func = depth == CV_32F ? (ScaleAddFunc)scaleAdd_32f : (ScaleAddFunc)scaleAdd_64f;
+ ScaleAddFunc func = depth == CV_32F ? (ScaleAddFunc)scaleAdd_32f : (ScaleAddFunc)scaleAdd_64f;
if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() )
{
_mean = mean.reshape(1, size.height);
}
-void cv::calcCovarMatrix( InputArray _data, OutputArray _covar, InputOutputArray _mean, int flags, int ctype )
+void cv::calcCovarMatrix( InputArray _src, OutputArray _covar, InputOutputArray _mean, int flags, int ctype )
{
- if(_data.kind() == _InputArray::STD_VECTOR_MAT)
+ if(_src.kind() == _InputArray::STD_VECTOR_MAT)
{
std::vector<cv::Mat> src;
- _data.getMatVector(src);
+ _src.getMatVector(src);
CV_Assert( src.size() > 0 );
return;
}
- Mat data = _data.getMat(), mean;
+ Mat data = _src.getMat(), mean;
CV_Assert( ((flags & CV_COVAR_ROWS) != 0) ^ ((flags & CV_COVAR_COLS) != 0) );
bool takeRows = (flags & CV_COVAR_ROWS) != 0;
int type = data.type();
else
{
ctype = std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), CV_32F);
- reduce( _data, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype );
+ reduce( _src, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype );
mean = _mean.getMat();
}
double cv::Mahalanobis( InputArray _v1, InputArray _v2, InputArray _icovar )
{
- Mat v1 = _v1.getMat(), v2 = _v2.getMat(), icovar = _icovar.getMat();
+ Mat v1 = _v1.getMat(), v2 = _v2.getMat(), icovar = _icovar.getMat();
int type = v1.type(), depth = v1.depth();
Size sz = v1.size();
int i, j, len = sz.width*sz.height*v1.channels();
{
double row_sum = 0;
j = 0;
- #if CV_ENABLE_UNROLLED
+ #if CV_ENABLE_UNROLLED
for(; j <= len - 4; j += 4 )
row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] +
diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3];
{
double row_sum = 0;
j = 0;
- #if CV_ENABLE_UNROLLED
+ #if CV_ENABLE_UNROLLED
for(; j <= len - 4; j += 4 )
row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] +
diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3];
{
int i = 0;
double result = 0;
- #if CV_ENABLE_UNROLLED
+ #if CV_ENABLE_UNROLLED
for( ; i <= len - 4; i += 4 )
result += (double)src1[i]*src2[i] + (double)src1[i+1]*src2[i+1] +
(double)src1[i+2]*src2[i+2] + (double)src1[i+3]*src2[i+3];
{
blockSize = std::min(len0 - i, blockSize0);
__m128i s = _mm_setzero_si128();
- j = 0;
+ j = 0;
for( ; j <= blockSize - 16; j += 16 )
{
__m128i b0 = _mm_loadu_si128((const __m128i*)(src1 + j));
PCA::PCA() {}
-PCA::PCA(InputArray data, InputArray mean, int flags, int maxComponents)
+PCA::PCA(InputArray data, InputArray _mean, int flags, int maxComponents)
{
- operator()(data, mean, flags, maxComponents);
+ operator()(data, _mean, flags, maxComponents);
}
PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComponents)
pca.mean.copyTo(mean);
pca.eigenvectors.copyTo(eigenvectors);
}
-
+
void cv::PCAProject(InputArray data, InputArray mean,
InputArray eigenvectors, OutputArray result)
{
bool elementWise(const MatExpr& /*expr*/) const { return true; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
static void makeExpr(MatExpr& res, const Mat& m);
};
static MatOp_Identity g_MatOp_Identity;
-
+
class MatOp_AddEx : public MatOp
{
public:
MatOp_AddEx() {}
virtual ~MatOp_AddEx() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return true; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const;
void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
void multiply(const MatExpr& e1, double s, MatExpr& res) const;
void divide(double s, const MatExpr& e, MatExpr& res) const;
-
+
void transpose(const MatExpr& e1, MatExpr& res) const;
void abs(const MatExpr& expr, MatExpr& res) const;
-
+
static void makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s=Scalar());
};
static MatOp_AddEx g_MatOp_AddEx;
-
+
class MatOp_Bin : public MatOp
{
public:
MatOp_Bin() {}
virtual ~MatOp_Bin() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return true; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
void multiply(const MatExpr& e1, double s, MatExpr& res) const;
void divide(double s, const MatExpr& e, MatExpr& res) const;
-
+
static void makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale=1);
static void makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s);
};
static MatOp_Bin g_MatOp_Bin;
-
+
class MatOp_Cmp : public MatOp
{
public:
MatOp_Cmp() {}
virtual ~MatOp_Cmp() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return true; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
static void makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b);
static void makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha);
};
-
+
static MatOp_Cmp g_MatOp_Cmp;
-
+
class MatOp_GEMM : public MatOp
{
public:
MatOp_GEMM() {}
virtual ~MatOp_GEMM() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return false; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const;
void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const;
void multiply(const MatExpr& e, double s, MatExpr& res) const;
-
+
void transpose(const MatExpr& expr, MatExpr& res) const;
-
+
static void makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b,
double alpha=1, const Mat& c=Mat(), double beta=1);
};
public:
MatOp_Invert() {}
virtual ~MatOp_Invert() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return false; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
-
+
static void makeExpr(MatExpr& res, int method, const Mat& m);
-};
+};
static MatOp_Invert g_MatOp_Invert;
public:
MatOp_T() {}
virtual ~MatOp_T() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return false; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
void multiply(const MatExpr& e1, double s, MatExpr& res) const;
void transpose(const MatExpr& expr, MatExpr& res) const;
-
+
static void makeExpr(MatExpr& res, const Mat& a, double alpha=1);
};
public:
MatOp_Solve() {}
virtual ~MatOp_Solve() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return false; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
static void makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b);
};
public:
MatOp_Initializer() {}
virtual ~MatOp_Initializer() {}
-
+
bool elementWise(const MatExpr& /*expr*/) const { return false; }
void assign(const MatExpr& expr, Mat& m, int type=-1) const;
-
+
void multiply(const MatExpr& e, double s, MatExpr& res) const;
-
+
static void makeExpr(MatExpr& res, int method, Size sz, int type, double alpha=1);
};
static MatOp_Initializer g_MatOp_Initializer;
-
+
static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; }
static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; }
static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); }
static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; }
static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); }
static inline bool isInitializer(const MatExpr& e) { return e.op == &g_MatOp_Initializer; }
-
+
/////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
bool MatOp::elementWise(const MatExpr& /*expr*/) const
{
return false;
}
-
+
void MatOp::roi(const MatExpr& expr, const Range& rowRange, const Range& colRange, MatExpr& e) const
{
if( elementWise(expr) )
e = MatExpr(&g_MatOp_Identity, 0, m(rowRange, colRange), Mat(), Mat());
}
}
-
+
void MatOp::diag(const MatExpr& expr, int d, MatExpr& e) const
{
if( elementWise(expr) )
}
}
-
+
void MatOp::augAssignAdd(const MatExpr& expr, Mat& m) const
{
Mat temp;
m += temp;
}
-
+
void MatOp::augAssignSubtract(const MatExpr& expr, Mat& m) const
{
Mat temp;
m -= temp;
}
-
+
void MatOp::augAssignMultiply(const MatExpr& expr, Mat& m) const
{
Mat temp;
m *= temp;
}
-
+
void MatOp::augAssignDivide(const MatExpr& expr, Mat& m) const
{
Mat temp;
expr.op->assign(expr, temp);
m /= temp;
}
-
-
+
+
void MatOp::augAssignAnd(const MatExpr& expr, Mat& m) const
{
Mat temp;
m &= temp;
}
-
+
void MatOp::augAssignOr(const MatExpr& expr, Mat& m) const
{
Mat temp;
m |= temp;
}
-
+
void MatOp::augAssignXor(const MatExpr& expr, Mat& m) const
{
Mat temp;
expr.op->assign(expr, temp);
m /= temp;
}
-
+
void MatOp::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
{
}
else
e1.op->assign(e1, m1);
-
+
if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) )
{
m2 = e2.a;
beta = e2.alpha;
s += e2.s;
- }
+ }
else
e2.op->assign(e2, m2);
MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s);
e2.op->add(e1, e2, res);
}
-
+
void MatOp::add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const
{
Mat m1;
MatOp_AddEx::makeExpr(res, m1, Mat(), 1, 0, s);
}
-
+
void MatOp::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
{
if( this == e2.op )
}
else
e1.op->assign(e1, m1);
-
+
if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) )
{
m2 = e2.a;
beta = -e2.alpha;
s -= e2.s;
- }
+ }
else
e2.op->assign(e2, m2);
MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s);
e2.op->subtract(e1, e2, res);
}
-
+
void MatOp::subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const
{
Mat m;
MatOp_AddEx::makeExpr(res, m, Mat(), -1, 0, s);
}
-
+
void MatOp::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const
{
if( this == e2.op )
{
Mat m1, m2;
-
+
if( isReciprocal(e1) )
{
if( isScaled(e2) )
}
else
e1.op->assign(e1, m1);
-
+
if( isScaled(e2) )
{
m2 = e2.a;
}
else
e2.op->assign(e2, m2);
-
+
MatOp_Bin::makeExpr(res, op, m1, m2, scale);
}
}
else
e2.op->multiply(e1, e2, res, scale);
}
-
-
+
+
void MatOp::multiply(const MatExpr& expr, double s, MatExpr& res) const
{
Mat m;
expr.op->assign(expr, m);
- MatOp_AddEx::makeExpr(res, m, Mat(), s, 0);
+ MatOp_AddEx::makeExpr(res, m, Mat(), s, 0);
}
-
-
+
+
void MatOp::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const
{
if( this == e2.op )
{
Mat m1, m2;
char op = '/';
-
+
if( isScaled(e1) )
{
m1 = e1.a;
}
else
e1.op->assign(e1, m1);
-
+
if( isScaled(e2) )
{
m2 = e2.a;
e2.op->divide(e1, e2, res, scale);
}
-
+
void MatOp::divide(double s, const MatExpr& expr, MatExpr& res) const
{
Mat m;
MatOp_Bin::makeExpr(res, '/', m, Mat(), s);
}
-
+
void MatOp::abs(const MatExpr& expr, MatExpr& res) const
{
Mat m;
MatOp_Bin::makeExpr(res, 'a', m, Mat());
}
-
+
void MatOp::transpose(const MatExpr& expr, MatExpr& res) const
{
Mat m;
MatOp_T::makeExpr(res, m, 1);
}
-
+
void MatOp::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
{
if( this == e2.op )
double scale = 1;
int flags = 0;
Mat m1, m2;
-
+
if( isT(e1) )
{
flags = CV_GEMM_A_T;
}
else
e1.op->assign(e1, m1);
-
+
if( isT(e2) )
{
flags |= CV_GEMM_B_T;
}
else
e2.op->assign(e2, m2);
-
+
MatOp_GEMM::makeExpr(res, flags, m1, m2, scale);
}
else
e2.op->matmul(e1, e2, res);
}
-
+
void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const
{
Mat m;
expr.op->assign(expr, m);
MatOp_Invert::makeExpr(res, method, m);
}
-
-
+
+
Size MatOp::size(const MatExpr& expr) const
{
return !expr.a.empty() ? expr.a.size() : expr.b.empty() ? expr.b.size() : expr.c.size();
int MatOp::type(const MatExpr& expr) const
{
return !expr.a.empty() ? expr.a.type() : expr.b.empty() ? expr.b.type() : expr.c.type();
-}
-
+}
+
//////////////////////////////////////////////////////////////////////////////////////////////////
MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar())
{
}
-
+
MatExpr MatExpr::row(int y) const
{
MatExpr e;
MatOp_AddEx::makeExpr(e, a, b, 1, 1);
return e;
}
-
+
MatExpr operator + (const Mat& a, const Scalar& s)
{
MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
return e;
}
-
+
MatExpr operator + (const Scalar& s, const Mat& a)
{
MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
return e;
-}
-
+}
+
MatExpr operator + (const MatExpr& e, const Mat& m)
{
MatExpr en;
e.op->add(e, MatExpr(m), en);
return en;
}
-
+
MatExpr operator + (const Mat& m, const MatExpr& e)
{
MatExpr en;
e.op->add(e, MatExpr(m), en);
return en;
-}
-
+}
+
MatExpr operator + (const MatExpr& e, const Scalar& s)
{
MatExpr en;
e.op->add(e, s, en);
return en;
}
-
+
MatExpr operator + (const Scalar& s, const MatExpr& e)
{
MatExpr en;
MatOp_AddEx::makeExpr(e, a, b, 1, -1);
return e;
}
-
+
MatExpr operator - (const Mat& a, const Scalar& s)
{
MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s);
return e;
}
-
+
MatExpr operator - (const Scalar& s, const Mat& a)
{
MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s);
return e;
}
-
+
MatExpr operator - (const MatExpr& e, const Mat& m)
{
MatExpr en;
e.op->subtract(e, MatExpr(m), en);
return en;
}
-
+
MatExpr operator - (const Mat& m, const MatExpr& e)
{
MatExpr en;
e.op->subtract(MatExpr(m), e, en);
return en;
}
-
+
MatExpr operator - (const MatExpr& e, const Scalar& s)
{
MatExpr en;
e.op->add(e, -s, en);
return en;
}
-
+
MatExpr operator - (const Scalar& s, const MatExpr& e)
{
MatExpr en;
e.op->subtract(s, e, en);
return en;
}
-
+
MatExpr operator - (const MatExpr& e1, const MatExpr& e2)
{
MatExpr en;
MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0);
return e;
}
-
+
MatExpr operator - (const MatExpr& e)
{
MatExpr en;
MatOp_Bin::makeExpr(e, '/', a, b);
return e;
}
-
+
MatExpr operator / (const Mat& a, double s)
{
MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0);
return e;
}
-
+
MatExpr operator / (double s, const Mat& a)
{
MatExpr e;
MatOp_Bin::makeExpr(e, '/', a, Mat(), s);
return e;
}
-
+
MatExpr operator / (const MatExpr& e, const Mat& m)
{
MatExpr en;
e.op->divide(e, MatExpr(m), en);
return en;
}
-
+
MatExpr operator / (const Mat& m, const MatExpr& e)
{
MatExpr en;
e.op->divide(MatExpr(m), e, en);
return en;
}
-
+
MatExpr operator / (const MatExpr& e, double s)
{
MatExpr en;
e.op->multiply(e, 1./s, en);
return en;
}
-
+
MatExpr operator / (double s, const MatExpr& e)
{
MatExpr en;
e.op->divide(s, e, en);
return en;
}
-
+
MatExpr operator / (const MatExpr& e1, const MatExpr& e2)
{
MatExpr en;
MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b);
return e;
}
-
+
MatExpr operator < (const Mat& a, double s)
{
MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
return e;
}
-
+
MatExpr operator < (double s, const Mat& a)
{
MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s);
return e;
}
-
+
MatExpr operator >= (const Mat& a, const Mat& b)
{
MatExpr e;
MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
return e;
-}
-
+}
+
MatExpr min(const Mat& a, const Mat& b)
{
MatExpr e;
MatOp_Bin::makeExpr(e, 'm', a, b);
return e;
}
-
+
MatExpr min(const Mat& a, double s)
{
MatExpr e;
MatOp_Bin::makeExpr(e, 'm', a, s);
return e;
}
-
+
MatExpr min(double s, const Mat& a)
{
MatExpr e;
MatOp_Bin::makeExpr(e, 'M', a, b);
return e;
}
-
+
MatExpr max(const Mat& a, double s)
{
MatExpr e;
MatOp_Bin::makeExpr(e, 'M', a, s);
return e;
}
-
+
MatExpr max(double s, const Mat& a)
{
MatExpr e;
MatOp_Bin::makeExpr(e, '&', a, b);
return e;
}
-
+
MatExpr operator & (const Mat& a, const Scalar& s)
{
MatExpr e;
MatOp_Bin::makeExpr(e, '&', a, s);
return e;
}
-
+
MatExpr operator & (const Scalar& s, const Mat& a)
{
MatExpr e;
MatOp_Bin::makeExpr(e, '&', a, s);
return e;
}
-
+
MatExpr operator | (const Mat& a, const Mat& b)
{
MatExpr e;
MatOp_Bin::makeExpr(e, '|', a, b);
return e;
}
-
+
MatExpr operator | (const Mat& a, const Scalar& s)
{
MatExpr e;
MatOp_Bin::makeExpr(e, '|', a, s);
return e;
}
-
+
MatExpr operator | (const Scalar& s, const Mat& a)
{
MatExpr e;
return en;
}
-
+
Size MatExpr::size() const
{
if( isT(*this) || isInv(*this) )
return a.size();
return op ? op->size(*this) : Size();
}
-
-
+
+
int MatExpr::type() const
{
if( isInitializer(*this) )
return CV_8U;
return op ? op->type(*this) : -1;
}
-
-
+
+
/////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_Identity::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_Identity::assign(const MatExpr& e, Mat& m, int _type) const
{
- if( type == -1 || type == e.a.type() )
+ if( _type == -1 || _type == e.a.type() )
m = e.a;
else
{
- CV_Assert( CV_MAT_CN(type) == e.a.channels() );
- e.a.convertTo(m, type);
+ CV_Assert( CV_MAT_CN(_type) == e.a.channels() );
+ e.a.convertTo(m, _type);
}
}
inline void MatOp_Identity::makeExpr(MatExpr& res, const Mat& m)
{
res = MatExpr(&g_MatOp_Identity, 0, m, Mat(), Mat(), 1, 0);
-}
-
+}
+
/////////////////////////////////////////////////////////////////////////////////////////////////////
-void MatOp_AddEx::assign(const MatExpr& e, Mat& m, int type) const
-{
- Mat temp, &dst = type == -1 || e.a.type() == type ? m : temp;
+void MatOp_AddEx::assign(const MatExpr& e, Mat& m, int _type) const
+{
+ Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp;
if( e.b.data )
{
if( e.s == Scalar() || !e.s.isReal() )
}
else
cv::addWeighted(e.a, e.alpha, e.b, e.beta, 0, dst);
-
+
if( !e.s.isReal() )
cv::add(dst, e.s, dst);
}
}
else if( e.s.isReal() && (dst.data != m.data || fabs(e.alpha) != 1))
{
- e.a.convertTo(m, type, e.alpha, e.s[0]);
+ e.a.convertTo(m, _type, e.alpha, e.s[0]);
return;
}
else if( e.alpha == 1 )
e.a.convertTo(dst, e.a.type(), e.alpha);
cv::add(dst, e.s, dst);
}
-
+
if( dst.data != m.data )
dst.convertTo(m, m.type());
}
-
+
void MatOp_AddEx::add(const MatExpr& e, const Scalar& s, MatExpr& res) const
{
res = e;
res.s += s;
}
-
+
void MatOp_AddEx::subtract(const Scalar& s, const MatExpr& e, MatExpr& res) const
{
res = e;
res.beta = -res.beta;
res.s = s - res.s;
}
-
+
void MatOp_AddEx::multiply(const MatExpr& e, double s, MatExpr& res) const
{
res = e;
res.beta *= s;
res.s *= s;
}
-
+
void MatOp_AddEx::divide(double s, const MatExpr& e, MatExpr& res) const
{
if( isScaled(e) )
else
MatOp::transpose(e, res);
}
-
+
void MatOp_AddEx::abs(const MatExpr& e, MatExpr& res) const
{
if( (!e.b.data || e.beta == 0) && fabs(e.alpha) == 1 )
else
MatOp::abs(e, res);
}
-
+
inline void MatOp_AddEx::makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s)
{
res = MatExpr(&g_MatOp_AddEx, 0, a, b, Mat(), alpha, beta, s);
}
-
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_Bin::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_Bin::assign(const MatExpr& e, Mat& m, int _type) const
{
- Mat temp, &dst = type == -1 || e.a.type() == type ? m : temp;
-
+ Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp;
+
if( e.flags == '*' )
cv::multiply(e.a, e.b, dst, e.alpha);
else if( e.flags == '/' && e.b.data )
cv::absdiff(e.a, e.s, dst);
else
CV_Error(CV_StsError, "Unknown operation");
-
+
if( dst.data != m.data )
- dst.convertTo(m, type);
+ dst.convertTo(m, _type);
}
void MatOp_Bin::multiply(const MatExpr& e, double s, MatExpr& res) const
{
res = MatExpr(&g_MatOp_Bin, op, a, Mat(), Mat(), 1, 0, s);
}
-
+
///////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_Cmp::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_Cmp::assign(const MatExpr& e, Mat& m, int _type) const
{
- Mat temp, &dst = type == -1 || type == CV_8U ? m : temp;
-
+ Mat temp, &dst = _type == -1 || _type == CV_8U ? m : temp;
+
if( e.b.data )
cv::compare(e.a, e.b, dst, e.flags);
else
cv::compare(e.a, e.alpha, dst, e.flags);
-
+
if( dst.data != m.data )
- dst.convertTo(m, type);
+ dst.convertTo(m, _type);
}
inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b)
{
res = MatExpr(&g_MatOp_Cmp, cmpop, a, b, Mat(), 1, 1);
}
-
+
inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha)
{
res = MatExpr(&g_MatOp_Cmp, cmpop, a, Mat(), Mat(), alpha, 1);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_T::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_T::assign(const MatExpr& e, Mat& m, int _type) const
{
- Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp;
-
+ Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
+
cv::transpose(e.a, dst);
-
+
if( dst.data != m.data || e.alpha != 1 )
- dst.convertTo(m, type, e.alpha);
+ dst.convertTo(m, _type, e.alpha);
}
void MatOp_T::multiply(const MatExpr& e, double s, MatExpr& res) const
res = e;
res.alpha *= s;
}
-
+
void MatOp_T::transpose(const MatExpr& e, MatExpr& res) const
{
if( e.alpha == 1 )
else
MatOp_AddEx::makeExpr(res, e.a, Mat(), e.alpha, 0);
}
-
+
inline void MatOp_T::makeExpr(MatExpr& res, const Mat& a, double alpha)
{
res = MatExpr(&g_MatOp_T, 0, a, Mat(), Mat(), alpha, 0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_GEMM::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_GEMM::assign(const MatExpr& e, Mat& m, int _type) const
{
- Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp;
-
+ Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
+
cv::gemm(e.a, e.b, e.alpha, e.c, e.beta, dst, e.flags);
if( dst.data != m.data )
- dst.convertTo(m, type);
+ dst.convertTo(m, _type);
}
void MatOp_GEMM::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
{
bool i1 = isIdentity(e1), i2 = isIdentity(e2);
double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha;
-
+
if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) )
MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0),
e1.a, e1.b, alpha1, e2.a, alpha2);
else
e2.op->add(e1, e2, res);
}
-
+
void MatOp_GEMM::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
{
bool i1 = isIdentity(e1), i2 = isIdentity(e2);
double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha;
-
+
if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) )
MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0),
e1.a, e1.b, alpha1, e2.a, -alpha2);
res.alpha *= s;
res.beta *= s;
}
-
+
void MatOp_GEMM::transpose(const MatExpr& e, MatExpr& res) const
{
res = e;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_Invert::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_Invert::assign(const MatExpr& e, Mat& m, int _type) const
{
- Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp;
-
+ Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
+
cv::invert(e.a, dst, e.flags);
if( dst.data != m.data )
- dst.convertTo(m, type);
+ dst.convertTo(m, _type);
}
void MatOp_Invert::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_Solve::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_Solve::assign(const MatExpr& e, Mat& m, int _type) const
{
- Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp;
-
+ Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
+
cv::solve(e.a, e.b, dst, e.flags);
if( dst.data != m.data )
- dst.convertTo(m, type);
+ dst.convertTo(m, _type);
}
inline void MatOp_Solve::makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b)
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int type) const
+
+void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const
{
- if( type == -1 )
- type = e.a.type();
- m.create(e.a.size(), type);
+ if( _type == -1 )
+ _type = e.a.type();
+ m.create(e.a.size(), _type);
if( e.flags == 'I' )
setIdentity(m, Scalar(e.alpha));
else if( e.flags == '0' )
res = e;
res.alpha *= s;
}
-
+
inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, Size sz, int type, double alpha)
{
res = MatExpr(&g_MatOp_Initializer, method, Mat(sz, type, (void*)0), Mat(), Mat(), alpha, 0);
-}
+}
+
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////
MatExpr Mat::t() const
MatOp_T::makeExpr(e, *this);
return e;
}
-
+
MatExpr Mat::inv(int method) const
{
MatExpr e;
MatOp_Invert::makeExpr(e, method, *this);
return e;
}
-
+
MatExpr Mat::mul(InputArray m, double scale) const
{
MatOp_Initializer::makeExpr(e, '0', Size(cols, rows), type);
return e;
}
-
+
MatExpr Mat::zeros(Size size, int type)
{
MatExpr e;
MatOp_Initializer::makeExpr(e, '0', size, type);
return e;
}
-
+
MatExpr Mat::ones(int rows, int cols, int type)
{
MatExpr e;
MatOp_Initializer::makeExpr(e, '1', Size(cols, rows), type);
return e;
}
-
+
MatExpr Mat::ones(Size size, int type)
{
MatExpr e;
MatOp_Initializer::makeExpr(e, 'I', size, type);
return e;
}
-
+
}
/* End of file. */
#endif
if( !allocator )
{
- size_t total = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount));
- data = datastart = (uchar*)fastMalloc(total + (int)sizeof(*refcount));
- refcount = (int*)(data + total);
+ size_t totalsize = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount));
+ data = datastart = (uchar*)fastMalloc(totalsize + (int)sizeof(*refcount));
+ refcount = (int*)(data + totalsize);
*refcount = 1;
}
else
}
-Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange) : size(&rows)
+Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange) : size(&rows)
{
initEmpty();
CV_Assert( m.dims >= 2 );
if( m.dims > 2 )
{
AutoBuffer<Range> rs(m.dims);
- rs[0] = rowRange;
- rs[1] = colRange;
+ rs[0] = _rowRange;
+ rs[1] = _colRange;
for( int i = 2; i < m.dims; i++ )
rs[i] = Range::all();
*this = m(rs);
}
*this = m;
- if( rowRange != Range::all() && rowRange != Range(0,rows) )
+ if( _rowRange != Range::all() && _rowRange != Range(0,rows) )
{
- CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
- rows = rowRange.size();
- data += step*rowRange.start;
+ CV_Assert( 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows );
+ rows = _rowRange.size();
+ data += step*_rowRange.start;
flags |= SUBMATRIX_FLAG;
}
- if( colRange != Range::all() && colRange != Range(0,cols) )
+ if( _colRange != Range::all() && _colRange != Range(0,cols) )
{
- CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
- cols = colRange.size();
- data += colRange.start*elemSize();
+ CV_Assert( 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols );
+ cols = _colRange.size();
+ data += _colRange.start*elemSize();
flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
flags |= SUBMATRIX_FLAG;
}
dims = 2;
CV_DbgAssert(CV_IS_IMAGE(img) && img->imageData != 0);
- int depth = IPL2CV_DEPTH(img->depth);
+ int imgdepth = IPL2CV_DEPTH(img->depth);
size_t esz;
step[0] = img->widthStep;
if(!img->roi)
{
CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL);
- flags = MAGIC_VAL + CV_MAKETYPE(depth, img->nChannels);
+ flags = MAGIC_VAL + CV_MAKETYPE(imgdepth, img->nChannels);
rows = img->height; cols = img->width;
datastart = data = (uchar*)img->imageData;
esz = CV_ELEM_SIZE(flags);
{
CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL || img->roi->coi != 0);
bool selectedPlane = img->roi->coi && img->dataOrder == IPL_DATA_ORDER_PLANE;
- flags = MAGIC_VAL + CV_MAKETYPE(depth, selectedPlane ? 1 : img->nChannels);
+ flags = MAGIC_VAL + CV_MAKETYPE(imgdepth, selectedPlane ? 1 : img->nChannels);
rows = img->roi->height; cols = img->roi->width;
esz = CV_ELEM_SIZE(flags);
data = datastart = (uchar*)img->imageData +
return (flags & FIXED_TYPE) == FIXED_TYPE;
}
-void _OutputArray::create(Size _sz, int type, int i, bool allowTransposed, int fixedDepthMask) const
+void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
{
int k = kind();
if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{
CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == _sz);
- CV_Assert(!fixedType() || ((Mat*)obj)->type() == type);
- ((Mat*)obj)->create(_sz, type);
+ CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype);
+ ((Mat*)obj)->create(_sz, mtype);
return;
}
- int sz[] = {_sz.height, _sz.width};
- create(2, sz, type, i, allowTransposed, fixedDepthMask);
+ int sizes[] = {_sz.height, _sz.width};
+ create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
}
-void _OutputArray::create(int rows, int cols, int type, int i, bool allowTransposed, int fixedDepthMask) const
+void _OutputArray::create(int rows, int cols, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
{
int k = kind();
if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{
CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(cols, rows));
- CV_Assert(!fixedType() || ((Mat*)obj)->type() == type);
- ((Mat*)obj)->create(rows, cols, type);
+ CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype);
+ ((Mat*)obj)->create(rows, cols, mtype);
return;
}
- int sz[] = {rows, cols};
- create(2, sz, type, i, allowTransposed, fixedDepthMask);
+ int sizes[] = {rows, cols};
+ create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
}
-void _OutputArray::create(int dims, const int* size, int type, int i, bool allowTransposed, int fixedDepthMask) const
+void _OutputArray::create(int dims, const int* sizes, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
{
int k = kind();
- type = CV_MAT_TYPE(type);
+ mtype = CV_MAT_TYPE(mtype);
if( k == MAT )
{
}
if( dims == 2 && m.dims == 2 && m.data &&
- m.type() == type && m.rows == size[1] && m.cols == size[0] )
+ m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
return;
}
if(fixedType())
{
- if(CV_MAT_CN(type) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
- type = m.type();
+ if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
+ mtype = m.type();
else
- CV_Assert(CV_MAT_TYPE(type) == m.type());
+ CV_Assert(CV_MAT_TYPE(mtype) == m.type());
}
if(fixedSize())
{
CV_Assert(m.dims == dims);
for(int j = 0; j < dims; ++j)
- CV_Assert(m.size[j] == size[j]);
+ CV_Assert(m.size[j] == sizes[j]);
}
- m.create(dims, size, type);
+ m.create(dims, sizes, mtype);
return;
}
{
CV_Assert( i < 0 );
int type0 = CV_MAT_TYPE(flags);
- CV_Assert( type == type0 || (CV_MAT_CN(type) == 1 && ((1 << type0) & fixedDepthMask) != 0) );
- CV_Assert( dims == 2 && ((size[0] == sz.height && size[1] == sz.width) ||
- (allowTransposed && size[0] == sz.width && size[1] == sz.height)));
+ CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == 1 && ((1 << type0) & fixedDepthMask) != 0) );
+ CV_Assert( dims == 2 && ((sizes[0] == sz.height && sizes[1] == sz.width) ||
+ (allowTransposed && sizes[0] == sz.width && sizes[1] == sz.height)));
return;
}
if( k == STD_VECTOR || k == STD_VECTOR_VECTOR )
{
- CV_Assert( dims == 2 && (size[0] == 1 || size[1] == 1 || size[0]*size[1] == 0) );
- size_t len = size[0]*size[1] > 0 ? size[0] + size[1] - 1 : 0;
+ CV_Assert( dims == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
+ size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0;
vector<uchar>* v = (vector<uchar>*)obj;
if( k == STD_VECTOR_VECTOR )
CV_Assert( i < 0 );
int type0 = CV_MAT_TYPE(flags);
- CV_Assert( type == type0 || (CV_MAT_CN(type) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) );
+ CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) );
int esz = CV_ELEM_SIZE(type0);
CV_Assert(!fixedSize() || len == ((vector<uchar>*)v)->size() / esz);
if( i < 0 )
{
- CV_Assert( dims == 2 && (size[0] == 1 || size[1] == 1 || size[0]*size[1] == 0) );
- size_t len = size[0]*size[1] > 0 ? size[0] + size[1] - 1 : 0, len0 = v.size();
+ CV_Assert( dims == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
+ size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = v.size();
CV_Assert(!fixedSize() || len == len0);
v.resize(len);
if( fixedType() )
{
- int type = CV_MAT_TYPE(flags);
+ int _type = CV_MAT_TYPE(flags);
for( size_t j = len0; j < len; j++ )
{
- if( v[i].type() == type )
+ if( v[i].type() == _type )
continue;
CV_Assert( v[i].empty() );
- v[i].flags = (v[i].flags & ~CV_MAT_TYPE_MASK) | type;
+ v[i].flags = (v[i].flags & ~CV_MAT_TYPE_MASK) | _type;
}
}
return;
}
if( dims == 2 && m.dims == 2 && m.data &&
- m.type() == type && m.rows == size[1] && m.cols == size[0] )
+ m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
return;
}
if(fixedType())
{
- if(CV_MAT_CN(type) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
- type = m.type();
+ if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
+ mtype = m.type();
else
- CV_Assert(!fixedType() || (CV_MAT_CN(type) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0));
+ CV_Assert(!fixedType() || (CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0));
}
if(fixedSize())
{
CV_Assert(m.dims == dims);
for(int j = 0; j < dims; ++j)
- CV_Assert(m.size[j] == size[j]);
+ CV_Assert(m.size[j] == sizes[j]);
}
- m.create(dims, size, type);
+ m.create(dims, sizes, mtype);
}
}
cv::Mat cv::Mat::cross(InputArray _m) const
{
Mat m = _m.getMat();
- int t = type(), d = CV_MAT_DEPTH(t);
- CV_Assert( dims <= 2 && m.dims <= 2 && size() == m.size() && t == m.type() &&
+ int tp = type(), d = CV_MAT_DEPTH(tp);
+ CV_Assert( dims <= 2 && m.dims <= 2 && size() == m.size() && tp == m.type() &&
((rows == 3 && cols == 1) || (cols*channels() == 3 && rows == 1)));
- Mat result(rows, cols, t);
+ Mat result(rows, cols, tp);
if( d == CV_32F )
{
CV_IMPL void
cvSort( const CvArr* _src, CvArr* _dst, CvArr* _idx, int flags )
{
- cv::Mat src = cv::cvarrToMat(_src), dst, idx;
+ cv::Mat src = cv::cvarrToMat(_src);
if( _idx )
{
int i, idx[CV_MAX_DIM] = {0}, d = m.dims, lastSize = m.size[d - 1];
size_t esz = m.elemSize();
- uchar* ptr = m.data;
+ uchar* dptr = m.data;
for(;;)
{
- for( i = 0; i < lastSize; i++, ptr += esz )
+ for( i = 0; i < lastSize; i++, dptr += esz )
{
- if( isZeroElem(ptr, esz) )
+ if( isZeroElem(dptr, esz) )
continue;
idx[d-1] = i;
uchar* to = newNode(idx, hash(idx));
- copyElem( ptr, to, esz );
+ copyElem( dptr, to, esz );
}
for( i = d - 2; i >= 0; i-- )
{
- ptr += m.step[i] - m.size[i+1]*m.step[i+1];
+ dptr += m.step[i] - m.size[i+1]*m.step[i+1];
if( ++idx[i] < m.size[i] )
break;
idx[i] = 0;
void cv::gpu::setGlDevice(int device)\r
{\r
#ifndef HAVE_CUDA\r
- (void)device;\r
+ (void)device;\r
throw_nocuda;\r
#else\r
#ifndef HAVE_OPENGL\r
- (void)device;\r
+ (void)device;\r
throw_nogl;\r
#else\r
if (!glFuncTab()->isGlContextInitialized())\r
{\r
public:\r
static const Ptr<Impl>& empty();\r
- \r
+\r
Impl(int rows, int cols, int type, unsigned int target);\r
Impl(const Mat& m, unsigned int target);\r
~Impl();\r
\r
private:\r
Impl();\r
- \r
+\r
unsigned int buffer_;\r
\r
#ifdef HAVE_CUDA\r
\r
#endif // HAVE_OPENGL\r
\r
-cv::GlBuffer::GlBuffer(Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::GlBuffer::GlBuffer(Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)usage;\r
+ (void)_usage;\r
throw_nogl;\r
#else\r
impl_ = Impl::empty();\r
#endif\r
}\r
\r
-cv::GlBuffer::GlBuffer(int rows, int cols, int type, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::GlBuffer::GlBuffer(int _rows, int _cols, int _type, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)rows;\r
- (void)cols;\r
- (void)type;\r
- (void)usage;\r
+ (void)_rows;\r
+ (void)_cols;\r
+ (void)_type;\r
+ (void)_usage;\r
throw_nogl;\r
#else\r
- impl_ = new Impl(rows, cols, type, usage);\r
- rows_ = rows;\r
- cols_ = cols;\r
- type_ = type;\r
+ impl_ = new Impl(_rows, _cols, _type, _usage);\r
+ rows_ = _rows;\r
+ cols_ = _cols;\r
+ type_ = _type;\r
#endif\r
}\r
\r
-cv::GlBuffer::GlBuffer(Size size, int type, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::GlBuffer::GlBuffer(Size _size, int _type, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)size;\r
- (void)type;\r
- (void)usage;\r
+ (void)_size;\r
+ (void)_type;\r
+ (void)_usage;\r
throw_nogl;\r
#else\r
- impl_ = new Impl(size.height, size.width, type, usage);\r
- rows_ = size.height;\r
- cols_ = size.width;\r
- type_ = type;\r
+ impl_ = new Impl(_size.height, _size.width, _type, _usage);\r
+ rows_ = _size.height;\r
+ cols_ = _size.width;\r
+ type_ = _type;\r
#endif\r
}\r
\r
-cv::GlBuffer::GlBuffer(InputArray mat_, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::GlBuffer::GlBuffer(InputArray mat_, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)mat_;\r
- (void)usage;\r
+ (void)mat_;\r
+ (void)_usage;\r
throw_nogl;\r
#else\r
int kind = mat_.kind();\r
- Size size = mat_.size();\r
- int type = mat_.type();\r
+ Size _size = mat_.size();\r
+ int _type = mat_.type();\r
\r
if (kind == _InputArray::GPU_MAT)\r
{\r
throw_nocuda;\r
#else\r
GpuMat d_mat = mat_.getGpuMat();\r
- impl_ = new Impl(d_mat.rows, d_mat.cols, d_mat.type(), usage);\r
+ impl_ = new Impl(d_mat.rows, d_mat.cols, d_mat.type(), _usage);\r
impl_->copyFrom(d_mat);\r
#endif\r
}\r
else\r
{\r
Mat mat = mat_.getMat();\r
- impl_ = new Impl(mat, usage);\r
+ impl_ = new Impl(mat, _usage);\r
}\r
\r
- rows_ = size.height;\r
- cols_ = size.width;\r
- type_ = type;\r
+ rows_ = _size.height;\r
+ cols_ = _size.width;\r
+ type_ = _type;\r
#endif\r
}\r
\r
-void cv::GlBuffer::create(int rows, int cols, int type, Usage usage)\r
+void cv::GlBuffer::create(int _rows, int _cols, int _type, Usage _usage)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)rows;\r
- (void)cols;\r
- (void)type;\r
- (void)usage;\r
+ (void)_rows;\r
+ (void)_cols;\r
+ (void)_type;\r
+ (void)_usage;\r
throw_nogl;\r
#else\r
- if (rows_ != rows || cols_ != cols || type_ != type || usage_ != usage)\r
+ if (rows_ != _rows || cols_ != _cols || type_ != _type || usage_ != _usage)\r
{\r
- impl_ = new Impl(rows, cols, type, usage);\r
- rows_ = rows;\r
- cols_ = cols;\r
- type_ = type;\r
- usage_ = usage;\r
+ impl_ = new Impl(_rows, _cols, _type, _usage);\r
+ rows_ = _rows;\r
+ cols_ = _cols;\r
+ type_ = _type;\r
+ usage_ = _usage;\r
}\r
#endif\r
}\r
void cv::GlBuffer::copyFrom(InputArray mat_)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)mat_;\r
+ (void)mat_;\r
throw_nogl;\r
#else\r
int kind = mat_.kind();\r
- Size size = mat_.size();\r
- int type = mat_.type();\r
+ Size _size = mat_.size();\r
+ int _type = mat_.type();\r
\r
- create(size, type);\r
+ create(_size, _type);\r
\r
switch (kind)\r
{\r
\r
private:\r
Impl();\r
- \r
+\r
GLuint tex_;\r
};\r
\r
#endif\r
}\r
\r
-cv::GlTexture::GlTexture(int rows, int cols, int type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)\r
+cv::GlTexture::GlTexture(int _rows, int _cols, int _type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)rows;\r
- (void)cols;\r
- (void)type;\r
+ (void)_rows;\r
+ (void)_cols;\r
+ (void)_type;\r
throw_nogl;\r
#else\r
- impl_ = new Impl(rows, cols, type);\r
- rows_ = rows;\r
- cols_ = cols;\r
- type_ = type;\r
+ impl_ = new Impl(_rows, _cols, _type);\r
+ rows_ = _rows;\r
+ cols_ = _cols;\r
+ type_ = _type;\r
#endif\r
}\r
\r
-cv::GlTexture::GlTexture(Size size, int type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)\r
+cv::GlTexture::GlTexture(Size _size, int _type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)size;\r
- (void)type;\r
+ (void)_size;\r
+ (void)_type;\r
throw_nogl;\r
#else\r
- impl_ = new Impl(size.height, size.width, type);\r
- rows_ = size.height;\r
- cols_ = size.width;\r
- type_ = type;\r
+ impl_ = new Impl(_size.height, _size.width, _type);\r
+ rows_ = _size.height;\r
+ cols_ = _size.width;\r
+ type_ = _type;\r
#endif\r
}\r
\r
cv::GlTexture::GlTexture(InputArray mat_, bool bgra) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)mat_;\r
- (void)bgra;\r
+ (void)mat_;\r
+ (void)bgra;\r
throw_nogl;\r
-#else \r
+#else\r
int kind = mat_.kind();\r
- Size size = mat_.size();\r
- int type = mat_.type();\r
+ Size _size = mat_.size();\r
+ int _type = mat_.type();\r
\r
switch (kind)\r
{\r
}\r
}\r
\r
- rows_ = size.height;\r
- cols_ = size.width;\r
- type_ = type;\r
+ rows_ = _size.height;\r
+ cols_ = _size.width;\r
+ type_ = _type;\r
#endif\r
}\r
\r
-void cv::GlTexture::create(int rows, int cols, int type)\r
+void cv::GlTexture::create(int _rows, int _cols, int _type)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)rows;\r
- (void)cols;\r
- (void)type;\r
+ (void)_rows;\r
+ (void)_cols;\r
+ (void)_type;\r
throw_nogl;\r
#else\r
- if (rows_ != rows || cols_ != cols || type_ != type)\r
+ if (rows_ != _rows || cols_ != _cols || type_ != _type)\r
{\r
- impl_ = new Impl(rows, cols, type);\r
- rows_ = rows;\r
- cols_ = cols;\r
- type_ = type;\r
+ impl_ = new Impl(_rows, _cols, _type);\r
+ rows_ = _rows;\r
+ cols_ = _cols;\r
+ type_ = _type;\r
}\r
#endif\r
}\r
void cv::GlTexture::copyFrom(InputArray mat_, bool bgra)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)mat_;\r
- (void)bgra;\r
+ (void)mat_;\r
+ (void)bgra;\r
throw_nogl;\r
#else\r
int kind = mat_.kind();\r
- Size size = mat_.size();\r
- int type = mat_.type();\r
+ Size _size = mat_.size();\r
+ int _type = mat_.type();\r
\r
- create(size, type);\r
+ create(_size, _type);\r
\r
switch(kind)\r
{\r
////////////////////////////////////////////////////////////////////////\r
// GlFont\r
\r
-cv::GlFont::GlFont(const string& family, int height, Weight weight, Style style)\r
- : family_(family), height_(height), weight_(weight), style_(style), base_(0)\r
+cv::GlFont::GlFont(const string& _family, int _height, Weight _weight, Style _style)\r
+ : family_(_family), height_(_height), weight_(_weight), style_(_style), base_(0)\r
{\r
#ifndef HAVE_OPENGL\r
throw_nogl;\r
base_ = glGenLists(256);\r
CV_CheckGlError();\r
\r
- glFuncTab()->generateBitmapFont(family, height, weight, (style & STYLE_ITALIC) != 0, (style & STYLE_UNDERLINE) != 0, 0, 256, base_);\r
+ glFuncTab()->generateBitmapFont(family_, height_, weight_, (style_ & STYLE_ITALIC) != 0, (style_ & STYLE_UNDERLINE) != 0, 0, 256, base_);\r
#endif\r
}\r
\r
class FontCompare : public unary_function<Ptr<GlFont>, bool>\r
{\r
public:\r
- inline FontCompare(const string& family, int height, GlFont::Weight weight, GlFont::Style style) \r
+ inline FontCompare(const string& family, int height, GlFont::Weight weight, GlFont::Style style)\r
: family_(family), height_(height), weight_(weight), style_(style)\r
{\r
}\r
Ptr<GlFont> cv::GlFont::get(const std::string& family, int height, Weight weight, Style style)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)family;\r
- (void)height;\r
- (void)weight;\r
- (void)style;\r
+ (void)family;\r
+ (void)height;\r
+ (void)weight;\r
+ (void)style;\r
throw_nogl;\r
return Ptr<GlFont>();\r
#else\r
void cv::render(const GlTexture& tex, Rect_<double> wndRect, Rect_<double> texRect)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)tex;\r
- (void)wndRect;\r
- (void)texRect;\r
+ (void)tex;\r
+ (void)wndRect;\r
+ (void)texRect;\r
throw_nogl;\r
#else\r
if (!tex.empty())\r
void cv::render(const GlArrays& arr, int mode, Scalar color)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)arr;\r
- (void)mode;\r
- (void)color;\r
+ (void)arr;\r
+ (void)mode;\r
+ (void)color;\r
throw_nogl;\r
#else\r
glColor3d(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0);\r
void cv::render(const string& str, const Ptr<GlFont>& font, Scalar color, Point2d pos)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)str;\r
- (void)font;\r
- (void)color;\r
- (void)pos;\r
+ (void)str;\r
+ (void)font;\r
+ (void)color;\r
+ (void)pos;\r
throw_nogl;\r
#else\r
glPushAttrib(GL_DEPTH_BUFFER_BIT);\r
bool icvCheckGlError(const char* file, const int line, const char* func)\r
{\r
#ifndef HAVE_OPENGL\r
- (void)file;\r
- (void)line;\r
- (void)func;\r
+ (void)file;\r
+ (void)line;\r
+ (void)func;\r
return true;\r
#else\r
GLenum err = glGetError();\r
if( iter > iters/10 && cvtest::randInt(rng)%200 == 0 ) // clear set
{
- int prev_count = cvset->total;
+ prev_count = cvset->total;
cvClearSet( cvset );
cvTsClearSimpleSet( sset );
if( cvtest::randInt(rng) % 200 == 0 ) // clear graph
{
- int prev_vtx_count = graph->total, prev_edge_count = graph->edges->total;
+ int prev_vtx_count2 = graph->total, prev_edge_count2 = graph->edges->total;
cvClearGraph( graph );
cvTsClearSimpleGraph( sgraph );
CV_TS_SEQ_CHECK_CONDITION( graph->active_count == 0 && graph->total == 0 &&
graph->first == 0 && graph->free_elems == 0 &&
- (graph->free_blocks != 0 || prev_vtx_count == 0),
+ (graph->free_blocks != 0 || prev_vtx_count2 == 0),
"The graph is not empty after clearing" );
CV_TS_SEQ_CHECK_CONDITION( edges->active_count == 0 && edges->total == 0 &&
edges->first == 0 && edges->free_elems == 0 &&
- (edges->free_blocks != 0 || prev_edge_count == 0),
+ (edges->free_blocks != 0 || prev_edge_count2 == 0),
"The graph is not empty after clearing" );
}
else if( op == 0 ) // add vertex
assert( src.channels() == 1 );
if( dim == 0 ) // row
{
- sum.create( 1, src.cols, CV_64FC1 );
+ sum.create( 1, src.cols, CV_64FC1 );
max.create( 1, src.cols, CV_64FC1 );
min.create( 1, src.cols, CV_64FC1 );
}
else
{
- sum.create( src.rows, 1, CV_64FC1 );
+ sum.create( src.rows, 1, CV_64FC1 );
max.create( src.rows, 1, CV_64FC1 );
min.create( src.rows, 1, CV_64FC1 );
}
sum.setTo(Scalar(0));
max.setTo(Scalar(-DBL_MAX));
min.setTo(Scalar(DBL_MAX));
-
+
const Mat_<Type>& src_ = src;
Mat_<double>& sum_ = (Mat_<double>&)sum;
Mat_<double>& min_ = (Mat_<double>&)min;
Mat_<double>& max_ = (Mat_<double>&)max;
-
+
if( dim == 0 )
{
for( int ri = 0; ri < src.rows; ri++ )
else if ( dstType == CV_32S )
eps = 0.6;
}
-
+
assert( opRes.type() == CV_64FC1 );
Mat _dst, dst, diff;
reduce( src, _dst, dim, opType, dstType );
getMatTypeStr( src.type(), srcTypeStr );
getMatTypeStr( dstType, dstTypeStr );
const char* dimStr = dim == 0 ? "ROWS" : "COLS";
-
+
sprintf( msg, "bad accuracy with srcType = %s, dstType = %s, opType = %s, dim = %s",
srcTypeStr.c_str(), dstTypeStr.c_str(), opTypeStr, dimStr );
ts->printf( cvtest::TS::LOG, msg );
{
int code = cvtest::TS::OK, tempCode;
Mat src, sum, avg, max, min;
-
+
src.create( sz, srcType );
randu( src, Scalar(0), Scalar(100) );
-
+
if( srcType == CV_8UC1 )
testReduce<uchar>( src, sum, avg, max, min, dim );
else if( srcType == CV_8SC1 )
testReduce<float>( src, sum, avg, max, min, dim );
else if( srcType == CV_64FC1 )
testReduce<double>( src, sum, avg, max, min, dim );
- else
+ else
assert( 0 );
-
+
// 1. sum
tempCode = checkOp( src, dstType, CV_REDUCE_SUM, sum, dim );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
// 2. avg
tempCode = checkOp( src, dstType, CV_REDUCE_AVG, avg, dim );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
// 3. max
tempCode = checkOp( src, dstType, CV_REDUCE_MAX, max, dim );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
// 4. min
tempCode = checkOp( src, dstType, CV_REDUCE_MIN, min, dim );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
return code;
}
int Core_ReduceTest::checkDim( int dim, Size sz )
{
int code = cvtest::TS::OK, tempCode;
-
+
// CV_8UC1
tempCode = checkCase( CV_8UC1, CV_8UC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkCase( CV_8UC1, CV_32SC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkCase( CV_8UC1, CV_32FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkCase( CV_8UC1, CV_64FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
// CV_16UC1
tempCode = checkCase( CV_16UC1, CV_32FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkCase( CV_16UC1, CV_64FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
// CV_16SC1
tempCode = checkCase( CV_16SC1, CV_32FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkCase( CV_16SC1, CV_64FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
// CV_32FC1
tempCode = checkCase( CV_32FC1, CV_32FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkCase( CV_32FC1, CV_64FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
// CV_64FC1
tempCode = checkCase( CV_64FC1, CV_64FC1, dim, sz );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
return code;
}
int Core_ReduceTest::checkSize( Size sz )
{
int code = cvtest::TS::OK, tempCode;
-
+
tempCode = checkDim( 0, sz ); // rows
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
- tempCode = checkDim( 1, sz ); // cols
+
+ tempCode = checkDim( 1, sz ); // cols
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
return code;
}
void Core_ReduceTest::run( int )
{
int code = cvtest::TS::OK, tempCode;
-
+
tempCode = checkSize( Size(1,1) );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkSize( Size(1,100) );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkSize( Size(100,1) );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
tempCode = checkSize( Size(1000,500) );
code = tempCode != cvtest::TS::OK ? tempCode : code;
-
+
ts->set_failed_test_info( code );
}
#define CHECK_C
-Size sz(200, 500);
-
class Core_PCATest : public cvtest::BaseTest
{
public:
protected:
void run(int)
{
+ const Size sz(200, 500);
+
double diffPrjEps, diffBackPrjEps,
prjEps, backPrjEps,
evalEps, evecEps;
int maxComponents = 100;
Mat rPoints(sz, CV_32FC1), rTestPoints(sz, CV_32FC1);
- RNG& rng = ts->get_rng();
-
+ RNG& rng = ts->get_rng();
+
rng.fill( rPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
rng.fill( rTestPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
-
+
PCA rPCA( rPoints, Mat(), CV_PCA_DATA_AS_ROW, maxComponents ), cPCA;
-
+
// 1. check C++ PCA & ROW
Mat rPrjTestPoints = rPCA.project( rTestPoints );
Mat rBackPrjTestPoints = rPCA.backProject( rPrjTestPoints );
-
+
Mat avg(1, sz.width, CV_32FC1 );
reduce( rPoints, avg, 0, CV_REDUCE_AVG );
Mat Q = rPoints - repeat( avg, rPoints.rows, 1 ), Qt = Q.t(), eval, evec;
Q = Qt * Q;
Q = Q /(float)rPoints.rows;
-
+
eigen( Q, eval, evec );
/*SVD svd(Q);
evec = svd.vt;
eval = svd.w;*/
-
+
Mat subEval( maxComponents, 1, eval.type(), eval.data ),
subEvec( maxComponents, evec.cols, evec.type(), evec.data );
-
+
#ifdef CHECK_C
Mat prjTestPoints, backPrjTestPoints, cPoints = rPoints.t(), cTestPoints = rTestPoints.t();
CvMat _points, _testPoints, _avg, _eval, _evec, _prjTestPoints, _backPrjTestPoints;
#endif
-
+
// check eigen()
double eigenEps = 1e-6;
double err;
{
Mat v = evec.row(i).t();
Mat Qv = Q * v;
-
+
Mat lv = eval.at<float>(i,0) * v;
err = norm( Qv, lv );
if( err > eigenEps )
absdiff(rPCA.eigenvectors, subEvec, tmp);
double mval = 0; Point mloc;
minMaxLoc(tmp, 0, &mval, 0, &mloc);
-
+
ts->printf( cvtest::TS::LOG, "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
ts->printf( cvtest::TS::LOG, "max diff is %g at (i=%d, j=%d) (%g vs %g)\n",
mval, mloc.y, mloc.x, rPCA.eigenvectors.at<float>(mloc.y, mloc.x),
}
}
}
-
+
prjEps = 1.265, backPrjEps = 1.265;
for( int i = 0; i < rTestPoints.rows; i++ )
{
return;
}
}
-
+
// 2. check C++ PCA & COL
cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents );
diffPrjEps = 1, diffBackPrjEps = 1;
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
-
+
#ifdef CHECK_C
// 3. check C PCA & ROW
_points = rPoints;
backPrjTestPoints.create(rPoints.size(), rPoints.type() );
_prjTestPoints = prjTestPoints;
_backPrjTestPoints = backPrjTestPoints;
-
+
cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW );
cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
-
+
err = norm(prjTestPoints, rPrjTestPoints, CV_RELATIVE_L2);
if( err > diffPrjEps )
{
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
-
+
// 3. check C PCA & COL
_points = cPoints;
_testPoints = cTestPoints;
evec = evec.t(); _evec = evec;
prjTestPoints = prjTestPoints.t(); _prjTestPoints = prjTestPoints;
backPrjTestPoints = backPrjTestPoints.t(); _backPrjTestPoints = backPrjTestPoints;
-
+
cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL );
cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
-
+
err = norm(cv::abs(prjTestPoints), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 );
if( err > diffPrjEps )
{
{
public:
Core_ArrayOpTest();
- ~Core_ArrayOpTest();
+ ~Core_ArrayOpTest();
protected:
- void run(int);
+ void run(int);
};
d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
phv = &hv;
}
-
+
const uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], false, phv) :
d == 3 ? M.ptr(idx[0], idx[1], idx[2], false, phv) :
M.ptr(idx, false, phv);
d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
phv = &hv;
}
-
+
if( d == 2 )
M.erase(idx[0], idx[1], phv);
else if( d == 3 )
d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
phv = &hv;
}
-
+
uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], true, phv) :
d == 3 ? M.ptr(idx[0], idx[1], idx[2], true, phv) :
M.ptr(idx, true, phv);
void Core_ArrayOpTest::run( int /* start_from */)
{
int errcount = 0;
-
+
// dense matrix operations
{
int sz3[] = {5, 10, 15};
RNG rng;
rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
-
+
int idx0[] = {3,4,5}, idx1[] = {0, 9, 7};
float val0 = 130;
Scalar val1(-1000, 30, 3, 8);
cvSetND(&matB, idx0, val1);
cvSet3D(&matB, idx1[0], idx1[1], idx1[2], -val1);
Ptr<CvMatND> matC = cvCloneMatND(&matB);
-
+
if( A.at<float>(idx0[0], idx0[1], idx0[2]) != val0 ||
A.at<float>(idx1[0], idx1[1], idx1[2]) != -val0 ||
cvGetReal3D(&matA, idx0[0], idx0[1], idx0[2]) != val0 ||
cvGetRealND(&matA, idx1) != -val0 ||
-
+
Scalar(B.at<Vec4s>(idx0[0], idx0[1], idx0[2])) != val1 ||
Scalar(B.at<Vec4s>(idx1[0], idx1[1], idx1[2])) != -val1 ||
Scalar(cvGet3D(matC, idx0[0], idx0[1], idx0[2])) != val1 ||
errcount++;
}
}
-
+
RNG rng;
const int MAX_DIM = 5, MAX_DIM_SZ = 10;
// sparse matrix operations
vector<double> all_vals2;
string sidx, min_sidx, max_sidx;
double min_val=0, max_val=0;
-
+
int p = 1;
for( k = 0; k < dims; k++ )
{
}
SparseMat M( dims, size, depth );
map<string, double> M0;
-
+
int nz0 = (unsigned)rng % max(p/5,10);
nz0 = min(max(nz0, 1), p);
all_vals.resize(nz0);
_all_vals2.convertTo(_all_vals2_f, CV_32F);
_all_vals2_f.convertTo(_all_vals2, CV_64F);
}
-
+
minMaxLoc(_all_vals, &min_val, &max_val);
double _norm0 = norm(_all_vals, CV_C);
double _norm1 = norm(_all_vals, CV_L1);
double _norm2 = norm(_all_vals, CV_L2);
-
+
for( i = 0; i < nz0; i++ )
{
for(;;)
break;
}
}
-
+
Ptr<CvSparseMat> M2 = (CvSparseMat*)M;
MatND Md;
M.copyTo(Md);
SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2);
-
+
int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount();
double norm0 = norm(M, CV_C);
double norm1 = norm(M, CV_L1);
double norm2 = norm(M, CV_L2);
double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000;
-
+
if( nz1 != nz0 || nz2 != nz0)
{
errcount++;
si, nz1, nz2, nz0 );
break;
}
-
+
if( fabs(norm0 - _norm0) > fabs(_norm0)*eps ||
fabs(norm1 - _norm1) > fabs(_norm1)*eps ||
fabs(norm2 - _norm2) > fabs(_norm2)*eps )
si, norm0, norm1, norm2, _norm0, _norm1, _norm2 );
break;
}
-
+
int n = (unsigned)rng % max(p/5,10);
n = min(max(n, 1), p) + nz0;
-
+
for( i = 0; i < n; i++ )
{
double val1, val2, val3, val0;
val1 = getValue(M, idx, rng);
val2 = getValue(M2, idx);
val3 = getValue(M3, idx, rng);
-
+
if( val1 != val0 || val2 != val0 || fabs(val3 - val0*2) > fabs(val0*2)*FLT_EPSILON )
{
errcount++;
break;
}
}
-
+
for( i = 0; i < n; i++ )
{
double val1, val2;
errcount++;
ts->printf(cvtest::TS::LOG, "SparseMat: after deleting M[%s], it is =%g/%g (while it should be 0)\n", sidx.c_str(), val1, val2 );
break;
- }
+ }
}
-
+
int nz = (int)M.nzcount();
if( nz != 0 )
{
ts->printf(cvtest::TS::LOG, "The number of non-zero elements after removing all the elements = %d (while it should be 0)\n", nz );
break;
}
-
+
int idx1[MAX_DIM], idx2[MAX_DIM];
double val1 = 0, val2 = 0;
M3 = SparseMat(Md);
min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
break;
}
-
+
minMaxIdx(Md, &val1, &val2, idx1, idx2);
s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) ||
break;
}
}
-
+
ts->set_failed_test_info(errcount == 0 ? cvtest::TS::OK : cvtest::TS::FAIL_INVALID_OUTPUT);
}
36.42f, 37.65f, 38.89f, 40.11f, 41.34f, 42.56f, 43.77f };
static const double xp = 1.64;
CV_Assert(n >= 1);
-
+
if( n <= 30 )
return chi2_tab95[n-1];
return n + sqrt((double)2*n)*xp + 0.6666666666666*(xp*xp - 1);
const int* H = (const int*)hist.data;
float* H0 = ((float*)hist0.data);
int i, hsz = hist.cols;
-
+
double sum = 0;
for( i = 0; i < hsz; i++ )
sum += H[i];
CV_Assert( fabs(1./sum - scale) < FLT_EPSILON );
-
+
if( dist_type == CV_RAND_UNI )
{
float scale0 = (float)(1./hsz);
}
else
{
- double sum = 0, r = (hsz-1.)/2;
+ double sum2 = 0, r = (hsz-1.)/2;
double alpha = 2*sqrt(2.)/r, beta = -alpha*r;
for( i = 0; i < hsz; i++ )
{
double x = i*alpha + beta;
H0[i] = (float)exp(-x*x);
- sum += H0[i];
+ sum2 += H0[i];
}
- sum = 1./sum;
+ sum2 = 1./sum2;
for( i = 0; i < hsz; i++ )
- H0[i] = (float)(H0[i]*sum);
+ H0[i] = (float)(H0[i]*sum2);
}
-
+
double chi2 = 0;
for( i = 0; i < hsz; i++ )
{
chi2 += (a - b)*(a - b)/(a + b);
}
realval = chi2;
-
+
double chi2_pval = chi2_p95(hsz - 1 - (dist_type == CV_RAND_NORMAL ? 2 : 0));
refval = chi2_pval*0.01;
return realval <= refval;
static int _ranges[][2] =
{{ 0, 256 }, { -128, 128 }, { 0, 65536 }, { -32768, 32768 },
{ -1000000, 1000000 }, { -1000, 1000 }, { -1000, 1000 }};
-
+
const int MAX_SDIM = 10;
const int N = 2000000;
const int maxSlice = 1000;
const int MAX_HIST_SIZE = 1000;
int progress = 0;
-
+
RNG& rng = ts->get_rng();
RNG tested_rng = theRNG();
test_case_count = 200;
-
+
for( int idx = 0; idx < test_case_count; idx++ )
{
progress = update_progress( progress, idx, test_case_count, 0 );
ts->update_context( this, idx, false );
-
+
int depth = cvtest::randInt(rng) % (CV_64F+1);
int c, cn = (cvtest::randInt(rng) % 4) + 1;
int type = CV_MAKETYPE(depth, cn);
double eps = 1.e-4;
if (depth == CV_64F)
eps = 1.e-7;
-
+
bool do_sphere_test = dist_type == CV_RAND_UNI;
Mat arr[2], hist[4];
int W[] = {0,0,0,0};
-
+
arr[0].create(1, SZ, type);
arr[1].create(1, SZ, type);
bool fast_algo = dist_type == CV_RAND_UNI && depth < CV_32F;
-
+
for( c = 0; c < cn; c++ )
{
int a, b, hsz;
while( abs(a-b) <= 1 );
if( a > b )
std::swap(a, b);
-
+
unsigned r = (unsigned)(b - a);
fast_algo = fast_algo && r <= 256 && (r & (r-1)) == 0;
hsz = min((unsigned)(b - a), (unsigned)MAX_HIST_SIZE);
int meanrange = vrange/16;
int mindiv = MAX(vrange/20, 5);
int maxdiv = MIN(vrange/8, 10000);
-
+
a = cvtest::randInt(rng) % meanrange - meanrange/2 +
(_ranges[depth][0] + _ranges[depth][1])/2;
b = cvtest::randInt(rng) % (maxdiv - mindiv) + mindiv;
}
A[c] = a;
B[c] = b;
- hist[c].create(1, hsz, CV_32S);
+ hist[c].create(1, hsz, CV_32S);
}
-
+
cv::RNG saved_rng = tested_rng;
int maxk = fast_algo ? 0 : 1;
for( k = 0; k <= maxk; k++ )
tested_rng.fill(aslice, dist_type, A, B);
}
}
-
+
if( maxk >= 1 && norm(arr[0], arr[1], NORM_INF) > eps)
{
ts->printf( cvtest::TS::LOG, "RNG output depends on the array lengths (some generated numbers get lost?)" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
-
+
for( c = 0; c < cn; c++ )
{
const uchar* data = arr[0].data;
double maxVal = dist_type == CV_RAND_UNI ? B[c] : A[c] + B[c]*4;
double scale = HSZ/(maxVal - minVal);
double delta = -minVal*scale;
-
+
hist[c] = Scalar::all(0);
-
+
for( i = c; i < SZ*cn; i += cn )
{
double val = depth == CV_8U ? ((const uchar*)data)[i] :
}
}
}
-
+
if( dist_type == CV_RAND_UNI && W[c] != SZ )
{
ts->printf( cvtest::TS::LOG, "Uniform RNG gave values out of the range [%g,%g) on channel %d/%d\n",
return;
}
double refval = 0, realval = 0;
-
+
if( !check_pdf(hist[c], 1./W[c], dist_type, refval, realval) )
{
ts->printf( cvtest::TS::LOG, "RNG failed Chi-square test "
return;
}
}
-
+
// Monte-Carlo test. Compute volume of SDIM-dimensional sphere
// inscribed in [-1,1]^SDIM cube.
if( do_sphere_test )
{
int SDIM = cvtest::randInt(rng) % (MAX_SDIM-1) + 2;
- int N0 = (SZ*cn/SDIM), N = 0;
+ int N0 = (SZ*cn/SDIM), n = 0;
double r2 = 0;
const uchar* data = arr[0].data;
double scale[4], delta[4];
scale[c] = 2./(B[c] - A[c]);
delta[c] = -A[c]*scale[c] - 1;
}
-
+
for( i = k = c = 0; i <= SZ*cn - SDIM; i++, k++, c++ )
{
double val = depth == CV_8U ? ((const uchar*)data)[i] :
r2 += val*val;
if( k == SDIM-1 )
{
- N += r2 <= 1;
+ n += r2 <= 1;
r2 = 0;
k = -1;
}
}
-
- double V = ((double)N/N0)*(1 << SDIM);
-
+
+ double V = ((double)n/N0)*(1 << SDIM);
+
// the theoretically computed volume
int sdim = SDIM % 2;
double V0 = sdim + 1;
for( sdim += 2; sdim <= SDIM; sdim += 2 )
V0 *= 2*CV_PI/sdim;
-
+
if( fabs(V - V0) > 0.3*fabs(V0) )
{
ts->printf( cvtest::TS::LOG, "RNG failed %d-dim sphere volume test (got %g instead of %g)\n",
{
public:
Core_RandRangeTest() {}
- ~Core_RandRangeTest() {}
+ ~Core_RandRangeTest() {}
protected:
void run(int)
{
theRNG().fill(af, RNG::UNIFORM, -DBL_MAX, DBL_MAX);
int n0 = 0, n255 = 0, nx = 0;
int nfmin = 0, nfmax = 0, nfx = 0;
-
+
for( int i = 0; i < a.rows; i++ )
for( int j = 0; j < a.cols; j++ )
{
BOWKMeansTrainer::~BOWKMeansTrainer()
{}
-Mat BOWKMeansTrainer::cluster( const Mat& descriptors ) const
+Mat BOWKMeansTrainer::cluster( const Mat& _descriptors ) const
{
Mat labels, vocabulary;
- kmeans( descriptors, clusterCount, labels, termcrit, attempts, flags, vocabulary );
+ kmeans( _descriptors, clusterCount, labels, termcrit, attempts, flags, vocabulary );
return vocabulary;
}
void BriefDescriptorExtractor::read( const FileNode& fn)
{
- int descriptorSize = fn["descriptorSize"];
- switch (descriptorSize)
+ int dSize = fn["descriptorSize"];
+ switch (dSize)
{
case 16:
test_fn_ = pixelTests16;
default:
CV_Error(CV_StsBadArg, "descriptorSize must be 16, 32, or 64");
}
- bytes_ = descriptorSize;
+ bytes_ = dSize;
}
void BriefDescriptorExtractor::write( FileStorage& fs) const
vector<KeyPoint> outKeypoints;
outKeypoints.reserve( keypoints.size() );
- int descriptorSize = descriptorExtractor->descriptorSize();
- Mat mergedDescriptors( maxKeypointsCount, 3*descriptorSize, descriptorExtractor->descriptorType() );
+ int dSize = descriptorExtractor->descriptorSize();
+ Mat mergedDescriptors( maxKeypointsCount, 3*dSize, descriptorExtractor->descriptorType() );
int mergedCount = 0;
// cp - current channel position
size_t cp[] = {0, 0, 0};
// merge descriptors
for( int ci = 0; ci < N; ci++ )
{
- Mat dst = mergedDescriptors(Range(mergedCount, mergedCount+1), Range(ci*descriptorSize, (ci+1)*descriptorSize));
+ Mat dst = mergedDescriptors(Range(mergedCount, mergedCount+1), Range(ci*dSize, (ci+1)*dSize));
channelDescriptors[ci].row( idxs[ci][cp[ci]] ).copyTo( dst );
cp[ci]++;
}
// draw keypoints
if( !(flags & DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS) )
{
- Mat outImg1 = outImg( Rect(0, 0, img1.cols, img1.rows) );
- drawKeypoints( outImg1, keypoints1, outImg1, singlePointColor, flags + DrawMatchesFlags::DRAW_OVER_OUTIMG );
+ Mat _outImg1 = outImg( Rect(0, 0, img1.cols, img1.rows) );
+ drawKeypoints( _outImg1, keypoints1, _outImg1, singlePointColor, flags + DrawMatchesFlags::DRAW_OVER_OUTIMG );
- Mat outImg2 = outImg( Rect(img1.cols, 0, img2.cols, img2.rows) );
- drawKeypoints( outImg2, keypoints2, outImg2, singlePointColor, flags + DrawMatchesFlags::DRAW_OVER_OUTIMG );
+ Mat _outImg2 = outImg( Rect(img1.cols, 0, img2.cols, img2.rows) );
+ drawKeypoints( _outImg2, keypoints2, _outImg2, singlePointColor, flags + DrawMatchesFlags::DRAW_OVER_OUTIMG );
}
}
pt2 = kp2.pt,
dpt2 = Point2f( std::min(pt2.x+outImg1.cols, float(outImg.cols-1)), pt2.y );
- line( outImg,
- Point(cvRound(pt1.x*draw_multiplier), cvRound(pt1.y*draw_multiplier)),
- Point(cvRound(dpt2.x*draw_multiplier), cvRound(dpt2.y*draw_multiplier)),
+ line( outImg,
+ Point(cvRound(pt1.x*draw_multiplier), cvRound(pt1.y*draw_multiplier)),
+ Point(cvRound(dpt2.x*draw_multiplier), cvRound(dpt2.y*draw_multiplier)),
color, 1, CV_AA, draw_shift_bits );
}
{
public:
HarrisDetector( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1,
- int blockSize=3, bool useHarrisDetector=true, double k=0.04 )
- : GFTTDetector( maxCorners, qualityLevel, minDistance, blockSize, useHarrisDetector, k ) {}
+ int blockSize=3, bool useHarrisDetector=true, double k=0.04 );
AlgorithmInfo* info() const;
};
+inline HarrisDetector::HarrisDetector( int _maxCorners, double _qualityLevel, double _minDistance,
+ int _blockSize, bool _useHarrisDetector, double _k )
+ : GFTTDetector( _maxCorners, _qualityLevel, _minDistance, _blockSize, _useHarrisDetector, _k ) {}
+
CV_INIT_ALGORITHM(HarrisDetector, "Feature2D.HARRIS",
obj.info()->addParam(obj, "nfeatures", obj.nfeatures);
obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel);
for(int i = 0; i < (int)ip.size(); ++i)
{
CV_Assert(ip[i].type() == FileNode::MAP);
- std::string name = (std::string)ip[i]["name"];
+ std::string _name = (std::string)ip[i]["name"];
int type = (int)ip[i]["type"];
switch(type)
case CV_16U:
case CV_16S:
case CV_32S:
- indexParams->setInt(name, (int) ip[i]["value"]);
+ indexParams->setInt(_name, (int) ip[i]["value"]);
break;
case CV_32F:
- indexParams->setFloat(name, (float) ip[i]["value"]);
+ indexParams->setFloat(_name, (float) ip[i]["value"]);
break;
case CV_64F:
- indexParams->setDouble(name, (double) ip[i]["value"]);
+ indexParams->setDouble(_name, (double) ip[i]["value"]);
break;
case CV_USRTYPE1:
- indexParams->setString(name, (std::string) ip[i]["value"]);
+ indexParams->setString(_name, (std::string) ip[i]["value"]);
break;
case CV_MAKETYPE(CV_USRTYPE1,2):
- indexParams->setBool(name, (int) ip[i]["value"] != 0);
+ indexParams->setBool(_name, (int) ip[i]["value"] != 0);
break;
case CV_MAKETYPE(CV_USRTYPE1,3):
indexParams->setAlgorithm((int) ip[i]["value"]);
for(int i = 0; i < (int)sp.size(); ++i)
{
CV_Assert(sp[i].type() == FileNode::MAP);
- std::string name = (std::string)sp[i]["name"];
+ std::string _name = (std::string)sp[i]["name"];
int type = (int)sp[i]["type"];
switch(type)
case CV_16U:
case CV_16S:
case CV_32S:
- searchParams->setInt(name, (int) sp[i]["value"]);
+ searchParams->setInt(_name, (int) sp[i]["value"]);
break;
case CV_32F:
- searchParams->setFloat(name, (float) ip[i]["value"]);
+ searchParams->setFloat(_name, (float) ip[i]["value"]);
break;
case CV_64F:
- searchParams->setDouble(name, (double) ip[i]["value"]);
+ searchParams->setDouble(_name, (double) ip[i]["value"]);
break;
case CV_USRTYPE1:
- searchParams->setString(name, (std::string) ip[i]["value"]);
+ searchParams->setString(_name, (std::string) ip[i]["value"]);
break;
case CV_MAKETYPE(CV_USRTYPE1,2):
- searchParams->setBool(name, (int) ip[i]["value"] != 0);
+ searchParams->setBool(_name, (int) ip[i]["value"] != 0);
break;
case CV_MAKETYPE(CV_USRTYPE1,3):
searchParams->setAlgorithm((int) ip[i]["value"]);
}
*imgptr += 0x10000;
}
- int i = (int)(imgptr-ioptr);
- ptsptr->pt = cvPoint( i&stepmask, i>>stepgap );
+ int imsk = (int)(imgptr-ioptr);
+ ptsptr->pt = cvPoint( imsk&stepmask, imsk>>stepgap );
// get the current location
accumulateMSERComp( comptr, ptsptr );
ptsptr++;
* @param detector_params parameters to use
*/
ORB::ORB(int _nfeatures, float _scaleFactor, int _nlevels, int _edgeThreshold,
- int _firstLevel, int WTA_K, int _scoreType, int _patchSize) :
+ int _firstLevel, int _WTA_K, int _scoreType, int _patchSize) :
nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
- edgeThreshold(_edgeThreshold), firstLevel(_firstLevel), WTA_K(WTA_K),
+ edgeThreshold(_edgeThreshold), firstLevel(_firstLevel), WTA_K(_WTA_K),
scoreType(_scoreType), patchSize(_patchSize)
{}
for (int level = 0; level < nlevels; ++level)
{
- int nfeatures = nfeaturesPerLevel[level];
- allKeypoints[level].reserve(nfeatures*2);
+ int featuresNum = nfeaturesPerLevel[level];
+ allKeypoints[level].reserve(featuresNum*2);
vector<KeyPoint> & keypoints = allKeypoints[level];
if( scoreType == ORB::HARRIS_SCORE )
{
// Keep more points than necessary as FAST does not give amazing corners
- KeyPointsFilter::retainBest(keypoints, 2 * nfeatures);
+ KeyPointsFilter::retainBest(keypoints, 2 * featuresNum);
// Compute the Harris cornerness (better scoring than FAST)
HarrisResponses(imagePyramid[level], keypoints, 7, HARRIS_K);
}
//cull to the final desired level, using the new Harris scores or the original FAST scores.
- KeyPointsFilter::retainBest(keypoints, nfeatures);
+ KeyPointsFilter::retainBest(keypoints, featuresNum);
float sf = getScale(level, firstLevel, scaleFactor);
if( image.type() != CV_8UC1 )
cvtColor(_image, image, CV_BGR2GRAY);
- int nlevels = this->nlevels;
+ int levelsNum = this->nlevels;
if( !do_keypoints )
{
//
// In short, ultimately the descriptor should
// ignore octave parameter and deal only with the keypoint size.
- nlevels = 0;
+ levelsNum = 0;
for( size_t i = 0; i < _keypoints.size(); i++ )
- nlevels = std::max(nlevels, std::max(_keypoints[i].octave, 0));
- nlevels++;
+ levelsNum = std::max(levelsNum, std::max(_keypoints[i].octave, 0));
+ levelsNum++;
}
// Pre-compute the scale pyramids
- vector<Mat> imagePyramid(nlevels), maskPyramid(nlevels);
- for (int level = 0; level < nlevels; ++level)
+ vector<Mat> imagePyramid(levelsNum), maskPyramid(levelsNum);
+ for (int level = 0; level < levelsNum; ++level)
{
float scale = 1/getScale(level, firstLevel, scaleFactor);
Size sz(cvRound(image.cols*scale), cvRound(image.rows*scale));
KeyPointsFilter::runByImageBorder(_keypoints, image.size(), edgeThreshold);
// Cluster the input keypoints depending on the level they were computed at
- allKeypoints.resize(nlevels);
+ allKeypoints.resize(levelsNum);
for (vector<KeyPoint>::iterator keypoint = _keypoints.begin(),
keypointEnd = _keypoints.end(); keypoint != keypointEnd; ++keypoint)
allKeypoints[keypoint->octave].push_back(*keypoint);
// Make sure we rescale the coordinates
- for (int level = 0; level < nlevels; ++level)
+ for (int level = 0; level < levelsNum; ++level)
{
if (level == firstLevel)
continue;
if( do_descriptors )
{
int nkeypoints = 0;
- for (int level = 0; level < nlevels; ++level)
+ for (int level = 0; level < levelsNum; ++level)
nkeypoints += (int)allKeypoints[level].size();
if( nkeypoints == 0 )
_descriptors.release();
_keypoints.clear();
int offset = 0;
- for (int level = 0; level < nlevels; ++level)
+ for (int level = 0; level < levelsNum; ++level)
{
// Get the features and compute their orientation
vector<KeyPoint>& keypoints = allKeypoints[level];
computeIntegralImages( const Mat& matI, Mat& matS, Mat& matT, Mat& _FT )
{
CV_Assert( matI.type() == CV_8U );
-
+
int x, y, rows = matI.rows, cols = matI.cols;
-
+
matS.create(rows + 1, cols + 1, CV_32S);
matT.create(rows + 1, cols + 1, CV_32S);
_FT.create(rows + 1, cols + 1, CV_32S);
-
+
const uchar* I = matI.ptr<uchar>();
int *S = matS.ptr<int>(), *T = matT.ptr<int>(), *FT = _FT.ptr<int>();
int istep = (int)matI.step, step = (int)(matS.step/sizeof(S[0]));
StarFeature f[MAX_PATTERN];
Mat sum, tilted, flatTilted;
- int y, i=0, rows = img.rows, cols = img.cols;
+ int y, rows = img.rows, cols = img.cols;
int border, npatterns=0, maxIdx=0;
CV_Assert( img.type() == CV_8UC1 );
-
+
responses.create( img.size(), CV_32F );
sizes.create( img.size(), CV_16S );
- while( pairs[i][0] >= 0 && !
- ( sizes0[pairs[i][0]] >= maxSize
- || sizes0[pairs[i+1][0]] + sizes0[pairs[i+1][0]]/2 >= std::min(rows, cols) ) )
+ while( pairs[npatterns][0] >= 0 && !
+ ( sizes0[pairs[npatterns][0]] >= maxSize
+ || sizes0[pairs[npatterns+1][0]] + sizes0[pairs[npatterns+1][0]]/2 >= std::min(rows, cols) ) )
{
- ++i;
+ ++npatterns;
}
-
- npatterns = i;
+
npatterns += (pairs[npatterns-1][0] >= 0);
maxIdx = pairs[npatterns-1][0];
-
+
computeIntegralImages( img, sum, tilted, flatTilted );
int step = (int)(sum.step/sum.elemSize());
- for( i = 0; i <= maxIdx; i++ )
+ for(int i = 0; i <= maxIdx; i++ )
{
int ur_size = sizes0[i], t_size = sizes0[i] + sizes0[i]/2;
int ur_area = (2*ur_size + 1)*(2*ur_size + 1);
sizes1[maxIdx] = -sizes1[maxIdx];
border = sizes0[maxIdx] + sizes0[maxIdx]/2;
- for( i = 0; i < npatterns; i++ )
+ for(int i = 0; i < npatterns; i++ )
{
int innerArea = f[pairs[i][1]].area;
int outerArea = f[pairs[i][0]].area - innerArea;
invSizes[i][0] = 1.f/outerArea;
invSizes[i][1] = 1.f/innerArea;
}
-
+
#if CV_SSE2
if( useSIMD )
{
- for( i = 0; i < npatterns; i++ )
+ for(int i = 0; i < npatterns; i++ )
{
_mm_store_ps((float*)&invSizes4[i][0], _mm_set1_ps(invSizes[i][0]));
_mm_store_ps((float*)&invSizes4[i][1], _mm_set1_ps(invSizes[i][1]));
}
- for( i = 0; i <= maxIdx; i++ )
+ for(int i = 0; i <= maxIdx; i++ )
_mm_store_ps((float*)&sizes1_4[i], _mm_set1_ps((float)sizes1[i]));
}
#endif
float* r_ptr2 = responses.ptr<float>(rows - 1 - y);
short* s_ptr = sizes.ptr<short>(y);
short* s_ptr2 = sizes.ptr<short>(rows - 1 - y);
-
+
memset( r_ptr, 0, cols*sizeof(r_ptr[0]));
memset( r_ptr2, 0, cols*sizeof(r_ptr2[0]));
memset( s_ptr, 0, cols*sizeof(s_ptr[0]));
for( y = border; y < rows - border; y++ )
{
- int x = border, i;
+ int x = border;
float* r_ptr = responses.ptr<float>(y);
short* s_ptr = sizes.ptr<short>(y);
-
+
memset( r_ptr, 0, border*sizeof(r_ptr[0]));
memset( s_ptr, 0, border*sizeof(s_ptr[0]));
memset( r_ptr + cols - border, 0, border*sizeof(r_ptr[0]));
__m128 bestResponse = _mm_setzero_ps();
__m128 bestSize = _mm_setzero_ps();
- for( i = 0; i <= maxIdx; i++ )
+ for(int i = 0; i <= maxIdx; i++ )
{
const int** p = (const int**)&f[i].p[0];
__m128i r0 = _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(p[0]+ofs)),
_mm_store_ps((float*)&vals[i], _mm_cvtepi32_ps(r0));
}
- for( i = 0; i < npatterns; i++ )
+ for(int i = 0; i < npatterns; i++ )
{
__m128 inner_sum = vals[pairs[i][1]];
__m128 outer_sum = _mm_sub_ps(vals[pairs[i][0]], inner_sum);
_mm_packs_epi32(_mm_cvtps_epi32(bestSize),_mm_setzero_si128()));
}
}
-#endif
+#endif
for( ; x < cols - border; x++ )
{
int ofs = y*step + x;
float bestResponse = 0;
int bestSize = 0;
- for( i = 0; i <= maxIdx; i++ )
+ for(int i = 0; i <= maxIdx; i++ )
{
const int** p = (const int**)&f[i].p[0];
vals[i] = p[0][ofs] - p[1][ofs] - p[2][ofs] + p[3][ofs] +
p[4][ofs] - p[5][ofs] - p[6][ofs] + p[7][ofs];
}
- for( i = 0; i < npatterns; i++ )
+ for(int i = 0; i < npatterns; i++ )
{
int inner_sum = vals[pairs[i][1]];
int outer_sum = vals[pairs[i][0]] - inner_sum;
int x, y, delta = sz/4, radius = delta*4;
float Lxx = 0, Lyy = 0, Lxy = 0;
int Lxxb = 0, Lyyb = 0, Lxyb = 0;
-
+
for( y = pt.y - radius; y <= pt.y + radius; y += delta )
for( x = pt.x - radius; x <= pt.x + radius; x += delta )
{
float Ly = r_ptr[(y+1)*rstep + x] - r_ptr[(y-1)*rstep + x];
Lxx += Lx*Lx; Lyy += Ly*Ly; Lxy += Lx*Ly;
}
-
+
if( (Lxx + Lyy)*(Lxx + Lyy) >= lineThresholdProjected*(Lxx*Lyy - Lxy*Lxy) )
return true;
;
}
}
-
+
StarDetector::StarDetector(int _maxSize, int _responseThreshold,
int _lineThresholdProjected,
int _lineThresholdBinarized,
{
Mat grayImage = image;
if( image.type() != CV_8U ) cvtColor( image, grayImage, CV_BGR2GRAY );
-
+
(*this)(grayImage, keypoints);
KeyPointsFilter::runByPixelsMask( keypoints, mask );
-}
+}
void StarDetector::operator()(const Mat& img, vector<KeyPoint>& keypoints) const
{
responseThreshold, lineThresholdProjected,
lineThresholdBinarized, suppressNonmaxSize );
}
-
+
}
/**
Default constructor. Initializes a new pool.
*/
- PooledAllocator(int blocksize = BLOCKSIZE)
+ PooledAllocator(int blockSize = BLOCKSIZE)
{
- this->blocksize = blocksize;
+ blocksize = blockSize;
remaining = 0;
base = NULL;
*/
void* allocateMemory(int size)
{
- int blocksize;
+ int blockSize;
/* Round size up to a multiple of wordsize. The following expression
only works for WORDSIZE that is a power of 2, by masking last bits of
wastedMemory += remaining;
/* Allocate new storage. */
- blocksize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
+ blockSize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE;
// use the standard C malloc to allocate memory
- void* m = ::malloc(blocksize);
+ void* m = ::malloc(blockSize);
if (!m) {
fprintf(stderr,"Failed to allocate memory.\n");
return NULL;
int shift = 0;
//int shift = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1);
- remaining = blocksize - sizeof(void*) - shift;
+ remaining = blockSize - sizeof(void*) - shift;
loc = ((char*)m + sizeof(void*) + shift);
}
void* rloc = loc;
/** @param only constructor we use in our code
* @param the size of the bitset (in bits)
*/
- DynamicBitset(size_t size)
+ DynamicBitset(size_t sz)
{
- resize(size);
+ resize(sz);
reset();
}
/** @param resize the bitset so that it contains at least size bits
* @param size
*/
- void resize(size_t size)
+ void resize(size_t sz)
{
- size_ = size;
- bitset_.resize(size / cell_bit_size_ + 1);
+ size_ = sz;
+ bitset_.resize(sz / cell_bit_size_ + 1);
}
/** @param set a bit to true
* Constructor.
*
* Params:
- * size = heap size
+ * sz = heap size
*/
- Heap(int size)
+ Heap(int sz)
{
- length = size;
+ length = sz;
heap.reserve(length);
count = 0;
}
* indices_length = length of indices vector
*
*/
- void chooseCentersRandom(int k, int* indices, int indices_length, int* centers, int& centers_length)
+ void chooseCentersRandom(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
{
UniqueRandom r(indices_length);
return;
}
- centers[index] = indices[rnd];
+ centers[index] = dsindices[rnd];
for (int j=0; j<index; ++j) {
DistanceType sq = distance(dataset[centers[index]], dataset[centers[j]], dataset.cols);
* indices = indices in the dataset
* Returns:
*/
- void chooseCentersGonzales(int k, int* indices, int indices_length, int* centers, int& centers_length)
+ void chooseCentersGonzales(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
{
int n = indices_length;
int rnd = rand_int(n);
assert(rnd >=0 && rnd < n);
- centers[0] = indices[rnd];
+ centers[0] = dsindices[rnd];
int index;
for (index=1; index<k; ++index) {
int best_index = -1;
DistanceType best_val = 0;
for (int j=0; j<n; ++j) {
- DistanceType dist = distance(dataset[centers[0]],dataset[indices[j]],dataset.cols);
+ DistanceType dist = distance(dataset[centers[0]],dataset[dsindices[j]],dataset.cols);
for (int i=1; i<index; ++i) {
- DistanceType tmp_dist = distance(dataset[centers[i]],dataset[indices[j]],dataset.cols);
+ DistanceType tmp_dist = distance(dataset[centers[i]],dataset[dsindices[j]],dataset.cols);
if (tmp_dist<dist) {
dist = tmp_dist;
}
}
}
if (best_index!=-1) {
- centers[index] = indices[best_index];
+ centers[index] = dsindices[best_index];
}
else {
break;
* indices = indices in the dataset
* Returns:
*/
- void chooseCentersKMeanspp(int k, int* indices, int indices_length, int* centers, int& centers_length)
+ void chooseCentersKMeanspp(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
{
int n = indices_length;
// Choose one random center and set the closestDistSq values
int index = rand_int(n);
assert(index >=0 && index < n);
- centers[0] = indices[index];
+ centers[0] = dsindices[index];
for (int i = 0; i < n; i++) {
- closestDistSq[i] = distance(dataset[indices[i]], dataset[indices[index]], dataset.cols);
+ closestDistSq[i] = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols);
currentPot += closestDistSq[i];
}
// Compute the new potential
double newPot = 0;
- for (int i = 0; i < n; i++) newPot += std::min( distance(dataset[indices[i]], dataset[indices[index]], dataset.cols), closestDistSq[i] );
+ for (int i = 0; i < n; i++) newPot += std::min( distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols), closestDistSq[i] );
// Store the best result
if ((bestNewPot < 0)||(newPot < bestNewPot)) {
}
// Add the appropriate center
- centers[centerCount] = indices[bestNewIndex];
+ centers[centerCount] = dsindices[bestNewIndex];
currentPot = bestNewPot;
- for (int i = 0; i < n; i++) closestDistSq[i] = std::min( distance(dataset[indices[i]], dataset[indices[bestNewIndex]], dataset.cols), closestDistSq[i] );
+ for (int i = 0; i < n; i++) closestDistSq[i] = std::min( distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols), closestDistSq[i] );
}
centers_length = centerCount;
- void computeLabels(int* indices, int indices_length, int* centers, int centers_length, int* labels, DistanceType& cost)
+ void computeLabels(int* dsindices, int indices_length, int* centers, int centers_length, int* labels, DistanceType& cost)
{
cost = 0;
for (int i=0; i<indices_length; ++i) {
- ElementType* point = dataset[indices[i]];
+ ElementType* point = dataset[dsindices[i]];
DistanceType dist = distance(point, dataset[centers[0]], veclen_);
labels[i] = 0;
for (int j=1; j<centers_length; ++j) {
*
* TODO: for 1-sized clusters don't store a cluster center (it's the same as the single cluster point)
*/
- void computeClustering(NodePtr node, int* indices, int indices_length, int branching, int level)
+ void computeClustering(NodePtr node, int* dsindices, int indices_length, int branching, int level)
{
node->size = indices_length;
node->level = level;
if (indices_length < leaf_size_) { // leaf node
- node->indices = indices;
+ node->indices = dsindices;
std::sort(node->indices,node->indices+indices_length);
node->childs = NULL;
return;
std::vector<int> labels(indices_length);
int centers_length;
- (this->*chooseCenters)(branching, indices, indices_length, ¢ers[0], centers_length);
+ (this->*chooseCenters)(branching, dsindices, indices_length, ¢ers[0], centers_length);
if (centers_length<branching) {
- node->indices = indices;
+ node->indices = dsindices;
std::sort(node->indices,node->indices+indices_length);
node->childs = NULL;
return;
// assign points to clusters
DistanceType cost;
- computeLabels(indices, indices_length, ¢ers[0], centers_length, &labels[0], cost);
+ computeLabels(dsindices, indices_length, ¢ers[0], centers_length, &labels[0], cost);
node->childs = pool.allocate<NodePtr>(branching);
int start = 0;
for (int i=0; i<branching; ++i) {
for (int j=0; j<indices_length; ++j) {
if (labels[j]==i) {
- std::swap(indices[j],indices[end]);
+ std::swap(dsindices[j],dsindices[end]);
std::swap(labels[j],labels[end]);
end++;
}
node->childs[i] = pool.allocate<Node>();
node->childs[i]->pivot = centers[i];
node->childs[i]->indices = NULL;
- computeClustering(node->childs[i],indices+start, end-start, branching, level+1);
+ computeClustering(node->childs[i],dsindices+start, end-start, branching, level+1);
start=end;
}
}
set(the_description "GPU-accelerated Computer Vision")
ocv_add_module(gpu opencv_imgproc opencv_calib3d opencv_objdetect opencv_video opencv_nonfree opencv_legacy)
-ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/cuda")
-
-ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../highgui/src")
+ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/cuda" "${CMAKE_CURRENT_SOURCE_DIR}/../highgui/src")
file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
file(GLOB lib_int_hdrs "src/*.hpp" "src/*.h")
set(ncv_files ${ncv_srcs} ${ncv_hdrs} ${ncv_cuda})
source_group("Src\\NVidia" FILES ${ncv_files})
- include_directories(AFTER SYSTEM ${CUDA_INCLUDE_DIRS})
- ocv_include_directories("src/nvidia" "src/nvidia/core" "src/nvidia/NPP_staging")
- ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
+ ocv_include_directories("src/nvidia" "src/nvidia/core" "src/nvidia/NPP_staging" ${CUDA_INCLUDE_DIRS})
+ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef /wd4211 /wd4201 /wd4100 /wd4505 /wd4408)
#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-keep")
#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;/EHsc-;")
if(MSVC)
if(NOT ENABLE_NOISY_WARNINGS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4211 /wd4201 /wd4100 /wd4505 /wd4408")
-
foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
string(REPLACE "/W4" "/W3" ${var} "${${var}}")
endforeach()
ocv_cuda_compile(cuda_objs ${lib_cuda} ${ncv_cuda})
#CUDA_BUILD_CLEAN_TARGET()
-
set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
-
if(NOT APPLE)
unset(CUDA_nvcuvid_LIBRARY CACHE)
find_cuda_helper_libs(nvcuvid)
################################################################################################################
file(GLOB test_srcs "test/*.cpp")
file(GLOB test_hdrs "test/*.hpp" "test/*.h")
+
+set(nvidia "")
if(HAVE_CUDA)
file(GLOB nvidia "test/nvidia/*.cpp" "test/nvidia/*.hpp" "test/nvidia/*.h")
set(nvidia FILES "Src\\\\\\\\NVidia" ${nvidia}) # 8 ugly backslashes :'(
-else()
- set(nvidia "")
endif()
ocv_add_accuracy_tests(FILES "Include" ${test_hdrs}
if(HAVE_OPENNI)
list(APPEND highgui_srcs src/cap_openni.cpp)
- include_directories(AFTER SYSTEM ${OPENNI_INCLUDE_DIR})
+ ocv_include_directories(${OPENNI_INCLUDE_DIR})
list(APPEND HIGHGUI_LIBRARIES ${OPENNI_LIBRARY})
endif(HAVE_OPENNI)
sinkpad = gst_element_get_static_pad (color, "sink");
-
+
// printf("linking dynamic pad to colourconverter %p %p\n", uridecodebin, pad);
gst_pad_link (pad, sinkpad);
if(manualpipeline) {
GstIterator *it = gst_bin_iterate_sinks(GST_BIN(uridecodebin));
if(gst_iterator_next(it, (gpointer *)&sink) != GST_ITERATOR_OK) {
- CV_ERROR(CV_StsError, "GStreamer: cannot find appsink in manual pipeline\n");
- return false;
+ CV_ERROR(CV_StsError, "GStreamer: cannot find appsink in manual pipeline\n");
+ return false;
}
- pipeline = uridecodebin;
+ pipeline = uridecodebin;
} else {
- pipeline = gst_pipeline_new (NULL);
+ pipeline = gst_pipeline_new (NULL);
color = gst_element_factory_make("ffmpegcolorspace", NULL);
sink = gst_element_factory_make("appsink", NULL);
gst_app_sink_set_max_buffers (GST_APP_SINK(sink), 1);
gst_app_sink_set_drop (GST_APP_SINK(sink), stream);
- {
- GstCaps* caps;
- caps = gst_caps_new_simple("video/x-raw-rgb",
- "red_mask", G_TYPE_INT, 0x0000FF,
- "green_mask", G_TYPE_INT, 0x00FF00,
- "blue_mask", G_TYPE_INT, 0xFF0000,
- NULL);
- gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
+ gst_app_sink_set_caps(GST_APP_SINK(sink), gst_caps_new_simple("video/x-raw-rgb",
+ "red_mask", G_TYPE_INT, 0x0000FF,
+ "green_mask", G_TYPE_INT, 0x00FF00,
+ "blue_mask", G_TYPE_INT, 0xFF0000,
+ NULL));
gst_caps_unref(caps);
- }
if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY) ==
GST_STATE_CHANGE_FAILURE) {
return -1;
} else {
buffer_number--;
- fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName);
+ fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName);
- goto try_again;
+ goto try_again;
}
}
if (capture->buffers[MAX_V4L_BUFFERS].start) {
free(capture->buffers[MAX_V4L_BUFFERS].start);
capture->buffers[MAX_V4L_BUFFERS].start = NULL;
- }
-
+ }
+
capture->buffers[MAX_V4L_BUFFERS].start = malloc(buf.length);
capture->buffers[MAX_V4L_BUFFERS].length = buf.length;
};
#ifdef USE_TEMP_BUFFER
memcpy(capture->buffers[MAX_V4L_BUFFERS].start,
- capture->buffers[buf.index].start,
- capture->buffers[MAX_V4L_BUFFERS].length );
+ capture->buffers[buf.index].start,
+ capture->buffers[MAX_V4L_BUFFERS].length );
capture->bufferIndex = MAX_V4L_BUFFERS;
//printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n",
- // buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused);
+ // buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused);
#else
capture->bufferIndex = buf.index;
#endif
capture->mmaps[capture->bufferIndex].format = capture->imageProperties.palette;
if (v4l1_ioctl (capture->deviceHandle, VIDIOCMCAPTURE,
- &capture->mmaps[capture->bufferIndex]) == -1) {
- /* capture is on the way, so just exit */
- return 1;
+ &capture->mmaps[capture->bufferIndex]) == -1) {
+ /* capture is on the way, so just exit */
+ return 1;
}
++capture->bufferIndex;
if (capture->is_v4l2_device == 1)
{
- if(capture->buffers[capture->bufferIndex].start){
- memcpy((char *)capture->frame.imageData,
- (char *)capture->buffers[capture->bufferIndex].start,
- capture->frame.imageSize);
- }
+ if(capture->buffers[capture->bufferIndex].start){
+ memcpy((char *)capture->frame.imageData,
+ (char *)capture->buffers[capture->bufferIndex].start,
+ capture->frame.imageSize);
+ }
} else
#endif /* HAVE_CAMV4L2 */
sprintf(name, "<unknown property string>");
capture->control.id = property_id;
}
-
+
if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &capture->control) == 0) {
/* all went well */
is_v4l2_device = 1;
CLEAR (capture->control);
CLEAR (capture->queryctrl);
-
+
/* get current values */
switch (property_id) {
case CV_CAP_PROP_BRIGHTNESS:
if (xioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type) < 0) {
perror ("Unable to stop the stream.");
}
- for (unsigned int n_buffers = 0; n_buffers < capture->req.count; ++n_buffers) {
- if (-1 == v4l2_munmap (capture->buffers[n_buffers].start, capture->buffers[n_buffers].length)) {
+ for (unsigned int n_buffers2 = 0; n_buffers2 < capture->req.count; ++n_buffers2) {
+ if (-1 == v4l2_munmap (capture->buffers[n_buffers2].start, capture->buffers[n_buffers2].length)) {
perror ("munmap");
}
}
if( !m_buf.empty() || m_f )
{
- png_uint_32 width, height;
+ png_uint_32 wdth, hght;
int bit_depth, color_type;
png_read_info( png_ptr, info_ptr );
- png_get_IHDR( png_ptr, info_ptr, &width, &height,
+ png_get_IHDR( png_ptr, info_ptr, &wdth, &hght,
&bit_depth, &color_type, 0, 0, 0 );
- m_width = (int)width;
- m_height = (int)height;
+ m_width = (int)wdth;
+ m_height = (int)hght;
m_color_type = color_type;
m_bit_depth = bit_depth;
if( bit_depth <= 8 || bit_depth == 16 )
{
- switch(color_type)
+ switch(color_type)
{
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_PALETTE:
else if( !isBigEndian() )
png_set_swap( png_ptr );
- if(img.channels() < 4)
+ if(img.channels() < 4)
{
/* observation: png_read_image() writes 400 bytes beyond
* end of data when reading a 400x118 color png
#else
png_set_gray_1_2_4_to_8( png_ptr );
#endif
-
+
if( CV_MAT_CN(m_type) > 1 && color )
png_set_bgr( png_ptr ); // convert RGB to BGR
else if( color )
if( params[i] == CV_IMWRITE_PNG_STRATEGY )
{
compression_strategy = params[i+1];
- compression_strategy = MIN(MAX(compression_strategy, 0), Z_FIXED);
+ compression_strategy = MIN(MAX(compression_strategy, 0), Z_FIXED);
}
}
if( tif )
{
- int width = 0, height = 0, photometric = 0;
+ int wdth = 0, hght = 0, photometric = 0;
m_tif = tif;
- if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &width ) &&
- TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &height ) &&
+ if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &wdth ) &&
+ TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &hght ) &&
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ))
{
int bpp=8, ncn = photometric > 1 ? 3 : 1;
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
-
- m_width = width;
- m_height = height;
+
+ m_width = wdth;
+ m_height = hght;
if( bpp > 8 &&
((photometric != 2 && photometric != 1) ||
(ncn != 1 && ncn != 3 && ncn != 4)))
bool color = img.channels() > 1;
uchar* data = img.data;
int step = (int)img.step;
-
+
if( img.depth() != CV_8U && img.depth() != CV_16U && img.depth() != CV_32F && img.depth() != CV_64F )
return false;
default:
{
return false;
- }
+ }
}
-
+
const int bitsPerByte = 8;
size_t fileStep = (width * channels * bitsPerChannel) / bitsPerByte;
int rowsPerStrip = (int)((1 << 13)/fileStep);
{
return false;
}
-
+
// defaults for now, maybe base them on params in the future
int compression = COMPRESSION_LZW;
int predictor = PREDICTOR_HORIZONTAL;
return false;
}
}
-
+
TIFFClose(pTiffHandle);
return true;
}
if( !strm.open(*m_buf) )
return false;
}
- else
+ else
{
#ifdef HAVE_TIFF
return writeLibTiff(img, params);
void CV_DrawingTest::run( int )
{
Mat testImg, valImg;
- const string name = "drawing/image.jpg";
+ const string fname = "drawing/image.jpg";
string path = ts->get_data_path(), filename;
- filename = path + name;
+ filename = path + fname;
draw( testImg );
{
public:
CV_FillConvexPolyTest() {}
- ~CV_FillConvexPolyTest() {}
+ ~CV_FillConvexPolyTest() {}
protected:
void run(int)
{
vector<Point> line1;
vector<Point> line2;
-
+
line1.push_back(Point(1, 1));
line1.push_back(Point(5, 1));
line1.push_back(Point(5, 8));
line1.push_back(Point(1, 8));
-
+
line2.push_back(Point(2, 2));
line2.push_back(Point(10, 2));
line2.push_back(Point(10, 16));
line2.push_back(Point(2, 16));
-
+
Mat gray0(10,10,CV_8U, Scalar(0));
fillConvexPoly(gray0, line1, Scalar(255), 8, 0);
int nz1 = countNonZero(gray0);
-
+
fillConvexPoly(gray0, line2, Scalar(0), 8, 1);
int nz2 = countNonZero(gray0)/255;
-
+
CV_Assert( nz1 == 40 && nz2 == 0 );
}
};
{
return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255);
}
-
+
const VideoFormat g_specific_fmt_list[] =
{
VideoFormat("avi", CV_FOURCC('X', 'V', 'I', 'D')),
VideoFormat("mkv", CV_FOURCC('X', 'V', 'I', 'D')),
VideoFormat("mkv", CV_FOURCC('M', 'P', 'E', 'G')),
VideoFormat("mkv", CV_FOURCC('M', 'J', 'P', 'G')),
-
+
VideoFormat("mov", CV_FOURCC('m', 'p', '4', 'v')),
VideoFormat()
};
-
+
}
class CV_HighGuiTest : public cvtest::BaseTest
if (!img)
break;
-
+
frames.push_back(Mat(img).clone());
if (writer == 0)
{
string ext = fmt.ext;
int fourcc = fmt.fourcc;
-
+
string fourcc_str = cvtest::fourccToString(fourcc);
const string video_file = "video_" + fourcc_str + "." + ext;
if (!writer.isOpened())
{
// call it repeatedly for easier debugging
- VideoWriter writer(video_file, fourcc, 25, frame_size, true);
+ VideoWriter writer2(video_file, fourcc, 25, frame_size, true);
ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str());
ts->printf(ts->LOG, "Cannot create VideoWriter object with codec %s.\n", fourcc_str.c_str());
ts->set_failed_test_info(ts->FAIL_MISMATCH);
const size_t IMAGE_COUNT = 30;
vector<Mat> images;
-
+
for( size_t i = 0; i < IMAGE_COUNT; ++i )
{
string file_path = format("%s../python/images/QCIF_%02d.bmp", dir.c_str(), i);
if (img.at<Vec3b>(k, l) == Vec3b::all(0))
img.at<Vec3b>(k, l) = Vec3b(0, 255, 0);
else img.at<Vec3b>(k, l) = Vec3b(0, 0, 255);
-
+
resize(img, img, frame_size, 0.0, 0.0, INTER_CUBIC);
images.push_back(img);
44141 Dortmund
Germany
www.md-it.de
-
+
Redistribution and use in source and binary forms,
with or without modification, are permitted provided
- that the following conditions are met:
+ that the following conditions are met:
Redistributions of source code must retain
- the above copyright notice, this list of conditions and the following disclaimer.
+ the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
+ and/or other materials provided with the distribution.
The name of Contributor may not be used to endorse or promote products
- derived from this software without specific prior written permission.
+ derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
_Tp cn = 0;
int i;
tab[0] = tab[1] = (_Tp)0;
-
+
for(i = 1; i < n-1; i++)
{
_Tp t = 3*(f[i+1] - 2*f[i] + f[i-1]);
_Tp l = 1/(4 - tab[(i-1)*4]);
tab[i*4] = l; tab[i*4+1] = (t - tab[(i-1)*4+1])*l;
}
-
+
for(i = n-1; i >= 0; i--)
{
_Tp c = tab[i*4+1] - tab[i*4]*cn;
x -= ix;
tab += ix*4;
return ((tab[3]*x + tab[2])*x + tab[1])*x + tab[0];
-}
+}
+
-
template<typename _Tp> struct ColorChannel
{
typedef float worktype_f;
static _Tp max() { return std::numeric_limits<_Tp>::max(); }
- static _Tp half() { return (_Tp)(max()/2 + 1); }
+ static _Tp half() { return (_Tp)(max()/2 + 1); }
};
template<> struct ColorChannel<float>
static double half() { return 0.5; }
};*/
-
+
///////////////////////////// Top-level template function ////////////////////////////////
template<class Cvt> void CvtColorLoop(const Mat& srcmat, Mat& dstmat, const Cvt& cvt)
const uchar* src = srcmat.data;
uchar* dst = dstmat.data;
size_t srcstep = srcmat.step, dststep = dstmat.step;
-
+
if( srcmat.isContinuous() && dstmat.isContinuous() )
{
sz.width *= sz.height;
sz.height = 1;
- }
-
+ }
+
for( ; sz.height--; src += srcstep, dst += dststep )
cvt((const _Tp*)src, (_Tp*)dst, sz.width);
}
-
-
+
+
////////////////// Various 3/4-channel to 3/4-channel RGB transformations /////////////////
-
+
template<typename _Tp> struct RGB2RGB
{
typedef _Tp channel_type;
-
+
RGB2RGB(int _srccn, int _dstcn, int _blueIdx) : srccn(_srccn), dstcn(_dstcn), blueIdx(_blueIdx) {}
void operator()(const _Tp* src, _Tp* dst, int n) const
{
}
}
}
-
+
int srccn, dstcn, blueIdx;
};
-
+
/////////// Transforming 16-bit (565 or 555) RGB to/from 24/32-bit (888[8]) RGB //////////
struct RGB5x52RGB
{
typedef uchar channel_type;
-
+
RGB5x52RGB(int _dstcn, int _blueIdx, int _greenBits)
- : dstcn(_dstcn), blueIdx(_blueIdx), greenBits(_greenBits) {}
-
+ : dstcn(_dstcn), blueIdx(_blueIdx), greenBits(_greenBits) {}
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int dcn = dstcn, bidx = blueIdx;
dst[3] = t & 0x8000 ? 255 : 0;
}
}
-
+
int dstcn, blueIdx, greenBits;
};
-
+
struct RGB2RGB5x5
{
typedef uchar channel_type;
-
+
RGB2RGB5x5(int _srccn, int _blueIdx, int _greenBits)
- : srccn(_srccn), blueIdx(_blueIdx), greenBits(_greenBits) {}
-
+ : srccn(_srccn), blueIdx(_blueIdx), greenBits(_greenBits) {}
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int scn = srccn, bidx = blueIdx;
((src[bidx^2]&~7) << 7)|(src[3] ? 0x8000 : 0));
}
}
-
+
int srccn, blueIdx, greenBits;
};
-
+
///////////////////////////////// Color to/from Grayscale ////////////////////////////////
template<typename _Tp>
struct Gray2RGB
{
typedef _Tp channel_type;
-
+
Gray2RGB(int _dstcn) : dstcn(_dstcn) {}
void operator()(const _Tp* src, _Tp* dst, int n) const
{
}
}
}
-
+
int dstcn;
};
-
+
struct Gray2RGB5x5
{
typedef uchar channel_type;
-
+
Gray2RGB5x5(int _greenBits) : greenBits(_greenBits) {}
void operator()(const uchar* src, uchar* dst, int n) const
{
#undef R2Y
#undef G2Y
#undef B2Y
-
+
enum
{
yuv_shift = 14,
struct RGB5x52Gray
{
typedef uchar channel_type;
-
+
RGB5x52Gray(int _greenBits) : greenBits(_greenBits) {}
void operator()(const uchar* src, uchar* dst, int n) const
{
template<typename _Tp> struct RGB2Gray
{
typedef _Tp channel_type;
-
+
RGB2Gray(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn)
{
static const float coeffs0[] = { 0.299f, 0.587f, 0.114f };
if(blueIdx == 0)
std::swap(coeffs[0], coeffs[2]);
}
-
+
void operator()(const _Tp* src, _Tp* dst, int n) const
{
int scn = srccn;
float coeffs[3];
};
-
+
template<> struct RGB2Gray<uchar>
{
typedef uchar channel_type;
-
+
RGB2Gray<uchar>(int _srccn, int blueIdx, const int* coeffs) : srccn(_srccn)
{
const int coeffs0[] = { R2Y, G2Y, B2Y };
if(!coeffs) coeffs = coeffs0;
-
+
int b = 0, g = 0, r = (1 << (yuv_shift-1));
int db = coeffs[blueIdx^2], dg = coeffs[1], dr = coeffs[blueIdx];
-
+
for( int i = 0; i < 256; i++, b += db, g += dg, r += dr )
{
tab[i] = b;
void operator()(const uchar* src, uchar* dst, int n) const
{
int scn = srccn;
- const int* _tab = tab;
+ const int* _tab = tab;
for(int i = 0; i < n; i++, src += scn)
dst[i] = (uchar)((_tab[src[0]] + _tab[src[1]+256] + _tab[src[2]+512]) >> yuv_shift);
}
- int srccn, blueIdx;
+ int srccn;
int tab[256*3];
};
-
+
template<> struct RGB2Gray<ushort>
{
typedef ushort channel_type;
-
+
RGB2Gray<ushort>(int _srccn, int blueIdx, const int* _coeffs) : srccn(_srccn)
{
static const int coeffs0[] = { R2Y, G2Y, B2Y };
if( blueIdx == 0 )
std::swap(coeffs[0], coeffs[2]);
}
-
+
void operator()(const ushort* src, ushort* dst, int n) const
{
int scn = srccn, cb = coeffs[0], cg = coeffs[1], cr = coeffs[2];
int coeffs[3];
};
-
+
///////////////////////////////////// RGB <-> YCrCb //////////////////////////////////////
template<typename _Tp> struct RGB2YCrCb_f
{
typedef _Tp channel_type;
-
+
RGB2YCrCb_f(int _srccn, int _blueIdx, const float* _coeffs) : srccn(_srccn), blueIdx(_blueIdx)
- {
- static const float coeffs0[] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f};
- memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
- if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
- }
-
+ {
+ static const float coeffs0[] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f};
+ memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
+ if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
+ }
+
void operator()(const _Tp* src, _Tp* dst, int n) const
{
int scn = srccn, bidx = blueIdx;
const _Tp delta = ColorChannel<_Tp>::half();
- float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
+ float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
n *= 3;
for(int i = 0; i < n; i += 3, src += scn)
{
}
}
int srccn, blueIdx;
- float coeffs[5];
+ float coeffs[5];
};
template<typename _Tp> struct RGB2YCrCb_i
{
typedef _Tp channel_type;
-
+
RGB2YCrCb_i(int _srccn, int _blueIdx, const int* _coeffs)
- : srccn(_srccn), blueIdx(_blueIdx)
- {
- static const int coeffs0[] = {R2Y, G2Y, B2Y, 11682, 9241};
- memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
- if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
- }
+ : srccn(_srccn), blueIdx(_blueIdx)
+ {
+ static const int coeffs0[] = {R2Y, G2Y, B2Y, 11682, 9241};
+ memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
+ if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
+ }
void operator()(const _Tp* src, _Tp* dst, int n) const
{
int scn = srccn, bidx = blueIdx;
- int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
+ int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift);
n *= 3;
for(int i = 0; i < n; i += 3, src += scn)
}
}
int srccn, blueIdx;
- int coeffs[5];
-};
+ int coeffs[5];
+};
template<typename _Tp> struct YCrCb2RGB_f
{
typedef _Tp channel_type;
-
+
YCrCb2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs)
- : dstcn(_dstcn), blueIdx(_blueIdx)
- {
- static const float coeffs0[] = {1.403f, -0.714f, -0.344f, 1.773f};
- memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
- }
+ : dstcn(_dstcn), blueIdx(_blueIdx)
+ {
+ static const float coeffs0[] = {1.403f, -0.714f, -0.344f, 1.773f};
+ memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
+ }
void operator()(const _Tp* src, _Tp* dst, int n) const
{
int dcn = dstcn, bidx = blueIdx;
_Tp Y = src[i];
_Tp Cr = src[i+1];
_Tp Cb = src[i+2];
-
+
_Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3);
_Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1);
_Tp r = saturate_cast<_Tp>(Y + (Cr - delta)*C0);
-
+
dst[bidx] = b; dst[1] = g; dst[bidx^2] = r;
if( dcn == 4 )
dst[3] = alpha;
}
}
int dstcn, blueIdx;
- float coeffs[4];
-};
+ float coeffs[4];
+};
template<typename _Tp> struct YCrCb2RGB_i
{
typedef _Tp channel_type;
-
+
YCrCb2RGB_i(int _dstcn, int _blueIdx, const int* _coeffs)
: dstcn(_dstcn), blueIdx(_blueIdx)
{
- static const int coeffs0[] = {22987, -11698, -5636, 29049};
- memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
+ static const int coeffs0[] = {22987, -11698, -5636, 29049};
+ memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
}
-
+
void operator()(const _Tp* src, _Tp* dst, int n) const
{
int dcn = dstcn, bidx = blueIdx;
_Tp Y = src[i];
_Tp Cr = src[i+1];
_Tp Cb = src[i+2];
-
+
int b = Y + CV_DESCALE((Cb - delta)*C3, yuv_shift);
int g = Y + CV_DESCALE((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift);
int r = Y + CV_DESCALE((Cr - delta)*C0, yuv_shift);
-
+
dst[bidx] = saturate_cast<_Tp>(b);
dst[1] = saturate_cast<_Tp>(g);
dst[bidx^2] = saturate_cast<_Tp>(r);
}
int dstcn, blueIdx;
int coeffs[4];
-};
+};
+
-
////////////////////////////////////// RGB <-> XYZ ///////////////////////////////////////
static const float sRGB2XYZ_D65[] =
0.212671f, 0.715160f, 0.072169f,
0.019334f, 0.119193f, 0.950227f
};
-
+
static const float XYZ2sRGB_D65[] =
{
3.240479f, -1.53715f, -0.498535f,
-0.969256f, 1.875991f, 0.041556f,
0.055648f, -0.204043f, 1.057311f
};
-
+
template<typename _Tp> struct RGB2XYZ_f
{
typedef _Tp channel_type;
-
+
RGB2XYZ_f(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn)
{
memcpy(coeffs, _coeffs ? _coeffs : sRGB2XYZ_D65, 9*sizeof(coeffs[0]));
float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2],
C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5],
C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8];
-
+
n *= 3;
for(int i = 0; i < n; i += 3, src += scn)
{
- _Tp X = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2);
- _Tp Y = saturate_cast<_Tp>(src[0]*C3 + src[1]*C4 + src[2]*C5);
- _Tp Z = saturate_cast<_Tp>(src[0]*C6 + src[1]*C7 + src[2]*C8);
+ _Tp X = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2);
+ _Tp Y = saturate_cast<_Tp>(src[0]*C3 + src[1]*C4 + src[2]*C5);
+ _Tp Z = saturate_cast<_Tp>(src[0]*C6 + src[1]*C7 + src[2]*C8);
dst[i] = X; dst[i+1] = Y; dst[i+2] = Z;
}
}
template<typename _Tp> struct RGB2XYZ_i
{
typedef _Tp channel_type;
-
+
RGB2XYZ_i(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn)
{
static const int coeffs0[] =
{
- 1689, 1465, 739,
- 871, 2929, 296,
+ 1689, 1465, 739,
+ 871, 2929, 296,
79, 488, 3892
};
for( int i = 0; i < 9; i++ )
int srccn;
int coeffs[9];
};
-
-
+
+
template<typename _Tp> struct XYZ2RGB_f
{
typedef _Tp channel_type;
-
+
XYZ2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs)
: dstcn(_dstcn), blueIdx(_blueIdx)
{
std::swap(coeffs[2], coeffs[8]);
}
}
-
+
void operator()(const _Tp* src, _Tp* dst, int n) const
{
int dcn = dstcn;
- _Tp alpha = ColorChannel<_Tp>::max();
+ _Tp alpha = ColorChannel<_Tp>::max();
float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2],
C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5],
C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8];
n *= 3;
for(int i = 0; i < n; i += 3, dst += dcn)
{
- _Tp B = saturate_cast<_Tp>(src[i]*C0 + src[i+1]*C1 + src[i+2]*C2);
- _Tp G = saturate_cast<_Tp>(src[i]*C3 + src[i+1]*C4 + src[i+2]*C5);
- _Tp R = saturate_cast<_Tp>(src[i]*C6 + src[i+1]*C7 + src[i+2]*C8);
+ _Tp B = saturate_cast<_Tp>(src[i]*C0 + src[i+1]*C1 + src[i+2]*C2);
+ _Tp G = saturate_cast<_Tp>(src[i]*C3 + src[i+1]*C4 + src[i+2]*C5);
+ _Tp R = saturate_cast<_Tp>(src[i]*C6 + src[i+1]*C7 + src[i+2]*C8);
dst[0] = B; dst[1] = G; dst[2] = R;
- if( dcn == 4 )
- dst[3] = alpha;
+ if( dcn == 4 )
+ dst[3] = alpha;
}
}
int dstcn, blueIdx;
template<typename _Tp> struct XYZ2RGB_i
{
typedef _Tp channel_type;
-
+
XYZ2RGB_i(int _dstcn, int _blueIdx, const int* _coeffs)
: dstcn(_dstcn), blueIdx(_blueIdx)
{
static const int coeffs0[] =
{
- 13273, -6296, -2042,
- -3970, 7684, 170,
+ 13273, -6296, -2042,
+ -3970, 7684, 170,
228, -836, 4331
};
for(int i = 0; i < 9; i++)
coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << xyz_shift)) : coeffs0[i];
-
+
if(blueIdx == 0)
{
std::swap(coeffs[0], coeffs[6]);
dst[0] = saturate_cast<_Tp>(B); dst[1] = saturate_cast<_Tp>(G);
dst[2] = saturate_cast<_Tp>(R);
if( dcn == 4 )
- dst[3] = alpha;
+ dst[3] = alpha;
}
}
int dstcn, blueIdx;
int coeffs[9];
};
-
+
////////////////////////////////////// RGB <-> HSV ///////////////////////////////////////
struct RGB2HSV_b
{
typedef uchar channel_type;
-
+
RGB2HSV_b(int _srccn, int _blueIdx, int _hrange)
: srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange)
{
CV_Assert( hrange == 180 || hrange == 256 );
}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int i, bidx = blueIdx, scn = srccn;
const int hsv_shift = 12;
-
+
static int sdiv_table[256];
static int hdiv_table180[256];
static int hdiv_table256[256];
static volatile bool initialized = false;
-
+
int hr = hrange;
const int* hdiv_table = hr == 180 ? hdiv_table180 : hdiv_table256;
n *= 3;
-
+
if( !initialized )
{
sdiv_table[0] = hdiv_table180[0] = hdiv_table256[0] = 0;
}
initialized = true;
}
-
+
for( i = 0; i < n; i += 3, src += scn )
{
int b = src[bidx], g = src[1], r = src[bidx^2];
int h, s, v = b;
int vmin = b, diff;
int vr, vg;
-
+
CV_CALC_MAX_8U( v, g );
CV_CALC_MAX_8U( v, r );
CV_CALC_MIN_8U( vmin, g );
CV_CALC_MIN_8U( vmin, r );
-
+
diff = v - vmin;
vr = v == r ? -1 : 0;
vg = v == g ? -1 : 0;
-
+
s = (diff * sdiv_table[v] + (1 << (hsv_shift-1))) >> hsv_shift;
h = (vr & (g - b)) +
(~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff))));
h = (h * hdiv_table[diff] + (1 << (hsv_shift-1))) >> hsv_shift;
h += h < 0 ? hr : 0;
-
+
dst[i] = saturate_cast<uchar>(h);
dst[i+1] = (uchar)s;
dst[i+2] = (uchar)v;
}
}
-
+
int srccn, blueIdx, hrange;
-};
+};
+
-
struct RGB2HSV_f
{
typedef float channel_type;
-
+
RGB2HSV_f(int _srccn, int _blueIdx, float _hrange)
: srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange) {}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, bidx = blueIdx, scn = srccn;
float hscale = hrange*(1.f/360.f);
n *= 3;
-
+
for( i = 0; i < n; i += 3, src += scn )
{
float b = src[bidx], g = src[1], r = src[bidx^2];
float h, s, v;
-
+
float vmin, diff;
-
+
v = vmin = r;
if( v < g ) v = g;
if( v < b ) v = b;
if( vmin > g ) vmin = g;
if( vmin > b ) vmin = b;
-
+
diff = v - vmin;
s = diff/(float)(fabs(v) + FLT_EPSILON);
diff = (float)(60./(diff + FLT_EPSILON));
h = (b - r)*diff + 120.f;
else
h = (r - g)*diff + 240.f;
-
+
if( h < 0 ) h += 360.f;
-
+
dst[i] = h*hscale;
dst[i+1] = s;
dst[i+2] = v;
}
}
-
+
int srccn, blueIdx;
float hrange;
};
struct HSV2RGB_f
{
typedef float channel_type;
-
+
HSV2RGB_f(int _dstcn, int _blueIdx, float _hrange)
: dstcn(_dstcn), blueIdx(_blueIdx), hscale(6.f/_hrange) {}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, bidx = blueIdx, dcn = dstcn;
float _hscale = hscale;
float alpha = ColorChannel<float>::max();
n *= 3;
-
+
for( i = 0; i < n; i += 3, dst += dcn )
{
float h = src[i], s = src[i+1], v = src[i+2];
tab[1] = v*(1.f - s);
tab[2] = v*(1.f - s*h);
tab[3] = v*(1.f - s*(1.f - h));
-
+
b = tab[sector_data[sector][0]];
g = tab[sector_data[sector][1]];
r = tab[sector_data[sector][2]];
int dstcn, blueIdx;
float hscale;
};
-
+
struct HSV2RGB_b
{
typedef uchar channel_type;
-
+
HSV2RGB_b(int _dstcn, int _blueIdx, int _hrange)
: dstcn(_dstcn), cvt(3, _blueIdx, (float)_hrange)
{}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int i, j, dcn = dstcn;
uchar alpha = ColorChannel<uchar>::max();
float buf[3*BLOCK_SIZE];
-
+
for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 )
{
int dn = std::min(n - i, (int)BLOCK_SIZE);
-
+
for( j = 0; j < dn*3; j += 3 )
{
buf[j] = src[j];
buf[j+2] = src[j+2]*(1.f/255.f);
}
cvt(buf, buf, dn);
-
+
for( j = 0; j < dn*3; j += 3, dst += dcn )
{
dst[0] = saturate_cast<uchar>(buf[j]*255.f);
}
}
}
-
+
int dstcn;
HSV2RGB_f cvt;
};
-
+
///////////////////////////////////// RGB <-> HLS ////////////////////////////////////////
struct RGB2HLS_f
{
typedef float channel_type;
-
+
RGB2HLS_f(int _srccn, int _blueIdx, float _hrange)
: srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange) {}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, bidx = blueIdx, scn = srccn;
float hscale = hrange*(1.f/360.f);
n *= 3;
-
+
for( i = 0; i < n; i += 3, src += scn )
{
float b = src[bidx], g = src[1], r = src[bidx^2];
float h = 0.f, s = 0.f, l;
float vmin, vmax, diff;
-
+
vmax = vmin = r;
if( vmax < g ) vmax = g;
if( vmax < b ) vmax = b;
if( vmin > g ) vmin = g;
if( vmin > b ) vmin = b;
-
+
diff = vmax - vmin;
l = (vmax + vmin)*0.5f;
-
+
if( diff > FLT_EPSILON )
{
s = l < 0.5f ? diff/(vmax + vmin) : diff/(2 - vmax - vmin);
diff = 60.f/diff;
-
+
if( vmax == r )
h = (g - b)*diff;
else if( vmax == g )
h = (b - r)*diff + 120.f;
else
h = (r - g)*diff + 240.f;
-
+
if( h < 0.f ) h += 360.f;
}
-
+
dst[i] = h*hscale;
dst[i+1] = l;
dst[i+2] = s;
}
}
-
+
int srccn, blueIdx;
float hrange;
};
-
-
+
+
struct RGB2HLS_b
{
typedef uchar channel_type;
-
+
RGB2HLS_b(int _srccn, int _blueIdx, int _hrange)
: srccn(_srccn), cvt(3, _blueIdx, (float)_hrange) {}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int i, j, scn = srccn;
float buf[3*BLOCK_SIZE];
-
+
for( i = 0; i < n; i += BLOCK_SIZE, dst += BLOCK_SIZE*3 )
{
int dn = std::min(n - i, (int)BLOCK_SIZE);
-
+
for( j = 0; j < dn*3; j += 3, src += scn )
{
buf[j] = src[0]*(1.f/255.f);
buf[j+2] = src[2]*(1.f/255.f);
}
cvt(buf, buf, dn);
-
+
for( j = 0; j < dn*3; j += 3 )
{
dst[j] = saturate_cast<uchar>(buf[j]);
}
}
}
-
+
int srccn;
RGB2HLS_f cvt;
};
-
+
struct HLS2RGB_f
{
typedef float channel_type;
-
+
HLS2RGB_f(int _dstcn, int _blueIdx, float _hrange)
: dstcn(_dstcn), blueIdx(_blueIdx), hscale(6.f/_hrange) {}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, bidx = blueIdx, dcn = dstcn;
float _hscale = hscale;
float alpha = ColorChannel<float>::max();
n *= 3;
-
+
for( i = 0; i < n; i += 3, dst += dcn )
{
float h = src[i], l = src[i+1], s = src[i+2];
float b, g, r;
-
+
if( s == 0 )
b = g = r = l;
else
{{1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0}};
float tab[4];
int sector;
-
+
float p2 = l <= 0.5f ? l*(1 + s) : l + s - l*s;
float p1 = 2*l - p2;
-
+
h *= _hscale;
if( h < 0 )
do h += 6; while( h < 0 );
else if( h >= 6 )
do h -= 6; while( h >= 6 );
-
+
assert( 0 <= h && h < 6 );
sector = cvFloor(h);
h -= sector;
-
+
tab[0] = p2;
tab[1] = p1;
tab[2] = p1 + (p2 - p1)*(1-h);
tab[3] = p1 + (p2 - p1)*h;
-
+
b = tab[sector_data[sector][0]];
g = tab[sector_data[sector][1]];
r = tab[sector_data[sector][2]];
}
-
+
dst[bidx] = b;
dst[1] = g;
dst[bidx^2] = r;
dst[3] = alpha;
}
}
-
+
int dstcn, blueIdx;
float hscale;
};
-
+
struct HLS2RGB_b
{
typedef uchar channel_type;
-
+
HLS2RGB_b(int _dstcn, int _blueIdx, int _hrange)
: dstcn(_dstcn), cvt(3, _blueIdx, (float)_hrange)
{}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int i, j, dcn = dstcn;
uchar alpha = ColorChannel<uchar>::max();
float buf[3*BLOCK_SIZE];
-
+
for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 )
{
int dn = std::min(n - i, (int)BLOCK_SIZE);
-
+
for( j = 0; j < dn*3; j += 3 )
{
buf[j] = src[j];
buf[j+2] = src[j+2]*(1.f/255.f);
}
cvt(buf, buf, dn);
-
+
for( j = 0; j < dn*3; j += 3, dst += dcn )
{
dst[0] = saturate_cast<uchar>(buf[j]*255.f);
}
}
}
-
+
int dstcn;
HLS2RGB_f cvt;
};
-
+
///////////////////////////////////// RGB <-> L*a*b* /////////////////////////////////////
static const float D65[] = { 0.950456f, 1.f, 1.088754f };
static float sRGBGammaTab[GAMMA_TAB_SIZE*4], sRGBInvGammaTab[GAMMA_TAB_SIZE*4];
static const float GammaTabScale = (float)GAMMA_TAB_SIZE;
-
-static ushort sRGBGammaTab_b[256], linearGammaTab_b[256];
+
+static ushort sRGBGammaTab_b[256], linearGammaTab_b[256];
#undef lab_shift
#define lab_shift xyz_shift
#define gamma_shift 3
#define lab_shift2 (lab_shift + gamma_shift)
#define LAB_CBRT_TAB_SIZE_B (256*3/2*(1<<gamma_shift))
static ushort LabCbrtTab_b[LAB_CBRT_TAB_SIZE_B];
-
+
static void initLabTabs()
{
static bool initialized = false;
f[i] = x < 0.008856f ? x*7.787f + 0.13793103448275862f : cvCbrt(x);
}
splineBuild(f, LAB_CBRT_TAB_SIZE, LabCbrtTab);
-
+
scale = 1.f/GammaTabScale;
for(i = 0; i <= GAMMA_TAB_SIZE; i++)
{
}
splineBuild(g, GAMMA_TAB_SIZE, sRGBGammaTab);
splineBuild(ig, GAMMA_TAB_SIZE, sRGBInvGammaTab);
-
+
for(i = 0; i < 256; i++)
{
float x = i*(1.f/255.f);
sRGBGammaTab_b[i] = saturate_cast<ushort>(255.f*(1 << gamma_shift)*(x <= 0.04045f ? x*(1.f/12.92f) : (float)pow((double)(x + 0.055)*(1./1.055), 2.4)));
linearGammaTab_b[i] = (ushort)(i*(1 << gamma_shift));
}
-
+
for(i = 0; i < LAB_CBRT_TAB_SIZE_B; i++)
{
float x = i*(1.f/(255.f*(1 << gamma_shift)));
struct RGB2Lab_b
{
typedef uchar channel_type;
-
+
RGB2Lab_b(int _srccn, int blueIdx, const float* _coeffs,
const float* _whitept, bool _srgb)
: srccn(_srccn), srgb(_srgb)
{
static volatile int _3 = 3;
initLabTabs();
-
+
if(!_coeffs) _coeffs = sRGB2XYZ_D65;
if(!_whitept) _whitept = D65;
float scale[] =
(float)(1 << lab_shift),
(1 << lab_shift)/_whitept[2]
};
-
+
for( int i = 0; i < _3; i++ )
{
coeffs[i*3+(blueIdx^2)] = cvRound(_coeffs[i*3]*scale[i]);
coeffs[i*3+1] = cvRound(_coeffs[i*3+1]*scale[i]);
coeffs[i*3+blueIdx] = cvRound(_coeffs[i*3+2]*scale[i]);
-
+
CV_Assert( coeffs[i] >= 0 && coeffs[i*3+1] >= 0 && coeffs[i*3+2] >= 0 &&
coeffs[i*3] + coeffs[i*3+1] + coeffs[i*3+2] < 2*(1 << lab_shift) );
}
}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
const int Lscale = (116*255+50)/100;
C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5],
C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8];
n *= 3;
-
+
for( i = 0; i < n; i += 3, src += scn )
{
int R = tab[src[0]], G = tab[src[1]], B = tab[src[2]];
int fX = LabCbrtTab_b[CV_DESCALE(R*C0 + G*C1 + B*C2, lab_shift)];
int fY = LabCbrtTab_b[CV_DESCALE(R*C3 + G*C4 + B*C5, lab_shift)];
int fZ = LabCbrtTab_b[CV_DESCALE(R*C6 + G*C7 + B*C8, lab_shift)];
-
+
int L = CV_DESCALE( Lscale*fY + Lshift, lab_shift2 );
int a = CV_DESCALE( 500*(fX - fY) + 128*(1 << lab_shift2), lab_shift2 );
int b = CV_DESCALE( 200*(fY - fZ) + 128*(1 << lab_shift2), lab_shift2 );
-
+
dst[i] = saturate_cast<uchar>(L);
dst[i+1] = saturate_cast<uchar>(a);
dst[i+2] = saturate_cast<uchar>(b);
}
}
-
+
int srccn;
int coeffs[9];
bool srgb;
};
-
-
+
+
struct RGB2Lab_f
{
typedef float channel_type;
-
+
RGB2Lab_f(int _srccn, int blueIdx, const float* _coeffs,
const float* _whitept, bool _srgb)
: srccn(_srccn), srgb(_srgb)
{
volatile int _3 = 3;
initLabTabs();
-
+
if(!_coeffs) _coeffs = sRGB2XYZ_D65;
if(!_whitept) _whitept = D65;
float scale[] = { LabCbrtTabScale/_whitept[0], LabCbrtTabScale, LabCbrtTabScale/_whitept[2] };
-
+
for( int i = 0; i < _3; i++ )
{
coeffs[i*3+(blueIdx^2)] = _coeffs[i*3]*scale[i];
coeffs[i*3] + coeffs[i*3+1] + coeffs[i*3+2] < 1.5f*LabCbrtTabScale );
}
}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, scn = srccn;
C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5],
C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8];
n *= 3;
-
+
for( i = 0; i < n; i += 3, src += scn )
{
float R = src[0], G = src[1], B = src[2];
G = splineInterpolate(G*gscale, gammaTab, GAMMA_TAB_SIZE);
B = splineInterpolate(B*gscale, gammaTab, GAMMA_TAB_SIZE);
}
- float fX = splineInterpolate(R*C0 + G*C1 + B*C2, LabCbrtTab, LAB_CBRT_TAB_SIZE);
+ float fX = splineInterpolate(R*C0 + G*C1 + B*C2, LabCbrtTab, LAB_CBRT_TAB_SIZE);
float fY = splineInterpolate(R*C3 + G*C4 + B*C5, LabCbrtTab, LAB_CBRT_TAB_SIZE);
float fZ = splineInterpolate(R*C6 + G*C7 + B*C8, LabCbrtTab, LAB_CBRT_TAB_SIZE);
-
+
float L = 116.f*fY - 16.f;
float a = 500.f*(fX - fY);
float b = 200.f*(fY - fZ);
-
+
dst[i] = L; dst[i+1] = a; dst[i+2] = b;
}
}
-
+
int srccn;
float coeffs[9];
bool srgb;
};
-
+
struct Lab2RGB_f
{
typedef float channel_type;
-
+
Lab2RGB_f( int _dstcn, int blueIdx, const float* _coeffs,
const float* _whitept, bool _srgb )
: dstcn(_dstcn), srgb(_srgb)
{
initLabTabs();
-
+
if(!_coeffs) _coeffs = XYZ2sRGB_D65;
if(!_whitept) _whitept = D65;
-
+
for( int i = 0; i < 3; i++ )
{
coeffs[i+(blueIdx^2)*3] = _coeffs[i]*_whitept[i];
coeffs[i+blueIdx*3] = _coeffs[i+6]*_whitept[i];
}
}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, dcn = dstcn;
C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8];
float alpha = ColorChannel<float>::max();
n *= 3;
-
+
for( i = 0; i < n; i += 3, dst += dcn )
{
float L = src[i], a = src[i+1], b = src[i+2];
Y = Y*Y*Y;
X = X*X*X;
Z = Z*Z*Z;
-
+
float R = X*C0 + Y*C1 + Z*C2;
float G = X*C3 + Y*C4 + Z*C5;
float B = X*C6 + Y*C7 + Z*C8;
-
+
if( gammaTab )
{
R = splineInterpolate(R*gscale, gammaTab, GAMMA_TAB_SIZE);
G = splineInterpolate(G*gscale, gammaTab, GAMMA_TAB_SIZE);
B = splineInterpolate(B*gscale, gammaTab, GAMMA_TAB_SIZE);
}
-
+
dst[0] = R; dst[1] = G; dst[2] = B;
if( dcn == 4 )
dst[3] = alpha;
}
}
-
+
int dstcn;
float coeffs[9];
bool srgb;
};
-
+
struct Lab2RGB_b
{
typedef uchar channel_type;
-
+
Lab2RGB_b( int _dstcn, int blueIdx, const float* _coeffs,
const float* _whitept, bool _srgb )
: dstcn(_dstcn), cvt(3, blueIdx, _coeffs, _whitept, _srgb ) {}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int i, j, dcn = dstcn;
uchar alpha = ColorChannel<uchar>::max();
float buf[3*BLOCK_SIZE];
-
+
for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 )
{
int dn = std::min(n - i, (int)BLOCK_SIZE);
-
+
for( j = 0; j < dn*3; j += 3 )
{
buf[j] = src[j]*(100.f/255.f);
buf[j+2] = (float)(src[j+2] - 128);
}
cvt(buf, buf, dn);
-
+
for( j = 0; j < dn*3; j += 3, dst += dcn )
{
dst[0] = saturate_cast<uchar>(buf[j]*255.f);
}
}
}
-
+
int dstcn;
Lab2RGB_f cvt;
};
-
-
+
+
///////////////////////////////////// RGB <-> L*u*v* /////////////////////////////////////
struct RGB2Luv_f
{
typedef float channel_type;
-
+
RGB2Luv_f( int _srccn, int blueIdx, const float* _coeffs,
const float* whitept, bool _srgb )
: srccn(_srccn), srgb(_srgb)
{
- volatile int i;
+ volatile int i;
initLabTabs();
-
+
if(!_coeffs) _coeffs = sRGB2XYZ_D65;
if(!whitept) whitept = D65;
-
+
for( i = 0; i < 3; i++ )
{
coeffs[i*3] = _coeffs[i*3];
CV_Assert( coeffs[i*3] >= 0 && coeffs[i*3+1] >= 0 && coeffs[i*3+2] >= 0 &&
coeffs[i*3] + coeffs[i*3+1] + coeffs[i*3+2] < 1.5f );
}
-
+
float d = 1.f/(whitept[0] + whitept[1]*15 + whitept[2]*3);
un = 4*whitept[0]*d;
vn = 9*whitept[1]*d;
-
+
CV_Assert(whitept[1] == 1.f);
}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, scn = srccn;
C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8];
float _un = 13*un, _vn = 13*vn;
n *= 3;
-
+
for( i = 0; i < n; i += 3, src += scn )
{
float R = src[0], G = src[1], B = src[2];
G = splineInterpolate(G*gscale, gammaTab, GAMMA_TAB_SIZE);
B = splineInterpolate(B*gscale, gammaTab, GAMMA_TAB_SIZE);
}
-
+
float X = R*C0 + G*C1 + B*C2;
float Y = R*C3 + G*C4 + B*C5;
float Z = R*C6 + G*C7 + B*C8;
-
+
float L = splineInterpolate(Y*LabCbrtTabScale, LabCbrtTab, LAB_CBRT_TAB_SIZE);
L = 116.f*L - 16.f;
-
- float d = (4*13) / std::max(X + 15 * Y + 3 * Z, FLT_EPSILON);
+
+ float d = (4*13) / std::max(X + 15 * Y + 3 * Z, FLT_EPSILON);
float u = L*(X*d - _un);
float v = L*((9*0.25f)*Y*d - _vn);
-
+
dst[i] = L; dst[i+1] = u; dst[i+2] = v;
}
}
-
+
int srccn;
float coeffs[9], un, vn;
bool srgb;
};
-
+
struct Luv2RGB_f
{
typedef float channel_type;
-
+
Luv2RGB_f( int _dstcn, int blueIdx, const float* _coeffs,
const float* whitept, bool _srgb )
: dstcn(_dstcn), srgb(_srgb)
{
initLabTabs();
-
+
if(!_coeffs) _coeffs = XYZ2sRGB_D65;
if(!whitept) whitept = D65;
-
+
for( int i = 0; i < 3; i++ )
{
coeffs[i+(blueIdx^2)*3] = _coeffs[i];
coeffs[i+3] = _coeffs[i+3];
coeffs[i+blueIdx*3] = _coeffs[i+6];
}
-
+
float d = 1.f/(whitept[0] + whitept[1]*15 + whitept[2]*3);
un = 4*whitept[0]*d;
vn = 9*whitept[1]*d;
-
+
CV_Assert(whitept[1] == 1.f);
}
-
+
void operator()(const float* src, float* dst, int n) const
{
int i, dcn = dstcn;
float alpha = ColorChannel<float>::max();
float _un = un, _vn = vn;
n *= 3;
-
+
for( i = 0; i < n; i += 3, dst += dcn )
{
float L = src[i], u = src[i+1], v = src[i+2], d, X, Y, Z;
v = v*d + _vn;
float iv = 1.f/v;
X = 2.25f * u * Y * iv ;
- Z = (12 - 3 * u - 20 * v) * Y * 0.25f * iv;
-
+ Z = (12 - 3 * u - 20 * v) * Y * 0.25f * iv;
+
float R = X*C0 + Y*C1 + Z*C2;
float G = X*C3 + Y*C4 + Z*C5;
float B = X*C6 + Y*C7 + Z*C8;
-
+
if( gammaTab )
{
R = splineInterpolate(R*gscale, gammaTab, GAMMA_TAB_SIZE);
G = splineInterpolate(G*gscale, gammaTab, GAMMA_TAB_SIZE);
B = splineInterpolate(B*gscale, gammaTab, GAMMA_TAB_SIZE);
}
-
+
dst[0] = R; dst[1] = G; dst[2] = B;
if( dcn == 4 )
dst[3] = alpha;
}
}
-
+
int dstcn;
float coeffs[9], un, vn;
bool srgb;
};
-
+
struct RGB2Luv_b
{
typedef uchar channel_type;
-
+
RGB2Luv_b( int _srccn, int blueIdx, const float* _coeffs,
const float* _whitept, bool _srgb )
: srccn(_srccn), cvt(3, blueIdx, _coeffs, _whitept, _srgb) {}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int i, j, scn = srccn;
float buf[3*BLOCK_SIZE];
-
+
for( i = 0; i < n; i += BLOCK_SIZE, dst += BLOCK_SIZE*3 )
{
int dn = std::min(n - i, (int)BLOCK_SIZE);
-
+
for( j = 0; j < dn*3; j += 3, src += scn )
{
buf[j] = src[0]*(1.f/255.f);
buf[j+2] = (float)(src[2]*(1.f/255.f));
}
cvt(buf, buf, dn);
-
+
for( j = 0; j < dn*3; j += 3 )
{
dst[j] = saturate_cast<uchar>(buf[j]*2.55f);
}
}
}
-
+
int srccn;
RGB2Luv_f cvt;
};
-
+
struct Luv2RGB_b
{
typedef uchar channel_type;
-
+
Luv2RGB_b( int _dstcn, int blueIdx, const float* _coeffs,
const float* _whitept, bool _srgb )
: dstcn(_dstcn), cvt(3, blueIdx, _coeffs, _whitept, _srgb ) {}
-
+
void operator()(const uchar* src, uchar* dst, int n) const
{
int i, j, dcn = dstcn;
uchar alpha = ColorChannel<uchar>::max();
float buf[3*BLOCK_SIZE];
-
+
for( i = 0; i < n; i += BLOCK_SIZE, src += BLOCK_SIZE*3 )
{
int dn = std::min(n - i, (int)BLOCK_SIZE);
-
+
for( j = 0; j < dn*3; j += 3 )
{
buf[j] = src[j]*(100.f/255.f);
buf[j+2] = (float)(src[j+2]*1.003921568627451f - 140.f);
}
cvt(buf, buf, dn);
-
+
for( j = 0; j < dn*3; j += 3, dst += dcn )
{
dst[0] = saturate_cast<uchar>(buf[j]*255.f);
}
}
}
-
+
int dstcn;
Luv2RGB_f cvt;
};
-
+
//////////////////////////// Bayer Pattern -> RGB conversion /////////////////////////////
template<typename T>
{
return 0;
}
-
+
int bayer2RGB(const T*, int, T*, int, int) const
{
return 0;
}
-};
-
+};
+
#if CV_SSE2
class SIMDBayerInterpolator_8u
{
{
use_simd = checkHardwareSupport(CV_CPU_SSE2);
}
-
+
int bayer2Gray(const uchar* bayer, int bayer_step, uchar* dst,
int width, int bcoeff, int gcoeff, int rcoeff) const
{
if( !use_simd )
return 0;
-
+
__m128i _b2y = _mm_set1_epi16((short)(rcoeff*2));
__m128i _g2y = _mm_set1_epi16((short)(gcoeff*2));
__m128i _r2y = _mm_set1_epi16((short)(bcoeff*2));
const uchar* bayer_end = bayer + width;
-
+
for( ; bayer <= bayer_end - 18; bayer += 14, dst += 14 )
{
__m128i r0 = _mm_loadu_si128((const __m128i*)bayer);
__m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step));
__m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2));
-
+
__m128i b1 = _mm_add_epi16(_mm_srli_epi16(_mm_slli_epi16(r0, 8), 7),
_mm_srli_epi16(_mm_slli_epi16(r2, 8), 7));
__m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2));
b1 = _mm_slli_epi16(_mm_srli_si128(b1, 2), 1);
-
+
__m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 7), _mm_srli_epi16(r2, 7));
__m128i g1 = _mm_srli_epi16(_mm_slli_epi16(r1, 8), 7);
g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2)));
g1 = _mm_slli_epi16(_mm_srli_si128(g1, 2), 2);
-
+
r0 = _mm_srli_epi16(r1, 8);
r1 = _mm_slli_epi16(_mm_add_epi16(r0, _mm_srli_si128(r0, 2)), 2);
r0 = _mm_slli_epi16(r0, 3);
g0 = _mm_unpacklo_epi8(g0, g1);
_mm_storeu_si128((__m128i*)dst, g0);
}
-
+
return (int)(bayer - (bayer_end - width));
}
-
+
int bayer2RGB(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const
{
if( !use_simd )
__m128i mask = _mm_set1_epi16(blue < 0 ? -1 : 0), z = _mm_setzero_si128();
__m128i masklo = _mm_set1_epi16(0x00ff);
const uchar* bayer_end = bayer + width;
-
+
for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 )
{
__m128i r0 = _mm_loadu_si128((const __m128i*)bayer);
__m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step));
__m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2));
-
+
__m128i b1 = _mm_add_epi16(_mm_and_si128(r0, masklo), _mm_and_si128(r2, masklo));
__m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2));
b1 = _mm_srli_si128(b1, 2);
b1 = _mm_srli_epi16(_mm_add_epi16(b1, delta1), 1);
b0 = _mm_srli_epi16(_mm_add_epi16(b0, delta2), 2);
b0 = _mm_packus_epi16(b0, b1);
-
+
__m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8));
__m128i g1 = _mm_and_si128(r1, masklo);
g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2)));
g1 = _mm_srli_si128(g1, 2);
g0 = _mm_srli_epi16(_mm_add_epi16(g0, delta2), 2);
g0 = _mm_packus_epi16(g0, g1);
-
+
r0 = _mm_srli_epi16(r1, 8);
r1 = _mm_add_epi16(r0, _mm_srli_si128(r0, 2));
r1 = _mm_srli_epi16(_mm_add_epi16(r1, delta1), 1);
r0 = _mm_packus_epi16(r0, r1);
-
+
b1 = _mm_and_si128(_mm_xor_si128(b0, r0), mask);
b0 = _mm_xor_si128(b0, b1);
r0 = _mm_xor_si128(r0, b1);
-
+
// b1 g1 b1 g1 ...
b1 = _mm_unpackhi_epi8(b0, g0);
// b0 g0 b2 g2 b4 g4 ....
b0 = _mm_unpacklo_epi8(b0, g0);
-
+
// r1 0 r3 0 ...
r1 = _mm_unpackhi_epi8(r0, z);
// r0 0 r2 0 r4 0 ...
r0 = _mm_unpacklo_epi8(r0, z);
-
+
// 0 b0 g0 r0 0 b2 g2 r2 0 ...
g0 = _mm_slli_si128(_mm_unpacklo_epi16(b0, r0), 1);
// 0 b8 g8 r8 0 b10 g10 r10 0 ...
g1 = _mm_slli_si128(_mm_unpackhi_epi16(b0, r0), 1);
-
+
// b1 g1 r1 0 b3 g3 r3 ....
r0 = _mm_unpacklo_epi16(b1, r1);
// b9 g9 r9 0 ...
r1 = _mm_unpackhi_epi16(b1, r1);
-
+
b0 = _mm_srli_si128(_mm_unpacklo_epi32(g0, r0), 1);
b1 = _mm_srli_si128(_mm_unpackhi_epi32(g0, r0), 1);
-
+
_mm_storel_epi64((__m128i*)(dst-1+0), b0);
_mm_storel_epi64((__m128i*)(dst-1+6*1), _mm_srli_si128(b0, 8));
_mm_storel_epi64((__m128i*)(dst-1+6*2), b1);
_mm_storel_epi64((__m128i*)(dst-1+6*3), _mm_srli_si128(b1, 8));
-
+
g0 = _mm_srli_si128(_mm_unpacklo_epi32(g1, r1), 1);
g1 = _mm_srli_si128(_mm_unpackhi_epi32(g1, r1), 1);
-
+
_mm_storel_epi64((__m128i*)(dst-1+6*4), g0);
_mm_storel_epi64((__m128i*)(dst-1+6*5), _mm_srli_si128(g0, 8));
-
+
_mm_storel_epi64((__m128i*)(dst-1+6*6), g1);
}
-
+
return (int)(bayer - (bayer_end - width));
}
-
+
bool use_simd;
};
#else
typedef SIMDBayerStubInterpolator_<uchar> SIMDBayerInterpolator_8u;
#endif
-
+
template<typename T, class SIMDInterpolator>
static void Bayer2Gray_( const Mat& srcmat, Mat& dstmat, int code )
{
const int G2Y = 9617;
const int B2Y = 1868;
const int SHIFT = 14;
-
+
const T* bayer0 = (const T*)srcmat.data;
int bayer_step = (int)(srcmat.step/sizeof(T));
T* dst0 = (T*)dstmat.data;
int bcoeff = B2Y, rcoeff = R2Y;
int start_with_green = code == CV_BayerGB2GRAY || code == CV_BayerGR2GRAY;
bool brow = true;
-
+
if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY )
{
brow = false;
std::swap(bcoeff, rcoeff);
}
-
+
dst0 += dst_step + 1;
size.height -= 2;
size.width -= 2;
-
+
for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
{
unsigned t0, t1, t2;
const T* bayer = bayer0;
T* dst = dst0;
const T* bayer_end = bayer + size.width;
-
+
if( size.width <= 0 )
{
dst[-1] = dst[size.width] = 0;
continue;
}
-
+
if( start_with_green )
{
t0 = (bayer[1] + bayer[bayer_step*2+1])*rcoeff;
t1 = (bayer[bayer_step] + bayer[bayer_step+2])*bcoeff;
t2 = bayer[bayer_step+1]*(2*G2Y);
-
+
dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
bayer++;
dst++;
}
-
+
int delta = vecOp.bayer2Gray(bayer, bayer_step, dst, size.width, bcoeff, G2Y, rcoeff);
bayer += delta;
dst += delta;
-
+
for( ; bayer <= bayer_end - 2; bayer += 2, dst += 2 )
{
t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff;
t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y;
t2 = bayer[bayer_step+1]*(4*bcoeff);
dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
-
+
t0 = (bayer[2] + bayer[bayer_step*2+2])*rcoeff;
t1 = (bayer[bayer_step+1] + bayer[bayer_step+3])*bcoeff;
t2 = bayer[bayer_step+2]*(2*G2Y);
dst[1] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
}
-
+
if( bayer < bayer_end )
{
t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff;
bayer++;
dst++;
}
-
+
dst0[-1] = dst0[0];
dst0[size.width] = dst0[size.width-1];
-
+
brow = !brow;
std::swap(bcoeff, rcoeff);
start_with_green = !start_with_green;
}
-
+
size = dstmat.size();
dst0 = (T*)dstmat.data;
if( size.height > 2 )
}
}
-template<typename T, class SIMDInterpolator>
+template<typename T, class SIMDInterpolator>
static void Bayer2RGB_( const Mat& srcmat, Mat& dstmat, int code )
{
SIMDInterpolator vecOp;
Size size = srcmat.size();
int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1;
int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR;
-
+
dst0 += dst_step + 3 + 1;
size.height -= 2;
size.width -= 2;
-
+
for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
{
int t0, t1;
const T* bayer = bayer0;
T* dst = dst0;
const T* bayer_end = bayer + size.width;
-
+
if( size.width <= 0 )
{
dst[-4] = dst[-3] = dst[-2] = dst[size.width*3-1] =
dst[size.width*3] = dst[size.width*3+1] = 0;
continue;
}
-
+
if( start_with_green )
{
t0 = (bayer[1] + bayer[bayer_step*2+1] + 1) >> 1;
bayer++;
dst += 3;
}
-
+
int delta = vecOp.bayer2RGB(bayer, bayer_step, dst, size.width, blue);
bayer += delta;
dst += delta*3;
-
+
if( blue > 0 )
{
for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 )
dst[-1] = (T)t0;
dst[0] = (T)t1;
dst[1] = bayer[bayer_step+1];
-
+
t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
dst[2] = (T)t0;
dst[1] = (T)t0;
dst[0] = (T)t1;
dst[-1] = bayer[bayer_step+1];
-
+
t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
dst[4] = (T)t0;
dst[2] = (T)t1;
}
}
-
+
if( bayer < bayer_end )
{
t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] +
bayer++;
dst += 3;
}
-
+
dst0[-4] = dst0[-1];
dst0[-3] = dst0[0];
dst0[-2] = dst0[1];
dst0[size.width*3-1] = dst0[size.width*3-4];
dst0[size.width*3] = dst0[size.width*3-3];
dst0[size.width*3+1] = dst0[size.width*3-2];
-
+
blue = -blue;
start_with_green = !start_with_green;
}
-
+
size = dstmat.size();
dst0 = (T*)dstmat.data;
if( size.height > 2 )
}
}
-
+
/////////////////// Demosaicing using Variable Number of Gradients ///////////////////////
-
+
static void Bayer2RGB_VNG_8u( const Mat& srcmat, Mat& dstmat, int code )
{
const uchar* bayer = srcmat.data;
uchar* dst = dstmat.data;
int dststep = (int)dstmat.step;
Size size = srcmat.size();
-
+
int blueIdx = code == CV_BayerBG2BGR_VNG || code == CV_BayerGB2BGR_VNG ? 0 : 2;
bool greenCell0 = code != CV_BayerBG2BGR_VNG && code != CV_BayerRG2BGR_VNG;
-
+
// for too small images use the simple interpolation algorithm
if( MIN(size.width, size.height) < 8 )
{
Bayer2RGB_<uchar, SIMDBayerInterpolator_8u>( srcmat, dstmat, code );
return;
}
-
+
const int brows = 3, bcn = 7;
- int N = size.width, N2 = N*2, N3 = N*3, N4 = N*4, N5 = N*5, N6 = N*6, N7 = N*7;
+ int N = size.width, N2 = N*2, N3 = N*3, N4 = N*4, N5 = N*5, N6 = N*6, N7 = N*7;
int i, bufstep = N7*bcn;
cv::AutoBuffer<ushort> _buf(bufstep*brows);
ushort* buf = (ushort*)_buf;
-
+
bayer += bstep*2;
-
+
#if CV_SSE2
bool haveSSE = cv::checkHardwareSupport(CV_CPU_SSE2);
#define _mm_absdiff_epu16(a,b) _mm_adds_epu16(_mm_subs_epu16(a, b), _mm_subs_epu16(b, a))
#endif
-
+
for( int y = 2; y < size.height - 4; y++ )
{
uchar* dstrow = dst + dststep*y + 6;
const uchar* srow;
-
+
for( int dy = (y == 2 ? -1 : 1); dy <= 1; dy++ )
{
ushort* brow = buf + ((y + dy - 1)%brows)*bufstep + 1;
srow = bayer + (y+dy)*bstep + 1;
-
+
for( i = 0; i < bcn; i++ )
brow[N*i-1] = brow[(N-2) + N*i] = 0;
-
+
i = 1;
-
+
#if CV_SSE2
if( haveSSE )
{
for( ; i <= N-9; i += 8, srow += 8, brow += 8 )
{
__m128i s1, s2, s3, s4, s6, s7, s8, s9;
-
+
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-1-bstep)),z);
s2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-bstep)),z);
s3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+1-bstep)),z);
-
+
s4 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-1)),z);
s6 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+1)),z);
-
+
s7 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow-1+bstep)),z);
s8 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+bstep)),z);
s9 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow+1+bstep)),z);
-
+
__m128i b0, b1, b2, b3, b4, b5, b6;
-
+
b0 = _mm_adds_epu16(_mm_slli_epi16(_mm_absdiff_epu16(s2,s8),1),
_mm_adds_epu16(_mm_absdiff_epu16(s1, s7),
_mm_absdiff_epu16(s3, s9)));
_mm_absdiff_epu16(s7, s9)));
b2 = _mm_slli_epi16(_mm_absdiff_epu16(s3,s7),1);
b3 = _mm_slli_epi16(_mm_absdiff_epu16(s1,s9),1);
-
+
_mm_storeu_si128((__m128i*)brow, b0);
_mm_storeu_si128((__m128i*)(brow + N), b1);
_mm_storeu_si128((__m128i*)(brow + N2), b2);
_mm_storeu_si128((__m128i*)(brow + N3), b3);
-
+
b4 = _mm_adds_epu16(b2,_mm_adds_epu16(_mm_absdiff_epu16(s2, s4),
_mm_absdiff_epu16(s6, s8)));
b5 = _mm_adds_epu16(b3,_mm_adds_epu16(_mm_absdiff_epu16(s2, s6),
_mm_absdiff_epu16(s4, s8)));
b6 = _mm_adds_epu16(_mm_adds_epu16(s2, s4), _mm_adds_epu16(s6, s8));
b6 = _mm_srli_epi16(b6, 1);
-
+
_mm_storeu_si128((__m128i*)(brow + N4), b4);
_mm_storeu_si128((__m128i*)(brow + N5), b5);
_mm_storeu_si128((__m128i*)(brow + N6), b6);
}
}
#endif
-
+
for( ; i < N-1; i++, srow++, brow++ )
{
brow[0] = (ushort)(std::abs(srow[-1-bstep] - srow[-1+bstep]) +
brow[N6] = (ushort)((srow[-bstep] + srow[-1] + srow[1] + srow[+bstep])>>1);
}
}
-
+
const ushort* brow0 = buf + ((y - 2) % brows)*bufstep + 2;
const ushort* brow1 = buf + ((y - 1) % brows)*bufstep + 2;
const ushort* brow2 = buf + (y % brows)*bufstep + 2;
static const float scale[] = { 0.f, 0.5f, 0.25f, 0.1666666666667f, 0.125f, 0.1f, 0.08333333333f, 0.0714286f, 0.0625f };
srow = bayer + y*bstep + 2;
bool greenCell = greenCell0;
-
+
i = 2;
#if CV_SSE2
int limit = !haveSSE ? N-2 : greenCell ? std::min(3, N-2) : 2;
#else
int limit = N - 2;
#endif
-
+
do
{
for( ; i < limit; i++, srow++, brow0++, brow1++, brow2++, dstrow += 3 )
int minGrad = std::min(std::min(std::min(gradN, gradS), gradW), gradE);
int maxGrad = std::max(std::max(std::max(gradN, gradS), gradW), gradE);
int R, G, B;
-
+
if( !greenCell )
{
int gradNE = brow0[N4+1] + brow1[N4];
int gradSW = brow1[N4] + brow2[N4-1];
int gradNW = brow0[N5-1] + brow1[N5];
int gradSE = brow1[N5] + brow2[N5+1];
-
+
minGrad = std::min(std::min(std::min(std::min(minGrad, gradNE), gradSW), gradNW), gradSE);
maxGrad = std::max(std::max(std::max(std::max(maxGrad, gradNE), gradSW), gradNW), gradSE);
int T = minGrad + maxGrad/2;
-
+
int Rs = 0, Gs = 0, Bs = 0, ng = 0;
if( gradN < T )
{
}
R = srow[0];
G = R + cvRound((Gs - Rs)*scale[ng]);
- B = R + cvRound((Bs - Rs)*scale[ng]);
+ B = R + cvRound((Bs - Rs)*scale[ng]);
}
else
{
int gradSW = brow1[N2] + brow1[N2-1] + brow2[N2] + brow2[N2-1];
int gradNW = brow0[N3] + brow0[N3-1] + brow1[N3] + brow1[N3-1];
int gradSE = brow1[N3] + brow1[N3+1] + brow2[N3] + brow2[N3+1];
-
+
minGrad = std::min(std::min(std::min(std::min(minGrad, gradNE), gradSW), gradNW), gradSE);
maxGrad = std::max(std::max(std::max(std::max(maxGrad, gradNE), gradSW), gradNW), gradSE);
int T = minGrad + maxGrad/2;
-
+
int Rs = 0, Gs = 0, Bs = 0, ng = 0;
if( gradN < T )
{
#if CV_SSE2
if( !haveSSE )
break;
-
+
__m128i emask = _mm_set1_epi32(0x0000ffff),
omask = _mm_set1_epi32(0xffff0000),
z = _mm_setzero_si128();
__m128 _0_5 = _mm_set1_ps(0.5f);
-
+
#define _mm_merge_epi16(a, b) _mm_or_si128(_mm_and_si128(a, emask), _mm_and_si128(b, omask)) //(aA_aA_aA_aA) * (bB_bB_bB_bB) => (bA_bA_bA_bA)
#define _mm_cvtloepi16_ps(a) _mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(a,a), 16)) //(1,2,3,4,5,6,7,8) => (1f,2f,3f,4f)
#define _mm_cvthiepi16_ps(a) _mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpackhi_epi16(a,a), 16)) //(1,2,3,4,5,6,7,8) => (5f,6f,7f,8f)
#define _mm_loadl_u8_s16(ptr, offset) _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)((ptr) + (offset))), z) //load 8 uchars to 8 shorts
-
+
// process 8 pixels at once
for( ; i <= N - 10; i += 8, srow += 8, brow0 += 8, brow1 += 8, brow2 += 8 )
{
//int gradE = brow1[N+1] + brow1[N];
__m128i gradE = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N+1)), _mm_loadu_si128((__m128i*)(brow1+N)));
-
+
//int minGrad = std::min(std::min(std::min(gradN, gradS), gradW), gradE);
//int maxGrad = std::max(std::max(std::max(gradN, gradS), gradW), gradE);
__m128i minGrad = _mm_min_epi16(_mm_min_epi16(gradN, gradS), _mm_min_epi16(gradW, gradE));
__m128i maxGrad = _mm_max_epi16(_mm_max_epi16(gradN, gradS), _mm_max_epi16(gradW, gradE));
-
+
__m128i grad0, grad1;
-
+
//int gradNE = brow0[N4+1] + brow1[N4];
//int gradNE = brow0[N2] + brow0[N2+1] + brow1[N2] + brow1[N2+1];
grad0 = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow0+N4+1)), _mm_loadu_si128((__m128i*)(brow1+N4)));
grad1 = _mm_adds_epi16( _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow0+N2)), _mm_loadu_si128((__m128i*)(brow0+N2+1))),
_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N2)), _mm_loadu_si128((__m128i*)(brow1+N2+1))));
__m128i gradNE = _mm_merge_epi16(grad0, grad1);
-
+
//int gradSW = brow1[N4] + brow2[N4-1];
//int gradSW = brow1[N2] + brow1[N2-1] + brow2[N2] + brow2[N2-1];
grad0 = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N4-1)), _mm_loadu_si128((__m128i*)(brow1+N4)));
grad1 = _mm_adds_epi16(_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N2)), _mm_loadu_si128((__m128i*)(brow2+N2-1))),
_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N2)), _mm_loadu_si128((__m128i*)(brow1+N2-1))));
__m128i gradSW = _mm_merge_epi16(grad0, grad1);
-
+
minGrad = _mm_min_epi16(_mm_min_epi16(minGrad, gradNE), gradSW);
maxGrad = _mm_max_epi16(_mm_max_epi16(maxGrad, gradNE), gradSW);
grad1 = _mm_adds_epi16(_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow0+N3)), _mm_loadu_si128((__m128i*)(brow0+N3-1))),
_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N3)), _mm_loadu_si128((__m128i*)(brow1+N3-1))));
__m128i gradNW = _mm_merge_epi16(grad0, grad1);
-
+
//int gradSE = brow1[N5] + brow2[N5+1];
//int gradSE = brow1[N3] + brow1[N3+1] + brow2[N3] + brow2[N3+1];
grad0 = _mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N5+1)), _mm_loadu_si128((__m128i*)(brow1+N5)));
grad1 = _mm_adds_epi16(_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow2+N3)), _mm_loadu_si128((__m128i*)(brow2+N3+1))),
_mm_adds_epi16(_mm_loadu_si128((__m128i*)(brow1+N3)), _mm_loadu_si128((__m128i*)(brow1+N3+1))));
__m128i gradSE = _mm_merge_epi16(grad0, grad1);
-
+
minGrad = _mm_min_epi16(_mm_min_epi16(minGrad, gradNW), gradSE);
maxGrad = _mm_max_epi16(_mm_max_epi16(maxGrad, gradNW), gradSE);
-
+
//int T = minGrad + maxGrad/2;
__m128i T = _mm_adds_epi16(_mm_srli_epi16(maxGrad, 1), minGrad);
__m128i RGs = z, GRs = z, Bs = z, ng = z;
-
+
__m128i x0 = _mm_loadl_u8_s16(srow, +0 );
__m128i x1 = _mm_loadl_u8_s16(srow, -1 - bstep );
__m128i x2 = _mm_loadl_u8_s16(srow, -1 - bstep*2);
__m128i x16 = _mm_loadl_u8_s16(srow, -2 - bstep );
__m128i t0, t1, mask;
-
+
// gradN ***********************************************
mask = _mm_cmpgt_epi16(T, gradN); // mask = T>gradN
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradN)
-
+
t0 = _mm_slli_epi16(x3, 1); // srow[-bstep]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, -bstep*2), x0); // srow[-bstep*2] + srow[0]
-
+
// RGs += (srow[-bstep*2] + srow[0]) * (T>gradN)
RGs = _mm_adds_epi16(RGs, _mm_and_si128(t1, mask));
// GRs += {srow[-bstep]*2; (srow[-bstep*2-1] + srow[-bstep*2+1])} * (T>gradN)
GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(t0, _mm_adds_epi16(x2,x4)), mask));
// Bs += {(srow[-bstep-1]+srow[-bstep+1]); srow[-bstep]*2 } * (T>gradN)
Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x1,x5), t0), mask));
-
+
// gradNE **********************************************
mask = _mm_cmpgt_epi16(T, gradNE); // mask = T>gradNE
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradNE)
t0 = _mm_slli_epi16(x5, 1); // srow[-bstep+1]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, -bstep*2+2), x0); // srow[-bstep*2+2] + srow[0]
-
+
// RGs += {(srow[-bstep*2+2] + srow[0]); srow[-bstep+1]*2} * (T>gradNE)
RGs = _mm_adds_epi16(RGs, _mm_and_si128(_mm_merge_epi16(t1, t0), mask));
// GRs += {brow0[N6+1]; (srow[-bstep*2+1] + srow[1])} * (T>gradNE)
GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(_mm_loadu_si128((__m128i*)(brow0+N6+1)), _mm_adds_epi16(x4,x7)), mask));
// Bs += {srow[-bstep+1]*2; (srow[-bstep] + srow[-bstep+2])} * (T>gradNE)
Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(t0,_mm_adds_epi16(x3,x6)), mask));
-
+
// gradE ***********************************************
mask = _mm_cmpgt_epi16(T, gradE); // mask = T>gradE
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradE)
-
+
t0 = _mm_slli_epi16(x7, 1); // srow[1]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, 2), x0); // srow[2] + srow[0]
GRs = _mm_adds_epi16(GRs, _mm_and_si128(t0, mask));
// Bs += {(srow[-bstep+1]+srow[bstep+1]); (srow[-bstep+2]+srow[bstep+2])} * (T>gradE)
Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x5,x9), _mm_adds_epi16(x6,x8)), mask));
-
+
// gradSE **********************************************
mask = _mm_cmpgt_epi16(T, gradSE); // mask = T>gradSE
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradSE)
-
+
t0 = _mm_slli_epi16(x9, 1); // srow[bstep+1]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, bstep*2+2), x0); // srow[bstep*2+2] + srow[0]
GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(_mm_loadu_si128((__m128i*)(brow2+N6+1)), _mm_adds_epi16(x7,x10)), mask));
// Bs += {srow[-bstep+1]*2; (srow[bstep+2]+srow[bstep])} * (T>gradSE)
Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_slli_epi16(x5, 1), _mm_adds_epi16(x8,x11)), mask));
-
+
// gradS ***********************************************
mask = _mm_cmpgt_epi16(T, gradS); // mask = T>gradS
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradS)
-
+
t0 = _mm_slli_epi16(x11, 1); // srow[bstep]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow,bstep*2), x0); // srow[bstep*2]+srow[0]
GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(t0, _mm_adds_epi16(x10,x12)), mask));
// Bs += {(srow[bstep+1]+srow[bstep-1]); srow[bstep]*2} * (T>gradS)
Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x9,x13), t0), mask));
-
+
// gradSW **********************************************
mask = _mm_cmpgt_epi16(T, gradSW); // mask = T>gradSW
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradSW)
-
+
t0 = _mm_slli_epi16(x13, 1); // srow[bstep-1]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, bstep*2-2), x0); // srow[bstep*2-2]+srow[0]
GRs = _mm_adds_epi16(GRs, _mm_and_si128(_mm_merge_epi16(_mm_loadu_si128((__m128i*)(brow2+N6-1)), _mm_adds_epi16(x12,x15)), mask));
// Bs += {srow[bstep-1]*2; (srow[bstep]+srow[bstep-2])} * (T>gradSW)
Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(t0,_mm_adds_epi16(x11,x14)), mask));
-
+
// gradW ***********************************************
mask = _mm_cmpgt_epi16(T, gradW); // mask = T>gradW
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradW)
-
+
t0 = _mm_slli_epi16(x15, 1); // srow[-1]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow, -2), x0); // srow[-2]+srow[0]
GRs = _mm_adds_epi16(GRs, _mm_and_si128(t0, mask));
// Bs += {(srow[-bstep-1]+srow[bstep-1]); (srow[bstep-2]+srow[-bstep-2])} * (T>gradW)
Bs = _mm_adds_epi16(Bs, _mm_and_si128(_mm_merge_epi16(_mm_adds_epi16(x1,x13), _mm_adds_epi16(x14,x16)), mask));
-
+
// gradNW **********************************************
mask = _mm_cmpgt_epi16(T, gradNW); // mask = T>gradNW
ng = _mm_sub_epi16(ng, mask); // ng += (T>gradNW)
-
+
t0 = _mm_slli_epi16(x1, 1); // srow[-bstep-1]*2
t1 = _mm_adds_epi16(_mm_loadl_u8_s16(srow,-bstep*2-2), x0); // srow[-bstep*2-2]+srow[0]
__m128 ngf0, ngf1;
ngf0 = _mm_div_ps(_0_5, _mm_cvtloepi16_ps(ng));
ngf1 = _mm_div_ps(_0_5, _mm_cvthiepi16_ps(ng));
-
+
// now interpolate r, g & b
t0 = _mm_sub_epi16(GRs, RGs);
t1 = _mm_sub_epi16(Bs, RGs);
-
+
t0 = _mm_add_epi16(x0, _mm_packs_epi32(
_mm_cvtps_epi32(_mm_mul_ps(_mm_cvtloepi16_ps(t0), ngf0)),
_mm_cvtps_epi32(_mm_mul_ps(_mm_cvthiepi16_ps(t0), ngf1))));
-
+
t1 = _mm_add_epi16(x0, _mm_packs_epi32(
_mm_cvtps_epi32(_mm_mul_ps(_mm_cvtloepi16_ps(t1), ngf0)),
_mm_cvtps_epi32(_mm_mul_ps(_mm_cvthiepi16_ps(t1), ngf1))));
-
+
x1 = _mm_merge_epi16(x0, t0);
x2 = _mm_merge_epi16(t0, x0);
-
+
uchar R[8], G[8], B[8];
-
+
_mm_storel_epi64(blueIdx ? (__m128i*)B : (__m128i*)R, _mm_packus_epi16(x1, z));
_mm_storel_epi64((__m128i*)G, _mm_packus_epi16(x2, z));
_mm_storel_epi64(blueIdx ? (__m128i*)R : (__m128i*)B, _mm_packus_epi16(t1, z));
-
+
for( int j = 0; j < 8; j++, dstrow += 3 )
{
dstrow[0] = B[j]; dstrow[1] = G[j]; dstrow[2] = R[j];
}
}
#endif
-
+
limit = N - 2;
}
while( i < N - 2 );
-
+
for( i = 0; i < 6; i++ )
{
dst[dststep*y + 5 - i] = dst[dststep*y + 8 - i];
dst[dststep*y + (N - 2)*3 + i] = dst[dststep*y + (N - 3)*3 + i];
}
-
+
greenCell0 = !greenCell0;
blueIdx ^= 2;
}
-
+
for( i = 0; i < size.width*3; i++ )
{
dst[i] = dst[i + dststep] = dst[i + dststep*2];
{
const int rangeBegin = range.begin() * 2;
const int rangeEnd = range.end() * 2;
-
+
size_t uvsteps[2] = {width/2, stride - width/2};
int usIdx = ustepIdx, vsIdx = vstepIdx;
const uchar* y1 = my1 + rangeBegin * stride;
const uchar* u1 = mu + (range.begin() / 2) * stride;
const uchar* v1 = mv + (range.begin() / 2) * stride;
-
+
if(range.begin() % 2 == 1)
{
u1 += uvsteps[(usIdx++) & 1];
const uchar* y1 = my1 + rangeBegin * stride;
const uchar* u1 = mu + (range.begin() / 2) * stride;
const uchar* v1 = mv + (range.begin() / 2) * stride;
-
+
if(range.begin() % 2 == 1)
{
u1 += uvsteps[(usIdx++) & 1];
Mat src = _src.getMat(), dst;
Size sz = src.size();
int scn = src.channels(), depth = src.depth(), bidx;
-
+
CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F );
-
+
switch( code )
{
case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR:
CV_Assert( scn == 3 || scn == 4 );
dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3;
bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2;
-
+
_dst.create( sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
else
CvtColorLoop(src, dst, RGB2RGB<float>(scn, dcn, bidx));
break;
-
+
case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555:
case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555:
CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U );
if(tegra::cvtRGB2RGB565(src, dst, code == CV_RGB2BGR565 || code == CV_RGBA2BGR565 ? 0 : 2))
break;
#endif
-
+
CvtColorLoop(src, dst, RGB2RGB5x5(scn,
code == CV_BGR2BGR565 || code == CV_BGR2BGR555 ||
code == CV_BGRA2BGR565 || code == CV_BGRA2BGR555 ? 0 : 2,
code == CV_BGRA2BGR565 || code == CV_RGBA2BGR565 ? 6 : 5 // green bits
));
break;
-
+
case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652RGB: case CV_BGR5552RGB:
case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA:
if(dcn <= 0) dcn = (code==CV_BGR5652BGRA || code==CV_BGR5552BGRA || code==CV_BGR5652RGBA || code==CV_BGR5552RGBA) ? 4 : 3;
CV_Assert( (dcn == 3 || dcn == 4) && scn == 2 && depth == CV_8U );
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
CvtColorLoop(src, dst, RGB5x52RGB(dcn,
code == CV_BGR5652BGR || code == CV_BGR5552BGR ||
code == CV_BGR5652BGRA || code == CV_BGR5552BGRA ? 0 : 2, // blue idx
code == CV_BGR5652BGRA || code == CV_BGR5652RGBA ? 6 : 5 // green bits
));
break;
-
+
case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY:
CV_Assert( scn == 3 || scn == 4 );
_dst.create(sz, CV_MAKETYPE(depth, 1));
dst = _dst.getMat();
-
+
bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;
-
+
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
else
CvtColorLoop(src, dst, RGB2Gray<float>(scn, bidx, 0));
break;
-
+
case CV_BGR5652GRAY: case CV_BGR5552GRAY:
CV_Assert( scn == 2 && depth == CV_8U );
_dst.create(sz, CV_8UC1);
dst = _dst.getMat();
-
+
CvtColorLoop(src, dst, RGB5x52Gray(code == CV_BGR5652GRAY ? 6 : 5));
break;
-
+
case CV_GRAY2BGR: case CV_GRAY2BGRA:
if( dcn <= 0 ) dcn = (code==CV_GRAY2BGRA) ? 4 : 3;
CV_Assert( scn == 1 && (dcn == 3 || dcn == 4));
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
else
CvtColorLoop(src, dst, Gray2RGB<float>(dcn));
break;
-
+
case CV_GRAY2BGR565: case CV_GRAY2BGR555:
CV_Assert( scn == 1 && depth == CV_8U );
_dst.create(sz, CV_8UC2);
dst = _dst.getMat();
-
+
CvtColorLoop(src, dst, Gray2RGB5x5(code == CV_GRAY2BGR565 ? 6 : 5));
break;
-
+
case CV_BGR2YCrCb: case CV_RGB2YCrCb:
case CV_BGR2YUV: case CV_RGB2YUV:
{
static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };
const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;
-
+
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
-
+
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, coeffs_f));
}
break;
-
+
case CV_YCrCb2BGR: case CV_YCrCb2RGB:
case CV_YUV2BGR: case CV_YUV2RGB:
{
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
bidx = code == CV_YCrCb2BGR || code == CV_YUV2RGB ? 0 : 2;
static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f };
- static const int yuv_i[] = { 33292, -6472, -9519, 18678 };
+ static const int yuv_i[] = { 33292, -6472, -9519, 18678 };
const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;
const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i;
-
+
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
if( depth == CV_8U )
CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, coeffs_i));
else if( depth == CV_16U )
CvtColorLoop(src, dst, YCrCb2RGB_f<float>(dcn, bidx, coeffs_f));
}
break;
-
+
case CV_BGR2XYZ: case CV_RGB2XYZ:
CV_Assert( scn == 3 || scn == 4 );
bidx = code == CV_BGR2XYZ ? 0 : 2;
-
+
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
-
+
if( depth == CV_8U )
CvtColorLoop(src, dst, RGB2XYZ_i<uchar>(scn, bidx, 0));
else if( depth == CV_16U )
else
CvtColorLoop(src, dst, RGB2XYZ_f<float>(scn, bidx, 0));
break;
-
+
case CV_XYZ2BGR: case CV_XYZ2RGB:
if( dcn <= 0 ) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
bidx = code == CV_XYZ2BGR ? 0 : 2;
-
+
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
if( depth == CV_8U )
CvtColorLoop(src, dst, XYZ2RGB_i<uchar>(dcn, bidx, 0));
else if( depth == CV_16U )
else
CvtColorLoop(src, dst, XYZ2RGB_f<float>(dcn, bidx, 0));
break;
-
+
case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL:
case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL:
{
code == CV_BGR2HSV_FULL || code == CV_BGR2HLS_FULL ? 0 : 2;
int hrange = depth == CV_32F ? 360 : code == CV_BGR2HSV || code == CV_RGB2HSV ||
code == CV_BGR2HLS || code == CV_RGB2HLS ? 180 : 256;
-
+
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
-
+
if( code == CV_BGR2HSV || code == CV_RGB2HSV ||
code == CV_BGR2HSV_FULL || code == CV_RGB2HSV_FULL )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
- if(tegra::cvtRGB2HSV(src, dst, bidx, hrange))
+ if(tegra::cvtRGB2HSV(src, dst, bidx, hrange))
break;
#endif
if( depth == CV_8U )
}
}
break;
-
+
case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL:
case CV_HLS2BGR: case CV_HLS2RGB: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL:
{
code == CV_HSV2BGR_FULL || code == CV_HLS2BGR_FULL ? 0 : 2;
int hrange = depth == CV_32F ? 360 : code == CV_HSV2BGR || code == CV_HSV2RGB ||
code == CV_HLS2BGR || code == CV_HLS2RGB ? 180 : 255;
-
+
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
if( code == CV_HSV2BGR || code == CV_HSV2RGB ||
code == CV_HSV2BGR_FULL || code == CV_HSV2RGB_FULL )
{
}
}
break;
-
+
case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab:
case CV_BGR2Luv: case CV_RGB2Luv: case CV_LBGR2Luv: case CV_LRGB2Luv:
{
code == CV_LBGR2Lab || code == CV_LBGR2Luv ? 0 : 2;
bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab ||
code == CV_BGR2Luv || code == CV_RGB2Luv;
-
+
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
-
+
if( code == CV_BGR2Lab || code == CV_RGB2Lab ||
code == CV_LBGR2Lab || code == CV_LRGB2Lab )
{
}
}
break;
-
+
case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB:
case CV_Luv2BGR: case CV_Luv2RGB: case CV_Luv2LBGR: case CV_Luv2LRGB:
{
code == CV_Lab2LBGR || code == CV_Luv2LBGR ? 0 : 2;
bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB ||
code == CV_Luv2BGR || code == CV_Luv2RGB;
-
+
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
if( code == CV_Lab2BGR || code == CV_Lab2RGB ||
code == CV_Lab2LBGR || code == CV_Lab2LRGB )
{
}
}
break;
-
+
case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: case CV_BayerRG2GRAY: case CV_BayerGR2GRAY:
if(dcn <= 0) dcn = 1;
CV_Assert( scn == 1 && dcn == 1 );
-
+
_dst.create(sz, depth);
dst = _dst.getMat();
-
+
if( depth == CV_8U )
Bayer2Gray_<uchar, SIMDBayerInterpolator_8u>(src, dst, code);
else if( depth == CV_16U )
else
CV_Error(CV_StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types");
break;
-
+
case CV_BayerBG2BGR: case CV_BayerGB2BGR: case CV_BayerRG2BGR: case CV_BayerGR2BGR:
case CV_BayerBG2BGR_VNG: case CV_BayerGB2BGR_VNG: case CV_BayerRG2BGR_VNG: case CV_BayerGR2BGR_VNG:
if(dcn <= 0) dcn = 3;
CV_Assert( scn == 1 && dcn == 3 );
-
+
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
if( code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ||
code == CV_BayerRG2BGR || code == CV_BayerGR2BGR )
{
{
// http://www.fourcc.org/yuv.php#NV21 == yuv420sp -> a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2x2 subsampled chroma samples
// http://www.fourcc.org/yuv.php#NV12 -> a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples
-
+
if (dcn <= 0) dcn = (code==CV_YUV420sp2BGRA || code==CV_YUV420sp2RGBA || code==CV_YUV2BGRA_NV12 || code==CV_YUV2RGBA_NV12) ? 4 : 3;
- const int bidx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2BGR_NV12 || code==CV_YUV2BGRA_NV12) ? 0 : 2;
- const int uidx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2RGB_NV21 || code==CV_YUV2RGBA_NV21) ? 1 : 0;
-
+ const int bIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2BGR_NV12 || code==CV_YUV2BGRA_NV12) ? 0 : 2;
+ const int uIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2RGB_NV21 || code==CV_YUV2RGBA_NV21) ? 1 : 0;
+
CV_Assert( dcn == 3 || dcn == 4 );
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
-
+
Size dstSz(sz.width, sz.height * 2 / 3);
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
int srcstep = (int)src.step;
const uchar* y = src.ptr();
const uchar* uv = y + srcstep * dstSz.height;
-
- switch(dcn*100 + bidx * 10 + uidx)
+
+ switch(dcn*100 + bIdx * 10 + uIdx)
{
case 300: cvtYUV420sp2RGB<0, 0> (dst, srcstep, y, uv); break;
case 301: cvtYUV420sp2RGB<0, 1> (dst, srcstep, y, uv); break;
{
//http://www.fourcc.org/yuv.php#YV12 == yuv420p -> It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.
//http://www.fourcc.org/yuv.php#IYUV == I420 -> It comprises an NxN Y plane followed by (N/2)x(N/2) U and V planes
-
+
if (dcn <= 0) dcn = (code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12 || code==CV_YUV2RGBA_IYUV || code==CV_YUV2BGRA_IYUV) ? 4 : 3;
- const int bidx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2BGR_IYUV || code==CV_YUV2BGRA_IYUV) ? 0 : 2;
- const int uidx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2RGB_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12) ? 1 : 0;
-
+ const int bIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2BGR_IYUV || code==CV_YUV2BGRA_IYUV) ? 0 : 2;
+ const int uIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2RGB_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12) ? 1 : 0;
+
CV_Assert( dcn == 3 || dcn == 4 );
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
Size dstSz(sz.width, sz.height * 2 / 3);
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
int srcstep = (int)src.step;
const uchar* y = src.ptr();
const uchar* u = y + srcstep * dstSz.height;
const uchar* v = y + srcstep * (dstSz.height + dstSz.height/4) + (dstSz.width/2) * ((dstSz.height % 4)/2);
-
+
int ustepIdx = 0;
int vstepIdx = dstSz.height % 4 == 2 ? 1 : 0;
-
- if(uidx == 1) { std::swap(u ,v), std::swap(ustepIdx, vstepIdx); };
-
- switch(dcn*10 + bidx)
+
+ if(uIdx == 1) { std::swap(u ,v), std::swap(ustepIdx, vstepIdx); };
+
+ switch(dcn*10 + bIdx)
{
case 30: cvtYUV420p2RGB<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
case 32: cvtYUV420p2RGB<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
case CV_YUV2GRAY_420:
{
if (dcn <= 0) dcn = 1;
-
+
CV_Assert( dcn == 1 );
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
Size dstSz(sz.width, sz.height * 2 / 3);
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
-
+
src(Range(0, dstSz.height), Range::all()).copyTo(dst);
}
break;
{
//http://www.fourcc.org/yuv.php#UYVY
//http://www.fourcc.org/yuv.php#YUY2
- //http://www.fourcc.org/yuv.php#YVYU
-
+ //http://www.fourcc.org/yuv.php#YVYU
+
if (dcn <= 0) dcn = (code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2RGBA_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 4 : 3;
- const int bidx = (code==CV_YUV2BGR_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2BGR_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2BGR_YVYU || code==CV_YUV2BGRA_YVYU) ? 0 : 2;
- const int ycn = (code==CV_YUV2RGB_UYVY || code==CV_YUV2BGR_UYVY || code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY) ? 1 : 0;
- const int uidx = (code==CV_YUV2RGB_YVYU || code==CV_YUV2BGR_YVYU || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 1 : 0;
-
+ const int bIdx = (code==CV_YUV2BGR_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2BGR_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2BGR_YVYU || code==CV_YUV2BGRA_YVYU) ? 0 : 2;
+ const int ycn = (code==CV_YUV2RGB_UYVY || code==CV_YUV2BGR_UYVY || code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY) ? 1 : 0;
+ const int uIdx = (code==CV_YUV2RGB_YVYU || code==CV_YUV2BGR_YVYU || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 1 : 0;
+
CV_Assert( dcn == 3 || dcn == 4 );
CV_Assert( scn == 2 && depth == CV_8U );
_dst.create(sz, CV_8UC(dcn));
dst = _dst.getMat();
-
- switch(dcn*1000 + bidx*100 + uidx*10 + ycn)
+
+ switch(dcn*1000 + bIdx*100 + uIdx*10 + ycn)
{
case 3000: cvtYUV422toRGB<0,0,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3001: cvtYUV422toRGB<0,0,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case CV_YUV2GRAY_UYVY: case CV_YUV2GRAY_YUY2:
{
if (dcn <= 0) dcn = 1;
-
+
CV_Assert( dcn == 1 );
CV_Assert( scn == 2 && depth == CV_8U );
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
}
}
-
+
CV_IMPL void
cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int code )
{
cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0;
CV_Assert( src.depth() == dst.depth() );
-
+
cv::cvtColor(src, dst, code, dst.channels());
CV_Assert( dst.data == dst0.data );
}
/*
Various border types, image boundaries are denoted with '|'
-
+
* BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
* BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
* BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
- * BORDER_WRAP: cdefgh|abcdefgh|abcdefg
+ * BORDER_WRAP: cdefgh|abcdefgh|abcdefg
* BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'
*/
int cv::borderInterpolate( int p, int len, int borderType )
wholeSize = Size(-1,-1);
}
-
+
FilterEngine::FilterEngine( const Ptr<BaseFilter>& _filter2D,
const Ptr<BaseRowFilter>& _rowFilter,
init(_filter2D, _rowFilter, _columnFilter, _srcType, _dstType, _bufType,
_rowBorderType, _columnBorderType, _borderValue);
}
-
+
FilterEngine::~FilterEngine()
{
}
_srcType = CV_MAT_TYPE(_srcType);
_bufType = CV_MAT_TYPE(_bufType);
_dstType = CV_MAT_TYPE(_dstType);
-
+
srcType = _srcType;
int srcElemSize = (int)getElemSize(srcType);
dstType = _dstType;
bufType = _bufType;
-
+
filter2D = _filter2D;
rowFilter = _rowFilter;
columnFilter = _columnFilter;
if( _columnBorderType < 0 )
_columnBorderType = _rowBorderType;
-
+
rowBorderType = _rowBorderType;
columnBorderType = _columnBorderType;
-
+
CV_Assert( columnBorderType != BORDER_WRAP );
-
+
if( isSeparable() )
{
CV_Assert( !rowFilter.empty() && !columnFilter.empty() );
CV_Assert( 0 <= anchor.x && anchor.x < ksize.width &&
0 <= anchor.y && anchor.y < ksize.height );
- borderElemSize = srcElemSize/(CV_MAT_DEPTH(srcType) >= CV_32S ? sizeof(int) : 1);
+ borderElemSize = srcElemSize/(CV_MAT_DEPTH(srcType) >= CV_32S ? sizeof(int) : 1);
int borderLength = std::max(ksize.width - 1, 1);
borderTab.resize(borderLength*borderElemSize);
int FilterEngine::start(Size _wholeSize, Rect _roi, int _maxBufRows)
{
int i, j;
-
+
wholeSize = _wholeSize;
roi = _roi;
CV_Assert( roi.x >= 0 && roi.y >= 0 && roi.width >= 0 && roi.height >= 0 &&
int n = (int)constBorderValue.size(), N;
N = (maxWidth + ksize.width - 1)*esz;
tdst = isSeparable() ? &srcRow[0] : dst;
-
+
for( i = 0; i < N; i += n )
{
n = std::min( n, N - i );
if( isSeparable() )
(*rowFilter)(&srcRow[0], dst, maxWidth, cn);
}
-
+
int maxBufStep = bufElemSize*(int)alignSize(maxWidth +
(!isSeparable() ? ksize.width - 1 : 0),VEC_ALIGN);
ringBuf.resize(maxBufStep*rows.size()+VEC_ALIGN);
else
{
int xofs1 = std::min(roi.x, anchor.x) - roi.x;
-
+
int btab_esz = borderElemSize, wholeWidth = wholeSize.width;
int* btab = (int*)&borderTab[0];
-
+
for( i = 0; i < dx1; i++ )
{
int p0 = (borderInterpolate(i-dx1, wholeWidth, rowBorderType) + xofs1)*btab_esz;
bool isolated, int maxBufRows)
{
Rect srcRoi = _srcRoi;
-
+
if( srcRoi == Rect(0,0,-1,-1) )
srcRoi = Rect(0,0,src.cols,src.rows);
-
+
CV_Assert( srcRoi.x >= 0 && srcRoi.y >= 0 &&
srcRoi.width >= 0 && srcRoi.height >= 0 &&
srcRoi.x + srcRoi.width <= src.cols &&
srcRoi.y + srcRoi.height <= src.rows );
Point ofs;
- Size wholeSize(src.cols, src.rows);
+ Size wsz(src.cols, src.rows);
if( !isolated )
- src.locateROI( wholeSize, ofs );
- start( wholeSize, srcRoi + ofs, maxBufRows );
+ src.locateROI( wsz, ofs );
+ start( wsz, srcRoi + ofs, maxBufRows );
return startY - ofs.y;
}
uchar* dst, int dststep )
{
CV_Assert( wholeSize.width > 0 && wholeSize.height > 0 );
-
+
const int *btab = &borderTab[0];
int esz = (int)getElemSize(srcType), btab_esz = borderElemSize;
uchar** brows = &rows[0];
int bi = (startY - startY0 + rowCount) % bufRows;
uchar* brow = alignPtr(&ringBuf[0], VEC_ALIGN) + bi*bufStep;
uchar* row = isSep ? &srcRow[0] : brow;
-
+
if( ++rowCount > bufRows )
{
--rowCount;
row[i + (width1 - _dx2)*esz] = src[btab[i+_dx1*esz]];
}
}
-
+
if( isSep )
(*rowFilter)(row, brow, width, CV_MAT_CN(srcType));
}
const Rect& _srcRoi, Point dstOfs, bool isolated)
{
CV_Assert( src.type() == srcType && dst.type() == dstType );
-
+
Rect srcRoi = _srcRoi;
if( srcRoi == Rect(0,0,-1,-1) )
srcRoi = Rect(0,0,src.cols,src.rows);
-
+
if( srcRoi.area() == 0 )
return;
{
if( !checkHardwareSupport(CV_CPU_SSE2) )
return 0;
-
+
int i = 0, k, _ksize = kernel.rows + kernel.cols - 1;
int* dst = (int*)_dst;
const int* _kx = (const int*)kernel.data;
s2 = _mm_add_epi32(s2, _mm_unpacklo_epi16(x2, x3));
s3 = _mm_add_epi32(s3, _mm_unpackhi_epi16(x2, x3));
}
-
+
_mm_store_si128((__m128i*)(dst + i), s0);
_mm_store_si128((__m128i*)(dst + i + 4), s1);
_mm_store_si128((__m128i*)(dst + i + 8), s2);
{
if( !checkHardwareSupport(CV_CPU_SSE2) )
return 0;
-
+
int i = 0, j, k, _ksize = kernel.rows + kernel.cols - 1;
int* dst = (int*)_dst;
bool symmetrical = (symmetryType & KERNEL_SYMMETRICAL) != 0;
{
if( !checkHardwareSupport(CV_CPU_SSE2) )
return 0;
-
+
int ksize2 = (kernel.rows + kernel.cols - 1)/2;
const float* ky = (const float*)kernel.data + ksize2;
int i = 0, k;
{
if( !checkHardwareSupport(CV_CPU_SSE2) )
return 0;
-
+
int ksize2 = (kernel.rows + kernel.cols - 1)/2;
const float* ky = (const float*)kernel.data + ksize2;
int i = 0;
Mat kernel;
};
-
+
/////////////////////////////////////// 16s //////////////////////////////////
-
+
struct RowVec_16s32f
{
RowVec_16s32f() {}
kernel = _kernel;
sse2_supported = checkHardwareSupport(CV_CPU_SSE2);
}
-
+
int operator()(const uchar* _src, uchar* _dst, int width, int cn) const
{
if( !sse2_supported )
return 0;
-
+
int i = 0, k, _ksize = kernel.rows + kernel.cols - 1;
float* dst = (float*)_dst;
const float* _kx = (const float*)kernel.data;
width *= cn;
-
+
for( ; i <= width - 8; i += 8 )
{
const short* src = (const short*)_src + i;
{
f = _mm_load_ss(_kx+k);
f = _mm_shuffle_ps(f, f, 0);
-
+
__m128i x0i = _mm_loadu_si128((const __m128i*)src);
__m128i x1i = _mm_srai_epi32(_mm_unpackhi_epi16(x0i, x0i), 16);
x0i = _mm_srai_epi32(_mm_unpacklo_epi16(x0i, x0i), 16);
}
return i;
}
-
+
Mat kernel;
bool sse2_supported;
};
-
-
+
+
struct SymmColumnVec_32f16s
{
SymmColumnVec_32f16s() { symmetryType=0; }
CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 );
sse2_supported = checkHardwareSupport(CV_CPU_SSE2);
}
-
+
int operator()(const uchar** _src, uchar* _dst, int width) const
{
if( !sse2_supported )
return 0;
-
+
int ksize2 = (kernel.rows + kernel.cols - 1)/2;
const float* ky = (const float*)kernel.data + ksize2;
int i = 0, k;
const float *S, *S2;
short* dst = (short*)_dst;
__m128 d4 = _mm_set1_ps(delta);
-
+
if( symmetrical )
{
for( ; i <= width - 16; i += 16 )
s3 = _mm_load_ps(S+12);
s2 = _mm_add_ps(_mm_mul_ps(s2, f), d4);
s3 = _mm_add_ps(_mm_mul_ps(s3, f), d4);
-
+
for( k = 1; k <= ksize2; k++ )
{
S = src[k] + i;
s2 = _mm_add_ps(s2, _mm_mul_ps(x0, f));
s3 = _mm_add_ps(s3, _mm_mul_ps(x1, f));
}
-
+
__m128i s0i = _mm_cvtps_epi32(s0);
__m128i s1i = _mm_cvtps_epi32(s1);
__m128i s2i = _mm_cvtps_epi32(s2);
__m128i s3i = _mm_cvtps_epi32(s3);
-
+
_mm_storeu_si128((__m128i*)(dst + i), _mm_packs_epi32(s0i, s1i));
_mm_storeu_si128((__m128i*)(dst + i + 8), _mm_packs_epi32(s2i, s3i));
}
-
+
for( ; i <= width - 4; i += 4 )
{
__m128 f = _mm_load_ss(ky);
f = _mm_shuffle_ps(f, f, 0);
__m128 x0, s0 = _mm_load_ps(src[0] + i);
s0 = _mm_add_ps(_mm_mul_ps(s0, f), d4);
-
+
for( k = 1; k <= ksize2; k++ )
{
f = _mm_load_ss(ky+k);
x0 = _mm_add_ps(_mm_load_ps(src[k]+i), _mm_load_ps(src[-k] + i));
s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f));
}
-
+
__m128i s0i = _mm_cvtps_epi32(s0);
_mm_storel_epi64((__m128i*)(dst + i), _mm_packs_epi32(s0i, s0i));
}
__m128 f, s0 = d4, s1 = d4, s2 = d4, s3 = d4;
__m128 x0, x1;
S = src[0] + i;
-
+
for( k = 1; k <= ksize2; k++ )
{
S = src[k] + i;
s2 = _mm_add_ps(s2, _mm_mul_ps(x0, f));
s3 = _mm_add_ps(s3, _mm_mul_ps(x1, f));
}
-
+
__m128i s0i = _mm_cvtps_epi32(s0);
__m128i s1i = _mm_cvtps_epi32(s1);
__m128i s2i = _mm_cvtps_epi32(s2);
__m128i s3i = _mm_cvtps_epi32(s3);
-
+
_mm_storeu_si128((__m128i*)(dst + i), _mm_packs_epi32(s0i, s1i));
_mm_storeu_si128((__m128i*)(dst + i + 8), _mm_packs_epi32(s2i, s3i));
}
-
+
for( ; i <= width - 4; i += 4 )
{
__m128 f, x0, s0 = d4;
-
+
for( k = 1; k <= ksize2; k++ )
{
f = _mm_load_ss(ky+k);
x0 = _mm_sub_ps(_mm_load_ps(src[k]+i), _mm_load_ps(src[-k] + i));
s0 = _mm_add_ps(s0, _mm_mul_ps(x0, f));
}
-
+
__m128i s0i = _mm_cvtps_epi32(s0);
_mm_storel_epi64((__m128i*)(dst + i), _mm_packs_epi32(s0i, s0i));
}
}
-
+
return i;
}
-
+
int symmetryType;
float delta;
Mat kernel;
bool sse2_supported;
-};
-
+};
+
/////////////////////////////////////// 32f //////////////////////////////////
{
if( !checkHardwareSupport(CV_CPU_SSE) )
return 0;
-
+
int i = 0, k, _ksize = kernel.rows + kernel.cols - 1;
float* dst = (float*)_dst;
const float* _kx = (const float*)kernel.data;
{
if( !checkHardwareSupport(CV_CPU_SSE) )
return 0;
-
+
int i = 0, _ksize = kernel.rows + kernel.cols - 1;
float* dst = (float*)_dst;
const float* src = (const float*)_src + (_ksize/2)*cn;
y0 = _mm_mul_ps(_mm_add_ps(y0, y2), k1);
x0 = _mm_add_ps(x0, _mm_mul_ps(x1, k0));
y0 = _mm_add_ps(y0, _mm_mul_ps(y1, k0));
-
+
x2 = _mm_add_ps(_mm_loadu_ps(src + cn*2), _mm_loadu_ps(src - cn*2));
y2 = _mm_add_ps(_mm_loadu_ps(src + cn*2 + 4), _mm_loadu_ps(src - cn*2 + 4));
x0 = _mm_add_ps(x0, _mm_mul_ps(x2, k2));
y0 = _mm_add_ps(y0, _mm_mul_ps(y2, k2));
-
+
_mm_store_ps(dst + i, x0);
_mm_store_ps(dst + i + 4, y0);
}
x0 = _mm_mul_ps(_mm_sub_ps(x0, x2), k1);
y0 = _mm_mul_ps(_mm_sub_ps(y0, y2), k1);
-
+
x2 = _mm_sub_ps(_mm_loadu_ps(src + cn*2), _mm_loadu_ps(src - cn*2));
y2 = _mm_sub_ps(_mm_loadu_ps(src + cn*2 + 4), _mm_loadu_ps(src - cn*2 + 4));
x0 = _mm_add_ps(x0, _mm_mul_ps(x2, k2));
y0 = _mm_add_ps(y0, _mm_mul_ps(y2, k2));
-
+
_mm_store_ps(dst + i, x0);
_mm_store_ps(dst + i + 4, y0);
}
{
if( !checkHardwareSupport(CV_CPU_SSE) )
return 0;
-
+
int ksize2 = (kernel.rows + kernel.cols - 1)/2;
const float* ky = (const float*)kernel.data + ksize2;
int i = 0, k;
{
if( !checkHardwareSupport(CV_CPU_SSE) )
return 0;
-
+
int ksize2 = (kernel.rows + kernel.cols - 1)/2;
const float* ky = (const float*)kernel.data + ksize2;
int i = 0;
{
if( !checkHardwareSupport(CV_CPU_SSE2) )
return 0;
-
+
const float* kf = (const float*)&coeffs[0];
int i = 0, k, nz = _nz;
__m128 d4 = _mm_set1_ps(delta);
{
if( !checkHardwareSupport(CV_CPU_SSE2) )
return 0;
-
+
const float* kf = (const float*)&coeffs[0];
short* dst = (short*)_dst;
int i = 0, k, nz = _nz;
{
if( !checkHardwareSupport(CV_CPU_SSE) )
return 0;
-
+
const float* kf = (const float*)&coeffs[0];
const float** src = (const float**)_src;
float* dst = (float*)_dst;
(kernel.rows == 1 || kernel.cols == 1));
vecOp = _vecOp;
}
-
+
void operator()(const uchar* src, uchar* dst, int width, int cn)
{
int _ksize = ksize;
s0 += f*S[0]; s1 += f*S[1];
s2 += f*S[2]; s3 += f*S[3];
}
-
+
D[i] = s0; D[i+1] = s1;
D[i+2] = s2; D[i+3] = s3;
}
symmetryType = _symmetryType;
CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 && this->ksize <= 5 );
}
-
+
void operator()(const uchar* src, uchar* dst, int width, int cn)
{
int ksize2 = this->ksize/2, ksize2n = ksize2*cn;
{
typedef typename CastOp::type1 ST;
typedef typename CastOp::rtype DT;
-
+
ColumnFilter( const Mat& _kernel, int _anchor,
double _delta, const CastOp& _castOp=CastOp(),
const VecOp& _vecOp=VecOp() )
{
DT* D = (DT*)dst;
i = vecOp(src, dst, width);
- #if CV_ENABLE_UNROLLED
+ #if CV_ENABLE_UNROLLED
for( ; i <= width - 4; i += 4 )
{
ST f = ky[0];
{
typedef typename CastOp::type1 ST;
typedef typename CastOp::rtype DT;
-
+
SymmColumnSmallFilter( const Mat& _kernel, int _anchor,
double _delta, int _symmetryType,
const CastOp& _castOp=CastOp(),
{
if( is_1_2_1 )
{
- #if CV_ENABLE_UNROLLED
+ #if CV_ENABLE_UNROLLED
for( ; i <= width - 4; i += 4 )
{
ST s0 = S0[i] + S1[i]*2 + S2[i] + _delta;
D[i+3] = castOp(s1);
}
#else
- for( ; i < width; i ++ )
+ for( ; i < width; i ++ )
{
ST s0 = S0[i] + S1[i]*2 + S2[i] + _delta;
D[i] = castOp(s0);
}
else if( is_1_m2_1 )
{
- #if CV_ENABLE_UNROLLED
+ #if CV_ENABLE_UNROLLED
for( ; i <= width - 4; i += 4 )
{
ST s0 = S0[i] - S1[i]*2 + S2[i] + _delta;
D[i+3] = castOp(s1);
}
#else
- for( ; i < width; i ++ )
+ for( ; i < width; i ++ )
{
ST s0 = S0[i] - S1[i]*2 + S2[i] + _delta;
D[i] = castOp(s0);
D[i+3] = castOp(s1);
}
#else
- for( ; i < width; i ++ )
+ for( ; i < width; i ++ )
{
ST s0 = S2[i] - S0[i] + _delta;
D[i] = castOp(s0);
};
}
-
+
cv::Ptr<cv::BaseRowFilter> cv::getLinearRowFilter( int srcType, int bufType,
InputArray _kernel, int anchor,
int symmetryType )
return Ptr<BaseRowFilter>(new SymmRowSmallFilter<float, float, SymmRowSmallVec_32f>
(kernel, anchor, symmetryType, SymmRowSmallVec_32f(kernel, symmetryType)));
}
-
+
if( sdepth == CV_8U && ddepth == CV_32S )
return Ptr<BaseRowFilter>(new RowFilter<uchar, int, RowVec_8u32s>
(kernel, anchor, RowVec_8u32s(kernel)));
cv::Ptr<cv::BaseColumnFilter> cv::getLinearColumnFilter( int bufType, int dstType,
InputArray _kernel, int anchor,
- int symmetryType, double delta,
+ int symmetryType, double delta,
int bits )
{
Mat kernel = _kernel.getMat();
{
typedef typename CastOp::type1 KT;
typedef typename CastOp::rtype DT;
-
+
Filter2D( const Mat& _kernel, Point _anchor,
double _delta, const CastOp& _castOp=CastOp(),
const VecOp& _vecOp=VecOp() )
kernel = _kernel;
else
_kernel.convertTo(kernel, kdepth, _kernel.type() == CV_32S ? 1./(1 << bits) : 1.);
-
+
if( sdepth == CV_8U && ddepth == CV_8U )
return Ptr<BaseFilter>(new Filter2D<uchar, Cast<float, uchar>, FilterVec_8u>
(kernel, anchor, delta, Cast<float, uchar>(), FilterVec_8u(kernel, 0, delta)));
{
Mat _kernel = filter_kernel.getMat();
_srcType = CV_MAT_TYPE(_srcType);
- _dstType = CV_MAT_TYPE(_dstType);
+ _dstType = CV_MAT_TYPE(_dstType);
int cn = CV_MAT_CN(_srcType);
CV_Assert( cn == CV_MAT_CN(_dstType) );
int bits = 0;
/*int sdepth = CV_MAT_DEPTH(_srcType), ddepth = CV_MAT_DEPTH(_dstType);
- int ktype = _kernel.depth() == CV_32S ? KERNEL_INTEGER : getKernelType(_kernel, _anchor);
+ int ktype = _kernel.depth() == CV_32S ? KERNEL_INTEGER : getKernelType(_kernel, _anchor);
if( sdepth == CV_8U && (ddepth == CV_8U || ddepth == CV_16S) &&
_kernel.rows*_kernel.cols <= (1 << 10) )
{
bits = (ktype & KERNEL_INTEGER) ? 0 : 11;
_kernel.convertTo(kernel, CV_32S, 1 << bits);
}*/
-
+
Ptr<BaseFilter> _filter2D = getLinearFilter(_srcType, _dstType,
kernel, _anchor, _delta, bits);
double delta, int borderType )
{
Mat src = _src.getMat(), kernel = _kernel.getMat();
-
+
if( ddepth < 0 )
ddepth = src.depth();
double delta, int borderType )
{
Mat src = _src.getMat(), kernelX = _kernelX.getMat(), kernelY = _kernelY.getMat();
-
+
if( ddepth < 0 )
ddepth = src.depth();
int ts;
int dist;
TWeight weight;
- uchar t;
+ uchar t;
};
class Edge
{
v->t = v->weight < 0;
}
else
- v->parent = 0;
+ v->parent = 0;
}
first = first->next;
last->next = nilNode;
curr_ts++;
while( !orphans.empty() )
{
- Vtx* v = orphans.back();
+ Vtx* v2 = orphans.back();
orphans.pop_back();
int d, minDist = INT_MAX;
e0 = 0;
- vt = v->t;
+ vt = v2->t;
- for( ei = v->first; ei != 0; ei = edgePtr[ei].next )
+ for( ei = v2->first; ei != 0; ei = edgePtr[ei].next )
{
if( edgePtr[ei^(vt^1)].weight == 0 )
continue;
}
}
- if( (v->parent = e0) > 0 )
+ if( (v2->parent = e0) > 0 )
{
- v->ts = curr_ts;
- v->dist = minDist;
+ v2->ts = curr_ts;
+ v2->dist = minDist;
continue;
}
/* no parent is found */
- v->ts = 0;
- for( ei = v->first; ei != 0; ei = edgePtr[ei].next )
+ v2->ts = 0;
+ for( ei = v2->first; ei != 0; ei = edgePtr[ei].next )
{
u = vtxPtr+edgePtr[ei].dst;
ej = u->parent;
u->next = nilNode;
last = last->next = u;
}
- if( ej > 0 && vtxPtr+edgePtr[ej].dst == v )
+ if( ej > 0 && vtxPtr+edgePtr[ej].dst == v2 )
{
orphans.push_back(u);
u->parent = ORPHAN;
// copy or use the software.
//
//
-// Intel License Agreement
-// For Open Source Computer Vision Library
+// Intel License Agreement
+// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
template<> void Ptr<CvHistogram>::delete_obj()
{ cvReleaseHist(&obj); }
-
+
////////////////// Helper functions //////////////////////
static const size_t OUT_OF_RANGE = (size_t)1 << (sizeof(size_t)*8 - 2);
int i, j;
_tab.resize((high-low)*dims);
size_t* tab = &_tab[0];
-
+
if( uniform )
{
for( i = 0; i < dims; i++ )
double b = uniranges[i*2+1];
int sz = !issparse ? hist.size[i] : shist.size(i);
size_t step = !issparse ? hist.step[i] : 1;
-
+
for( j = low; j < high; j++ )
{
int idx = cvFloor(j*a + b);
written_idx = idx*step;
else
written_idx = OUT_OF_RANGE;
-
+
tab[i*(high - low) + j - low] = written_idx;
}
}
int idx = -1, sz = !issparse ? hist.size[i] : shist.size(i);
size_t written_idx = OUT_OF_RANGE;
size_t step = !issparse ? hist.step[i] : 1;
-
+
for(j = low;;)
{
for( ; j < limit; j++ )
tab[i*(high - low) + j - low] = written_idx;
-
+
if( (unsigned)(++idx) < (unsigned)sz )
{
limit = std::min(cvCeil(ranges[i][idx+1]), high);
{
int i, j, c;
CV_Assert( channels != 0 || nimages == dims );
-
+
imsize = images[0].size();
int depth = images[0].depth(), esz1 = (int)images[0].elemSize1();
bool isContinuous = true;
-
+
ptrs.resize(dims + 1);
deltas.resize((dims + 1)*2);
-
+
for( i = 0; i < dims; i++ )
{
if(!channels)
break;
CV_Assert( j < nimages );
}
-
+
CV_Assert( images[j].size() == imsize && images[j].depth() == depth );
if( !images[j].isContinuous() )
isContinuous = false;
deltas[i*2] = images[j].channels();
deltas[i*2+1] = (int)(images[j].step/esz1 - imsize.width*deltas[i*2]);
}
-
+
if( mask.data )
{
CV_Assert( mask.size() == imsize && mask.channels() == 1 );
deltas[dims*2] = 1;
deltas[dims*2 + 1] = (int)(mask.step/mask.elemSize1());
}
-
+
if( isContinuous )
{
imsize.width *= imsize.height;
imsize.height = 1;
}
-
+
if( !ranges )
{
CV_Assert( depth == CV_8U );
-
+
uniranges.resize( dims*2 );
for( i = 0; i < dims; i++ )
{
{
for( i = 0; i < dims; i++ )
{
- size_t j, n = histSize[i];
- for( j = 0; j < n; j++ )
- CV_Assert( ranges[i][j] < ranges[i][j+1] );
+ size_t n = histSize[i];
+ for(size_t k = 0; k < n; k++ )
+ CV_Assert( ranges[i][k] < ranges[i][k+1] );
}
}
}
-
-
-////////////////////////////////// C A L C U L A T E H I S T O G R A M ////////////////////////////////////
-
+
+
+////////////////////////////////// C A L C U L A T E H I S T O G R A M ////////////////////////////////////
+
template<typename T> static void
calcHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
Size imsize, Mat& hist, int dims, const float** _ranges,
int mstep = _deltas[dims*2 + 1];
int size[CV_MAX_DIM];
size_t hstep[CV_MAX_DIM];
-
+
for( i = 0; i < dims; i++ )
{
size[i] = hist.size[i];
hstep[i] = hist.step[i];
}
-
+
if( uniform )
{
const double* uniranges = &_uniranges[0];
-
+
if( dims == 1 )
{
double a = uniranges[0], b = uniranges[1];
int sz = size[0], d0 = deltas[0], step0 = deltas[1];
const T* p0 = (const T*)ptrs[0];
-
+
for( ; imsize.height--; p0 += step0, mask += mstep )
{
if( !mask )
size_t hstep0 = hstep[0];
const T* p0 = (const T*)ptrs[0];
const T* p1 = (const T*)ptrs[1];
-
+
for( ; imsize.height--; p0 += step0, p1 += step1, mask += mstep )
{
if( !mask )
size_t hstep0 = hstep[0], hstep1 = hstep[1];
const T* p0 = (const T*)ptrs[0];
const T* p1 = (const T*)ptrs[1];
- const T* p2 = (const T*)ptrs[2];
-
+ const T* p2 = (const T*)ptrs[2];
+
for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, mask += mstep )
{
if( !mask )
ptrs[i] += deltas[i*2];
Hptr += idx*hstep[i];
}
-
+
if( i == dims )
++*((int*)Hptr);
else
ptrs[i] += deltas[i*2];
Hptr += idx*hstep[i];
}
-
+
if( i == dims )
++*((int*)Hptr);
else
const float* ranges[CV_MAX_DIM];
for( i = 0; i < dims; i++ )
ranges[i] = &_ranges[i][0];
-
+
for( ; imsize.height--; mask += mstep )
{
for( x = 0; x < imsize.width; x++ )
{
uchar* Hptr = H;
i = 0;
-
+
if( !mask || mask[x] )
for( ; i < dims; i++ )
{
float v = (float)*ptrs[i];
const float* R = ranges[i];
int idx = -1, sz = size[i];
-
+
while( v >= R[idx+1] && ++idx < sz )
; // nop
-
+
if( (unsigned)idx >= (unsigned)sz )
break;
ptrs[i] += deltas[i*2];
Hptr += idx*hstep[i];
}
-
+
if( i == dims )
++*((int*)Hptr);
else
for( ; i < dims; i++ )
ptrs[i] += deltas[i*2];
}
-
+
for( i = 0; i < dims; i++ )
ptrs[i] += deltas[i*2 + 1];
}
- }
+ }
}
-
-
+
+
static void
calcHist_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
Size imsize, Mat& hist, int dims, const float** _ranges,
uchar** ptrs = &_ptrs[0];
const int* deltas = &_deltas[0];
uchar* H = hist.data;
- int i, x;
+ int x;
const uchar* mask = _ptrs[dims];
int mstep = _deltas[dims*2 + 1];
vector<size_t> _tab;
-
+
calcHistLookupTables_8u( hist, SparseMat(), dims, _ranges, _uniranges, uniform, false, _tab );
const size_t* tab = &_tab[0];
-
+
if( dims == 1 )
{
int d0 = deltas[0], step0 = deltas[1];
int matH[256] = {0};
const uchar* p0 = (const uchar*)ptrs[0];
-
+
for( ; imsize.height--; p0 += step0, mask += mstep )
{
if( !mask )
}
p0 += x;
}
- else
+ else
for( x = 0; x <= imsize.width - 4; x += 4 )
{
int t0 = p0[0], t1 = p0[d0];
matH[t0]++; matH[t1]++;
p0 += d0*2;
}
-
+
for( ; x < imsize.width; x++, p0 += d0 )
matH[*p0]++;
}
if( mask[x] )
matH[*p0]++;
}
-
- for( i = 0; i < 256; i++ )
+
+ for(int i = 0; i < 256; i++ )
{
size_t hidx = tab[i];
if( hidx < OUT_OF_RANGE )
d1 = deltas[2], step1 = deltas[3];
const uchar* p0 = (const uchar*)ptrs[0];
const uchar* p1 = (const uchar*)ptrs[1];
-
+
for( ; imsize.height--; p0 += step0, p1 += step1, mask += mstep )
{
if( !mask )
int d0 = deltas[0], step0 = deltas[1],
d1 = deltas[2], step1 = deltas[3],
d2 = deltas[4], step2 = deltas[5];
-
+
const uchar* p0 = (const uchar*)ptrs[0];
const uchar* p1 = (const uchar*)ptrs[1];
const uchar* p2 = (const uchar*)ptrs[2];
-
+
for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, mask += mstep )
{
if( !mask )
for( x = 0; x < imsize.width; x++ )
{
uchar* Hptr = H;
- for( i = 0; i < dims; i++ )
+ int i = 0;
+ for( ; i < dims; i++ )
{
size_t idx = tab[*ptrs[i] + i*256];
if( idx >= OUT_OF_RANGE )
Hptr += idx;
ptrs[i] += deltas[i*2];
}
-
+
if( i == dims )
++*((int*)Hptr);
else
Hptr += idx;
ptrs[i] += deltas[i*2];
}
-
+
if( i == dims )
++*((int*)Hptr);
else
for( ; i < dims; i++ )
ptrs[i] += deltas[i*2];
}
- for( i = 0; i < dims; i++ )
+ for(int i = 0; i < dims; i++ )
ptrs[i] += deltas[i*2 + 1];
}
}
const float** ranges, bool uniform, bool accumulate )
{
Mat mask = _mask.getMat();
-
+
CV_Assert(dims > 0 && histSize);
-
+
uchar* histdata = _hist.getMat().data;
_hist.create(dims, histSize, CV_32F);
Mat hist = _hist.getMat(), ihist = hist;
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
-
+
if( !accumulate || histdata != hist.data )
hist = Scalar(0.);
else
hist.convertTo(ihist, CV_32S);
-
+
vector<uchar*> ptrs;
vector<int> deltas;
vector<double> uniranges;
Size imsize;
-
+
CV_Assert( !mask.data || mask.type() == CV_8UC1 );
histPrepareImages( images, nimages, channels, mask, dims, hist.size, ranges,
uniform, ptrs, deltas, imsize, uniranges );
const double* _uniranges = uniform ? &uniranges[0] : 0;
-
+
int depth = images[0].depth();
-
+
if( depth == CV_8U )
calcHist_8u(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform );
else if( depth == CV_16U )
calcHist_<float>(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform );
else
CV_Error(CV_StsUnsupportedFormat, "");
-
+
ihist.convertTo(hist, CV_32F);
}
int mstep = _deltas[dims*2 + 1];
const int* size = hist.hdr->size;
int idx[CV_MAX_DIM];
-
+
if( uniform )
{
const double* uniranges = &_uniranges[0];
-
+
for( ; imsize.height--; mask += mstep )
{
for( x = 0; x < imsize.width; x++ )
break;
ptrs[i] += deltas[i*2];
}
-
+
if( i == dims )
++*(int*)hist.ptr(idx, true);
else
const float* ranges[CV_MAX_DIM];
for( i = 0; i < dims; i++ )
ranges[i] = &_ranges[i][0];
-
+
for( ; imsize.height--; mask += mstep )
{
for( x = 0; x < imsize.width; x++ )
{
i = 0;
-
+
if( !mask || mask[x] )
for( ; i < dims; i++ )
{
float v = (float)*ptrs[i];
const float* R = ranges[i];
int j = -1, sz = size[i];
-
+
while( v >= R[j+1] && ++j < sz )
; // nop
-
+
if( (unsigned)j >= (unsigned)sz )
break;
- ptrs[i] += deltas[i*2];
+ ptrs[i] += deltas[i*2];
idx[i] = j;
}
-
+
if( i == dims )
++*(int*)hist.ptr(idx, true);
else
for( ; i < dims; i++ )
ptrs[i] += deltas[i*2];
}
-
+
for( i = 0; i < dims; i++ )
ptrs[i] += deltas[i*2 + 1];
}
- }
-}
+ }
+}
+
-
static void
calcSparseHist_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
Size imsize, SparseMat& hist, int dims, const float** _ranges,
{
uchar** ptrs = (uchar**)&_ptrs[0];
const int* deltas = &_deltas[0];
- int i, x;
+ int x;
const uchar* mask = _ptrs[dims];
int mstep = _deltas[dims*2 + 1];
int idx[CV_MAX_DIM];
vector<size_t> _tab;
-
+
calcHistLookupTables_8u( Mat(), hist, dims, _ranges, _uniranges, uniform, true, _tab );
const size_t* tab = &_tab[0];
-
+
for( ; imsize.height--; mask += mstep )
{
for( x = 0; x < imsize.width; x++ )
ptrs[i] += deltas[i*2];
idx[i] = (int)hidx;
}
-
+
if( i == dims )
++*(int*)hist.ptr(idx,true);
else
for( ; i < dims; i++ )
ptrs[i] += deltas[i*2];
}
- for( i = 0; i < dims; i++ )
+ for(int i = 0; i < dims; i++ )
ptrs[i] += deltas[i*2 + 1];
}
-}
-
+}
+
static void calcHist( const Mat* images, int nimages, const int* channels,
const Mat& mask, SparseMat& hist, int dims, const int* histSize,
const float** ranges, bool uniform, bool accumulate, bool keepInt )
{
size_t i, N;
-
+
if( !accumulate )
hist.create(dims, histSize, CV_32F);
else
val->i = cvRound(val->f);
}
}
-
+
vector<uchar*> ptrs;
vector<int> deltas;
vector<double> uniranges;
Size imsize;
-
+
CV_Assert( !mask.data || mask.type() == CV_8UC1 );
histPrepareImages( images, nimages, channels, mask, dims, hist.hdr->size, ranges,
uniform, ptrs, deltas, imsize, uniranges );
const double* _uniranges = uniform ? &uniranges[0] : 0;
-
+
int depth = images[0].depth();
if( depth == CV_8U )
calcSparseHist_8u(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, uniform );
calcSparseHist_<float>(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, uniform );
else
CV_Error(CV_StsUnsupportedFormat, "");
-
+
if( !keepInt )
{
SparseMatIterator it = hist.begin();
}
}
}
-
+
}
-
+
void cv::calcHist( const Mat* images, int nimages, const int* channels,
InputArray _mask, SparseMat& hist, int dims, const int* histSize,
const float** ranges, bool uniform, bool accumulate )
{
int i, dims = (int)histSize.size(), rsz = (int)ranges.size(), csz = (int)channels.size();
int nimages = (int)images.total();
-
+
CV_Assert(nimages > 0 && dims > 0);
CV_Assert(rsz == dims*2 || (rsz == 0 && images.depth(0) == CV_8U));
CV_Assert(csz == 0 || csz == dims);
for( i = 0; i < rsz/2; i++ )
_ranges[i] = (float*)&ranges[i*2];
}
-
+
AutoBuffer<Mat> buf(nimages);
for( i = 0; i < nimages; i++ )
buf[i] = images.getMat(i);
-
+
calcHist(&buf[0], nimages, csz ? &channels[0] : 0,
mask, hist, dims, &histSize[0], rsz ? (const float**)_ranges : 0,
true, accumulate);
}
-/////////////////////////////////////// B A C K P R O J E C T ////////////////////////////////////
-
+/////////////////////////////////////// B A C K P R O J E C T ////////////////////////////////////
+
namespace cv
{
int bpstep = _deltas[dims*2 + 1];
int size[CV_MAX_DIM];
size_t hstep[CV_MAX_DIM];
-
+
for( i = 0; i < dims; i++ )
{
size[i] = hist.size[i];
hstep[i] = hist.step[i];
}
-
+
if( uniform )
{
const double* uniranges = &_uniranges[0];
-
+
if( dims == 1 )
{
double a = uniranges[0], b = uniranges[1];
int sz = size[0], d0 = deltas[0], step0 = deltas[1];
const T* p0 = (const T*)ptrs[0];
-
+
for( ; imsize.height--; p0 += step0, bproj += bpstep )
{
for( x = 0; x < imsize.width; x++, p0 += d0 )
size_t hstep0 = hstep[0];
const T* p0 = (const T*)ptrs[0];
const T* p1 = (const T*)ptrs[1];
-
+
for( ; imsize.height--; p0 += step0, p1 += step1, bproj += bpstep )
{
for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 )
size_t hstep0 = hstep[0], hstep1 = hstep[1];
const T* p0 = (const T*)ptrs[0];
const T* p1 = (const T*)ptrs[1];
- const T* p2 = (const T*)ptrs[2];
-
+ const T* p2 = (const T*)ptrs[2];
+
for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, bproj += bpstep )
{
for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 )
ptrs[i] += deltas[i*2];
Hptr += idx*hstep[i];
}
-
+
if( i == dims )
bproj[x] = saturate_cast<BT>(*(float*)Hptr*scale);
else
const float* ranges[CV_MAX_DIM];
for( i = 0; i < dims; i++ )
ranges[i] = &_ranges[i][0];
-
+
for( ; imsize.height--; bproj += bpstep )
{
for( x = 0; x < imsize.width; x++ )
float v = (float)*ptrs[i];
const float* R = ranges[i];
int idx = -1, sz = size[i];
-
+
while( v >= R[idx+1] && ++idx < sz )
; // nop
-
+
if( (unsigned)idx >= (unsigned)sz )
break;
ptrs[i] += deltas[i*2];
Hptr += idx*hstep[i];
}
-
+
if( i == dims )
bproj[x] = saturate_cast<BT>(*(float*)Hptr*scale);
else
ptrs[i] += deltas[i*2];
}
}
-
+
for( i = 0; i < dims; i++ )
ptrs[i] += deltas[i*2 + 1];
}
- }
+ }
}
uchar* bproj = _ptrs[dims];
int bpstep = _deltas[dims*2 + 1];
vector<size_t> _tab;
-
+
calcHistLookupTables_8u( hist, SparseMat(), dims, _ranges, _uniranges, uniform, false, _tab );
const size_t* tab = &_tab[0];
-
+
if( dims == 1 )
{
int d0 = deltas[0], step0 = deltas[1];
uchar matH[256] = {0};
const uchar* p0 = (const uchar*)ptrs[0];
-
+
for( i = 0; i < 256; i++ )
{
size_t hidx = tab[i];
if( hidx < OUT_OF_RANGE )
matH[i] = saturate_cast<uchar>(*(float*)(H + hidx)*scale);
}
-
+
for( ; imsize.height--; p0 += step0, bproj += bpstep )
{
if( d0 == 1 )
}
p0 += x;
}
- else
+ else
for( x = 0; x <= imsize.width - 4; x += 4 )
{
uchar t0 = matH[p0[0]], t1 = matH[p0[d0]];
bproj[x+2] = t0; bproj[x+3] = t1;
p0 += d0*2;
}
-
+
for( ; x < imsize.width; x++, p0 += d0 )
bproj[x] = matH[*p0];
}
d1 = deltas[2], step1 = deltas[3];
const uchar* p0 = (const uchar*)ptrs[0];
const uchar* p1 = (const uchar*)ptrs[1];
-
+
for( ; imsize.height--; p0 += step0, p1 += step1, bproj += bpstep )
{
for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1 )
const uchar* p0 = (const uchar*)ptrs[0];
const uchar* p1 = (const uchar*)ptrs[1];
const uchar* p2 = (const uchar*)ptrs[2];
-
+
for( ; imsize.height--; p0 += step0, p1 += step1, p2 += step2, bproj += bpstep )
{
for( x = 0; x < imsize.width; x++, p0 += d0, p1 += d1, p2 += d2 )
ptrs[i] += deltas[i*2];
Hptr += idx;
}
-
+
if( i == dims )
bproj[x] = saturate_cast<uchar>(*(float*)Hptr*scale);
else
ptrs[i] += deltas[i*2 + 1];
}
}
-}
+}
}
-
+
void cv::calcBackProject( const Mat* images, int nimages, const int* channels,
InputArray _hist, OutputArray _backProject,
const float** ranges, double scale, bool uniform )
vector<double> uniranges;
Size imsize;
int dims = hist.dims == 2 && hist.size[1] == 1 ? 1 : hist.dims;
-
+
CV_Assert( dims > 0 && hist.data );
_backProject.create( images[0].size(), images[0].depth() );
Mat backProject = _backProject.getMat();
histPrepareImages( images, nimages, channels, backProject, dims, hist.size, ranges,
uniform, ptrs, deltas, imsize, uniranges );
const double* _uniranges = uniform ? &uniranges[0] : 0;
-
+
int depth = images[0].depth();
if( depth == CV_8U )
calcBackProj_8u(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform);
const int* size = hist.hdr->size;
int idx[CV_MAX_DIM];
const SparseMat_<float>& hist_ = (const SparseMat_<float>&)hist;
-
+
if( uniform )
{
const double* uniranges = &_uniranges[0];
break;
ptrs[i] += deltas[i*2];
}
-
+
if( i == dims )
bproj[x] = saturate_cast<BT>(hist_(idx)*scale);
else
const float* ranges[CV_MAX_DIM];
for( i = 0; i < dims; i++ )
ranges[i] = &_ranges[i][0];
-
+
for( ; imsize.height--; bproj += bpstep )
{
for( x = 0; x < imsize.width; x++ )
float v = (float)*ptrs[i];
const float* R = ranges[i];
int j = -1, sz = size[i];
-
+
while( v >= R[j+1] && ++j < sz )
; // nop
-
+
if( (unsigned)j >= (unsigned)sz )
break;
idx[i] = j;
ptrs[i] += deltas[i*2];
}
-
+
if( i == dims )
bproj[x] = saturate_cast<BT>(hist_(idx)*scale);
else
ptrs[i] += deltas[i*2];
}
}
-
+
for( i = 0; i < dims; i++ )
ptrs[i] += deltas[i*2 + 1];
}
- }
+ }
}
int bpstep = _deltas[dims*2 + 1];
vector<size_t> _tab;
int idx[CV_MAX_DIM];
-
+
calcHistLookupTables_8u( Mat(), hist, dims, _ranges, _uniranges, uniform, true, _tab );
const size_t* tab = &_tab[0];
-
+
for( ; imsize.height--; bproj += bpstep )
{
for( x = 0; x < imsize.width; x++ )
idx[i] = (int)hidx;
ptrs[i] += deltas[i*2];
}
-
+
if( i == dims )
bproj[x] = saturate_cast<uchar>(hist.value<float>(idx)*scale);
else
for( i = 0; i < dims; i++ )
ptrs[i] += deltas[i*2 + 1];
}
-}
+}
}
vector<double> uniranges;
Size imsize;
int dims = hist.dims();
-
+
CV_Assert( dims > 0 );
_backProject.create( images[0].size(), images[0].depth() );
Mat backProject = _backProject.getMat();
dims, hist.hdr->size, ranges,
uniform, ptrs, deltas, imsize, uniranges );
const double* _uniranges = uniform ? &uniranges[0] : 0;
-
+
int depth = images[0].depth();
if( depth == CV_8U )
calcSparseBackProj_8u(ptrs, deltas, imsize, hist, dims, ranges,
CV_Error(CV_StsUnsupportedFormat, "");
}
-
+
void cv::calcBackProject( InputArrayOfArrays images, const vector<int>& channels,
InputArray hist, OutputArray dst,
const vector<float>& ranges,
for( i = 0; i < rsz/2; i++ )
_ranges[i] = (float*)&ranges[i*2];
}
-
+
AutoBuffer<Mat> buf(nimages);
for( i = 0; i < nimages; i++ )
buf[i] = images.getMat(i);
-
+
calcBackProject(&buf[0], nimages, csz ? &channels[0] : 0,
hist, dst, rsz ? (const float**)_ranges : 0, scale, true);
}
-
-////////////////// C O M P A R E H I S T O G R A M S ////////////////////////
+
+////////////////// C O M P A R E H I S T O G R A M S ////////////////////////
double cv::compareHist( InputArray _H1, InputArray _H2, int method )
{
NAryMatIterator it(arrays, planes);
double result = 0;
int j, len = (int)it.size;
-
+
CV_Assert( H1.type() == H2.type() && H1.type() == CV_32F );
-
+
double s1 = 0, s2 = 0, s11 = 0, s12 = 0, s22 = 0;
-
+
CV_Assert( it.planes[0].isContinuous() && it.planes[1].isContinuous() );
-
+
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
const float* h1 = (const float*)it.planes[0].data;
const float* h2 = (const float*)it.planes[1].data;
len = it.planes[0].rows*it.planes[0].cols;
-
+
if( method == CV_COMP_CHISQR )
{
for( j = 0; j < len; j++ )
{
double a = h1[j];
double b = h2[j];
-
+
s12 += a*b;
s1 += a;
s11 += a*a;
else
CV_Error( CV_StsBadArg, "Unknown comparison method" );
}
-
+
if( method == CV_COMP_CORREL )
{
size_t total = H1.total();
s1 = fabs(s1) > FLT_EPSILON ? 1./std::sqrt(s1) : 1.;
result = std::sqrt(std::max(1. - result*s1, 0.));
}
-
+
return result;
}
-
+
double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method )
{
double result = 0;
int i, dims = H1.dims();
-
+
CV_Assert( dims > 0 && dims == H2.dims() && H1.type() == H2.type() && H1.type() == CV_32F );
for( i = 0; i < dims; i++ )
CV_Assert( H1.size(i) == H2.size(i) );
-
+
const SparseMat *PH1 = &H1, *PH2 = &H2;
if( PH1->nzcount() > PH2->nzcount() && method != CV_COMP_CHISQR )
std::swap(PH1, PH2);
-
+
SparseMatConstIterator it = PH1->begin();
int N1 = (int)PH1->nzcount(), N2 = (int)PH2->nzcount();
-
+
if( method == CV_COMP_CHISQR )
{
for( i = 0; i < N1; i++, ++it )
else if( method == CV_COMP_CORREL )
{
double s1 = 0, s2 = 0, s11 = 0, s12 = 0, s22 = 0;
-
+
for( i = 0; i < N1; i++, ++it )
{
double v1 = it.value<float>();
s1 += v1;
s11 += v1*v1;
}
-
+
it = PH2->begin();
for( i = 0; i < N2; i++, ++it )
{
s2 += v2;
s22 += v2*v2;
}
-
+
size_t total = 1;
for( i = 0; i < H1.dims(); i++ )
total *= H1.size(i);
else if( method == CV_COMP_BHATTACHARYYA )
{
double s1 = 0, s2 = 0;
-
+
for( i = 0; i < N1; i++, ++it )
{
double v1 = it.value<float>();
result += std::sqrt(v1*v2);
s1 += v1;
}
-
+
it = PH2->begin();
for( i = 0; i < N2; i++, ++it )
s2 += it.value<float>();
-
+
s1 *= s2;
s1 = fabs(s1) > FLT_EPSILON ? 1./std::sqrt(s1) : 1.;
result = std::sqrt(std::max(1. - result*s1, 0.));
}
else
CV_Error( CV_StsBadArg, "Unknown comparison method" );
-
+
return result;
}
-
+
const int CV_HIST_DEFAULT_TYPE = CV_32F;
/* Creates new histogram */
hist = (CvHistogram *)cvAlloc( sizeof( CvHistogram ));
hist->type = CV_HIST_MAGIC_VAL + ((int)type & 1);
- if (uniform) hist->type|= CV_HIST_UNIFORM_FLAG;
+ if (uniform) hist->type|= CV_HIST_UNIFORM_FLAG;
hist->thresh2 = 0;
hist->bins = 0;
if( type == CV_HIST_ARRAY )
cvReleaseData( temp->bins );
temp->bins = 0;
}
-
+
if( temp->thresh2 )
cvFree( &temp->thresh2 );
cvFree( &temp );
CvSparseMat* mat = (CvSparseMat*)hist->bins;
CvSparseMatIterator iterator;
CvSparseNode *node;
-
+
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
CvSparseMatIterator iterator;
CvSparseNode *node;
float scale;
-
+
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
int* idx_min, int* idx_max )
{
double minVal, maxVal;
- int i, dims, size[CV_MAX_DIM];
+ int dims, size[CV_MAX_DIM];
if( !CV_IS_HIST(hist) )
CV_Error( CV_StsBadArg, "Invalid histogram header" );
{
int imin = minPt.y*mat.cols + minPt.x;
int imax = maxPt.y*mat.cols + maxPt.x;
- int i;
-
- for( i = dims - 1; i >= 0; i-- )
+
+ for(int i = dims - 1; i >= 0; i-- )
{
if( idx_min )
{
minVal = maxVal = 0;
}
- for( i = 0; i < dims; i++ )
+ for(int i = 0; i < dims; i++ )
{
if( idx_min )
idx_min[i] = _idx_min ? _idx_min[i] : -1;
{
int i;
int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1;
-
+
if( !CV_IS_HIST(hist1) || !CV_IS_HIST(hist2) )
CV_Error( CV_StsBadArg, "Invalid histogram header[s]" );
cv::Mat H1((const CvMatND*)hist1->bins), H2((const CvMatND*)hist2->bins);
return cv::compareHist(H1, H2, method);
}
-
+
int dims1 = cvGetDims( hist1->bins, size1 );
int dims2 = cvGetDims( hist2->bins, size2 );
-
+
if( dims1 != dims2 )
CV_Error( CV_StsUnmatchedSizes,
"The histograms have different numbers of dimensions" );
-
+
for( i = 0; i < dims1; i++ )
{
if( size1[i] != size2[i] )
double s2 = 0, s22 = 0;
double s12 = 0;
double num, denom2, scale = 1./total;
-
+
for( node1 = cvInitSparseMatIterator( mat1, &iterator );
node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
{
else if( method == CV_COMP_BHATTACHARYYA )
{
double s1 = 0, s2 = 0;
-
+
for( node1 = cvInitSparseMatIterator( mat1, &iterator );
node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
{
}
else
CV_Error( CV_StsBadArg, "Unknown comparison method" );
-
+
return result;
}
float* ranges[CV_MAX_DIM];
float** thresh = 0;
CvHistogram* dst;
-
+
if( !_dst )
CV_Error( CV_StsNullPtr, "Destination double pointer is NULL" );
if( dst && is_sparse == CV_IS_SPARSE_MAT(dst->bins))
{
dims2 = cvGetDims( dst->bins, size2 );
-
+
if( dims1 == dims2 )
{
for( i = 0; i < dims1; i++ )
dims = cvGetDims( hist->bins, size );
for( i = 0; i < dims; i++ )
total += size[i]+1;
-
+
if( uniform )
{
for( i = 0; i < dims; i++ )
if( !ranges[i] )
CV_Error( CV_StsNullPtr, "One of <ranges> elements is NULL" );
-
+
for( j = 0; j <= size[i]; j++ )
{
float val = ranges[i][j];
int size[CV_MAX_DIM];
int i, dims = cvGetDims( hist->bins, size);
bool uniform = CV_IS_UNIFORM_HIST(hist);
-
+
cv::vector<cv::Mat> images(dims);
for( i = 0; i < dims; i++ )
images[i] = cv::cvarrToMat(img[i]);
-
+
cv::Mat _mask;
if( mask )
_mask = cv::cvarrToMat(mask);
-
+
const float* uranges[CV_MAX_DIM] = {0};
const float** ranges = 0;
-
+
if( hist->type & CV_HIST_RANGES_FLAG )
{
ranges = (const float**)hist->thresh2;
ranges = uranges;
}
}
-
+
if( !CV_IS_SPARSE_HIST(hist) )
{
cv::Mat H((const CvMatND*)hist->bins);
else
{
CvSparseMat* sparsemat = (CvSparseMat*)hist->bins;
-
+
if( !accumulate )
cvZero( hist->bins );
cv::SparseMat sH(sparsemat);
cv::calcHist( &images[0], (int)images.size(), 0, _mask, sH, sH.dims(),
sH.dims() > 0 ? sH.hdr->size : 0, ranges, uniform, accumulate != 0, true );
-
+
if( accumulate )
cvZero( sparsemat );
-
+
cv::SparseMatConstIterator it = sH.begin();
int nz = (int)sH.nzcount();
for( i = 0; i < nz; i++, ++it )
int size[CV_MAX_DIM];
int i, dims = cvGetDims( hist->bins, size );
-
+
bool uniform = CV_IS_UNIFORM_HIST(hist);
const float* uranges[CV_MAX_DIM] = {0};
const float** ranges = 0;
-
+
if( hist->type & CV_HIST_RANGES_FLAG )
{
ranges = (const float**)hist->thresh2;
ranges = uranges;
}
}
-
+
cv::vector<cv::Mat> images(dims);
for( i = 0; i < dims; i++ )
images[i] = cv::cvarrToMat(img[i]);
-
+
cv::Mat _dst = cv::cvarrToMat(dst);
-
+
CV_Assert( _dst.size() == images[0].size() && _dst.depth() == images[0].depth() );
-
+
if( !CV_IS_SPARSE_HIST(hist) )
{
cv::Mat H((const CvMatND*)hist->bins);
cvCalcBayesianProb( CvHistogram** src, int count, CvHistogram** dst )
{
int i;
-
+
if( !src || !dst )
CV_Error( CV_StsNullPtr, "NULL histogram array pointer" );
if( count < 2 )
CV_Error( CV_StsOutOfRange, "Too small number of histograms" );
-
+
for( i = 0; i < count; i++ )
{
if( !CV_IS_HIST(src[i]) || !CV_IS_HIST(dst[i]) )
if( !CV_IS_MATND(src[i]->bins) || !CV_IS_MATND(dst[i]->bins) )
CV_Error( CV_StsBadArg, "The function supports dense histograms only" );
}
-
+
cvZero( dst[0]->bins );
// dst[0] = src[0] + ... + src[count-1]
for( i = 0; i < count; i++ )
{
CvMat sstub, *src = cvGetMat(srcarr, &sstub);
CvMat dstub, *dst = cvGetMat(dstarr, &dstub);
-
+
CV_Assert( CV_ARE_SIZES_EQ(src, dst) && CV_ARE_TYPES_EQ(src, dst) &&
CV_MAT_TYPE(src->type) == CV_8UC1 );
CvSize size = cvGetMatSize(src);
const int hist_sz = 256;
int hist[hist_sz];
memset(hist, 0, sizeof(hist));
-
+
for( y = 0; y < size.height; y++ )
{
const uchar* sptr = src->data.ptr + src->step*y;
for( x = 0; x < size.width; x++ )
hist[sptr[x]]++;
}
-
+
float scale = 255.f/(size.width*size.height);
int sum = 0;
uchar lut[hist_sz+1];
h->mat.refcount = mat->refcount;
// increase refcount so freeing temp header doesn't free data
- cvIncRefData( mat );
+ cvIncRefData( mat );
// free temporary header
cvReleaseMatND( &mat );
int step, width, height;
int numangle, numrho;
int total = 0;
- float ang;
- int r, n;
int i, j;
float irho = 1 / rho;
double scale;
memset( accum, 0, sizeof(accum[0]) * (numangle+2) * (numrho+2) );
- for( ang = 0, n = 0; n < numangle; ang += theta, n++ )
+ float ang = 0;
+ for(int n = 0; n < numangle; ang += theta, n++ )
{
tabSin[n] = (float)(sin(ang) * irho);
tabCos[n] = (float)(cos(ang) * irho);
for( j = 0; j < width; j++ )
{
if( image[i * step + j] != 0 )
- for( n = 0; n < numangle; n++ )
+ for(int n = 0; n < numangle; n++ )
{
- r = cvRound( j * tabCos[n] + i * tabSin[n] );
+ int r = cvRound( j * tabCos[n] + i * tabSin[n] );
r += (numrho - 1) / 2;
accum[(n+1) * (numrho+2) + r+1]++;
}
}
// stage 2. find local maximums
- for( r = 0; r < numrho; r++ )
- for( n = 0; n < numangle; n++ )
+ for(int r = 0; r < numrho; r++ )
+ for(int n = 0; n < numangle; n++ )
{
int base = (n+1) * (numrho+2) + r+1;
if( accum[base] > threshold &&
// choose random point out of the remaining ones
int idx = cvRandInt(&rng) % count;
int max_val = threshold-1, max_n = 0;
- CvPoint* pt = (CvPoint*)cvGetSeqElem( seq, idx );
+ CvPoint* point = (CvPoint*)cvGetSeqElem( seq, idx );
CvPoint line_end[2] = {{0,0}, {0,0}};
float a, b;
int* adata = (int*)accum.data;
int good_line;
const int shift = 16;
- i = pt->y;
- j = pt->x;
+ i = point->y;
+ j = point->x;
// "remove" it by overriding it with the last element
- *pt = *(CvPoint*)cvGetSeqElem( seq, count-1 );
+ *point = *(CvPoint*)cvGetSeqElem( seq, count-1 );
// check if it has been excluded already (i.e. belongs to some other line)
if( !mdata0[i*width + j] )
for( x = 0; x < cols; x++ )
{
float vx, vy;
- int sx, sy, x0, y0, x1, y1, r, k;
+ int sx, sy, x0, y0, x1, y1, r;
CvPoint pt;
vx = dx_row[x];
x0 = cvRound((x*idp)*ONE);
y0 = cvRound((y*idp)*ONE);
// Step from min_radius to max_radius in both directions of the gradient
- for( k = 0; k < 2; k++ )
+ for(int k1 = 0; k1 < 2; k1++ )
{
x1 = x0 + min_radius * sx;
y1 = y0 + min_radius * sy;
//Calculate circle's center in pixels
float cx = (float)((x + 0.5f)*dp), cy = (float)(( y + 0.5f )*dp);
float start_dist, dist_sum;
- float r_best = 0, c[3];
+ float r_best = 0;
int max_count = 0;
// Check distance with previously detected circles
for( j = 0; j < circles->total; j++ )
// Check if the circle has enough support
if( max_count > acc_threshold )
{
+ float c[3];
c[0] = cx;
c[1] = cy;
c[2] = (float)r_best;
static const double cs[][2]=
{{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}};
- int i;
if( x < FLT_EPSILON )
{
for( int i = 0; i < 8; i++ )
float sum = 0;
double y0=-(x+3)*CV_PI*0.25, s0 = sin(y0), c0=cos(y0);
- for( i = 0; i < 8; i++ )
+ for(int i = 0; i < 8; i++ )
{
double y = -(x+3-i)*CV_PI*0.25;
coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y));
}
sum = 1.f/sum;
- for( i = 0; i < 8; i++ )
+ for(int i = 0; i < 8; i++ )
coeffs[i] *= sum;
}
const T* srows[MAX_ESIZE]={0};
WT* rows[MAX_ESIZE]={0};
int prev_sy[MAX_ESIZE];
- int k, dy;
+ int dy;
xmin *= cn;
xmax *= cn;
HResize hresize;
VResize vresize;
- for( k = 0; k < ksize; k++ )
+ for(int k = 0; k < ksize; k++ )
{
prev_sy[k] = -1;
rows[k] = (WT*)_buffer + bufstep*k;
// image resize is a separable operation. In case of not too strong
for( dy = 0; dy < dsize.height; dy++, beta += ksize )
{
- int sy0 = yofs[dy], k, k0=ksize, k1=0, ksize2 = ksize/2;
+ int sy0 = yofs[dy], k0=ksize, k1=0, ksize2 = ksize/2;
- for( k = 0; k < ksize; k++ )
+ for(int k = 0; k < ksize; k++ )
{
int sy = clip(sy0 - ksize2 + 1 + k, 0, ssize.height);
for( k1 = std::max(k1, k); k1 < ksize; k1++ )
for( i = 0; i < 8; i++, w += 8 )
{
int yi = y[i];
- const T* S = S0 + yi*sstep;
+ const T* S1 = S0 + yi*sstep;
if( yi < 0 )
continue;
if( x[0] >= 0 )
- sum += (S[x[0]] - cv)*w[0];
+ sum += (S1[x[0]] - cv)*w[0];
if( x[1] >= 0 )
- sum += (S[x[1]] - cv)*w[1];
+ sum += (S1[x[1]] - cv)*w[1];
if( x[2] >= 0 )
- sum += (S[x[2]] - cv)*w[2];
+ sum += (S1[x[2]] - cv)*w[2];
if( x[3] >= 0 )
- sum += (S[x[3]] - cv)*w[3];
+ sum += (S1[x[3]] - cv)*w[3];
if( x[4] >= 0 )
- sum += (S[x[4]] - cv)*w[4];
+ sum += (S1[x[4]] - cv)*w[4];
if( x[5] >= 0 )
- sum += (S[x[5]] - cv)*w[5];
+ sum += (S1[x[5]] - cv)*w[5];
if( x[6] >= 0 )
- sum += (S[x[6]] - cv)*w[6];
+ sum += (S1[x[6]] - cv)*w[6];
if( x[7] >= 0 )
- sum += (S[x[7]] - cv)*w[7];
+ sum += (S1[x[7]] - cv)*w[7];
}
D[k] = castOp(sum);
}
remap( src, dpart, _XY, Mat(), interpolation, borderType, borderValue );
else
{
- Mat matA(bh, bw, CV_16U, A);
- remap( src, dpart, _XY, matA, interpolation, borderType, borderValue );
+ Mat _matA(bh, bw, CV_16U, A);
+ remap( src, dpart, _XY, _matA, interpolation, borderType, borderValue );
}
}
}
remap( src, dpart, _XY, Mat(), interpolation, borderType, borderValue );
else
{
- Mat matA(bh, bw, CV_16U, A);
- remap( src, dpart, _XY, matA, interpolation, borderType, borderValue );
+ Mat _matA(bh, bw, CV_16U, A);
+ remap( src, dpart, _XY, _matA, interpolation, borderType, borderValue );
}
}
}
yi_1 = ((CvPoint2D32f*)(reader.ptr))->y;
}
CV_NEXT_SEQ_ELEM( contour->elem_size, reader );
-
+
xi_12 = xi_1 * xi_1;
yi_12 = yi_1 * yi_1;
const T* ptr = (const T*)(img.data + y*img.step);
WT x0 = 0, x1 = 0, x2 = 0;
MT x3 = 0;
-
+
for( x = 0; x < size.width; x++ )
{
WT p = ptr[x];
typedef int WT;
typedef int MT;
cv::Size size = img.size();
- int x, y;
+ int y;
MT mom[10] = {0,0,0,0,0,0,0,0,0,0};
bool useSIMD = cv::checkHardwareSupport(CV_CPU_SSE2);
-
+
for( y = 0; y < size.height; y++ )
{
const T* ptr = img.ptr<T>(y);
int x0 = 0, x1 = 0, x2 = 0, x3 = 0, x = 0;
-
+
if( useSIMD )
{
__m128i qx_init = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
__m128i dx = _mm_set1_epi16(8);
__m128i z = _mm_setzero_si128(), qx0 = z, qx1 = z, qx2 = z, qx3 = z, qx = qx_init;
-
+
for( ; x <= size.width - 8; x += 8 )
{
__m128i p = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(ptr + x)), z);
qx1 = _mm_add_epi32(qx1, _mm_madd_epi16(p, qx));
qx2 = _mm_add_epi32(qx2, _mm_madd_epi16(p, sx));
qx3 = _mm_add_epi32(qx3, _mm_madd_epi16(px, sx));
-
+
qx = _mm_add_epi16(qx, dx);
}
int CV_DECL_ALIGNED(16) buf[4];
_mm_store_si128((__m128i*)buf, qx0);
x0 = buf[0] + buf[1] + buf[2] + buf[3];
_mm_store_si128((__m128i*)buf, qx1);
- x1 = buf[0] + buf[1] + buf[2] + buf[3];
+ x1 = buf[0] + buf[1] + buf[2] + buf[3];
_mm_store_si128((__m128i*)buf, qx2);
x2 = buf[0] + buf[1] + buf[2] + buf[3];
_mm_store_si128((__m128i*)buf, qx3);
x3 = buf[0] + buf[1] + buf[2] + buf[3];
}
-
+
for( ; x < size.width; x++ )
{
WT p = ptr[x];
WT xp = x * p, xxp;
-
+
x0 += p;
x1 += xp;
xxp = xp * x;
x2 += xxp;
x3 += xxp * x;
}
-
+
WT py = y * x0, sy = y*y;
-
+
mom[9] += ((MT)py) * sy; // m03
mom[8] += ((MT)x1) * sy; // m12
mom[7] += ((MT)x2) * y; // m21
mom[1] += x1; // m10
mom[0] += x0; // m00
}
-
- for( x = 0; x < 10; x++ )
+
+ for(int x = 0; x < 10; x++ )
moments[x] = (double)mom[x];
}
type = CV_MAT_TYPE( mat->type );
depth = CV_MAT_DEPTH( type );
cn = CV_MAT_CN( type );
-
+
cv::Size size = cvGetMatSize( mat );
if( cn > 1 && coi == 0 )
func = momentsInTile<double, double, double>;
else
CV_Error( CV_StsUnsupportedFormat, "" );
-
+
cv::Mat src0(mat);
for( int y = 0; y < size.height; y += TILE_SIZE )
{
cv::Size tileSize;
tileSize.height = std::min(TILE_SIZE, size.height - y);
-
+
for( int x = 0; x < size.width; x += TILE_SIZE )
{
tileSize.width = std::min(TILE_SIZE, size.width - x);
cv::compare( src, 0, tmp, CV_CMP_NE );
src = tmp;
}
-
+
double mom[10];
func( src, mom );
-
+
if(binary)
{
double s = 1./255;
for( int k = 0; k < 10; k++ )
mom[k] *= s;
}
-
+
double xm = x * mom[0], ym = y * mom[0];
- // accumulate moments computed in each tile
+ // accumulate moments computed in each tile
// + m00 ( = m00' )
moments->m00 += mom[0];
// + m21 ( = m21' + x*(2*m11' + 2*y*m10' + x*m01' + x*y*m00') + y*m20')
moments->m21 += mom[7] + x * (2 * (mom[4] + y * mom[1]) + x * (mom[2] + ym)) + y * mom[3];
-
+
// + m12 ( = m12' + y*(2*m11' + 2*x*m01' + y*m10' + x*y*m00') + x*m02')
moments->m12 += mom[8] + y * (2 * (mom[4] + x * mom[2]) + y * (mom[1] + xm)) + x * mom[5];
return m;
}
-
+
}
-
+
cv::Moments cv::moments( InputArray _array, bool binaryImage )
{
CvMoments om;
int i, j = 0, count;
const int N = 16;
float buf[N];
- CvMat buffer = cvMat( 1, N, CV_32F, buf );
+ CvMat buffer = cvMat( 1, N, CV_32F, buf );
CvSeqReader reader;
CvContour contour_header;
CvSeq* contour = 0;
if( contour->total > 1 )
{
int is_float = CV_SEQ_ELTYPE( contour ) == CV_32FC2;
-
+
cvStartReadSeq( contour, &reader, 0 );
cvSetSeqReaderPos( &reader, slice.start_index );
count = cvSliceLength( slice, contour );
CV_NEXT_SEQ_ELEM( contour->elem_size, reader );
// Bugfix by Axel at rubico.com 2010-03-22, affects closed slices only
// wraparound not handled by CV_NEXT_SEQ_ELEM
- if( is_closed && i == count - 2 )
+ if( is_closed && i == count - 2 )
cvSetSeqReaderPos( &reader, slice.start_index );
buffer.data.fl[j] = dx * dx + dy * dy;
*_radius = 0;
CvSeqReader reader;
- int i, k, count;
+ int k, count;
CvPoint2D32f pts[8];
CvContour contour_header;
CvSeqBlock block;
pt_left = pt_right = pt_top = pt_bottom = (CvPoint *)(reader.ptr);
CV_READ_SEQ_ELEM( pt, reader );
- for( i = 1; i < count; i++ )
+ for(int i = 1; i < count; i++ )
{
CvPoint* pt_ptr = (CvPoint*)reader.ptr;
CV_READ_SEQ_ELEM( pt, reader );
pt_left = pt_right = pt_top = pt_bottom = (CvPoint2D32f *) (reader.ptr);
CV_READ_SEQ_ELEM( pt, reader );
- for( i = 1; i < count; i++ )
+ for(int i = 1; i < count; i++ )
{
CvPoint2D32f* pt_ptr = (CvPoint2D32f*)reader.ptr;
CV_READ_SEQ_ELEM( pt, reader );
for( k = 0; k < max_iters; k++ )
{
double min_delta = 0, delta;
- CvPoint2D32f ptfl, farAway = { 0, 0};
- /*only for first iteration because the alg is repared at the loop's foot*/
- if(k==0)
- icvFindEnslosingCicle4pts_32f( pts, ¢er, &radius );
+ CvPoint2D32f ptfl, farAway = { 0, 0};
+ /*only for first iteration because the alg is repared at the loop's foot*/
+ if(k==0)
+ icvFindEnslosingCicle4pts_32f( pts, ¢er, &radius );
cvStartReadSeq( sequence, &reader, 0 );
- for( i = 0; i < count; i++ )
+ for(int i = 0; i < count; i++ )
{
if( !is_float )
{
if( result )
break;
- CvPoint2D32f ptsCopy[4];
- /* find good replacement partner for the point which is at most far away,
- starting with the one that lays in the actual circle (i=3) */
- for(int i = 3; i >=0; i-- )
- {
- for(int j = 0; j < 4; j++ )
- {
- ptsCopy[j]=(i != j)? pts[j]: farAway;
- }
-
- icvFindEnslosingCicle4pts_32f(ptsCopy, ¢er, &radius );
- if( icvIsPtInCircle( pts[i], center, radius )>=0){ // replaced one again in the new circle?
- pts[i] = farAway;
- break;
- }
- }
+ CvPoint2D32f ptsCopy[4];
+ /* find good replacement partner for the point which is at most far away,
+ starting with the one that lays in the actual circle (i=3) */
+ for(int i = 3; i >=0; i-- )
+ {
+ for(int j = 0; j < 4; j++ )
+ {
+ ptsCopy[j]=(i != j)? pts[j]: farAway;
+ }
+
+ icvFindEnslosingCicle4pts_32f(ptsCopy, ¢er, &radius );
+ if( icvIsPtInCircle( pts[i], center, radius )>=0){ // replaced one again in the new circle?
+ pts[i] = farAway;
+ break;
+ }
+ }
}
if( !result )
cvStartReadSeq( sequence, &reader, 0 );
radius = 0.f;
- for( i = 0; i < count; i++ )
+ for(int i = 0; i < count; i++ )
{
CvPoint2D32f ptfl;
float t, dx, dy;
yi_1 = ((CvPoint2D32f*)(reader.ptr))->y;
}
CV_NEXT_SEQ_ELEM( contour->elem_size, reader );
-
+
while( lpt-- > 0 )
{
double dxy, xi, yi;
/****************************************************************************************\
- copy data from one buffer to other buffer
+ copy data from one buffer to other buffer
\****************************************************************************************/
n = ptseq->total;
if( n < 5 )
CV_Error( CV_StsBadSize, "Number of points should be >= 5" );
-
+
/*
- * New fitellipse algorithm, contributed by Dr. Daniel Weiss
+ * New fitellipse algorithm, contributed by Dr. Daniel Weiss
*/
CvPoint2D32f c = {0,0};
double gfp[5], rp[5], t;
cvStartReadSeq( ptseq, &reader );
is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2;
-
+
for( i = 0; i < n; i++ )
{
CvPoint2D32f p;
Ad[i*5 + 3] = p.x;
Ad[i*5 + 4] = p.y;
}
-
+
cvSolve( &A, &b, &x, CV_SVD );
// now use general-form parameters A - E to find the ellipse center:
xmin = ymin = 0;
}
else if( ptseq->total )
- {
+ {
int is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2;
cvStartReadSeq( ptseq, &reader, 0 );
ymin = ymax = pt.y;
for( i = 1; i < ptseq->total; i++ )
- {
+ {
CV_READ_SEQ_ELEM( pt, reader );
-
+
if( xmin > pt.x )
xmin = pt.x;
-
+
if( xmax < pt.x )
xmax = pt.x;
ymin = ymax = CV_TOGGLE_FLT(pt.y);
for( i = 1; i < ptseq->total; i++ )
- {
+ {
CV_READ_SEQ_ELEM( pt, reader );
pt.x = CV_TOGGLE_FLT(pt.x);
pt.y = CV_TOGGLE_FLT(pt.y);
-
+
if( xmin > pt.x )
xmin = pt.x;
-
+
if( xmax < pt.x )
xmax = pt.x;
if( update )
((CvContour*)ptseq)->rect = rect;
-
+
return rect;
}
Mat cameraMatrix = _cameraMatrix.getMat();
if( !centerPrincipalPoint && cameraMatrix.type() == CV_64F )
return cameraMatrix;
-
+
Mat newCameraMatrix;
cameraMatrix.convertTo(newCameraMatrix, CV_64F);
if( centerPrincipalPoint )
{
Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
Mat matR = _matR.getMat(), newCameraMatrix = _newCameraMatrix.getMat();
-
+
if( m1type <= 0 )
m1type = CV_16SC2;
CV_Assert( m1type == CV_16SC2 || m1type == CV_32FC1 || m1type == CV_32FC2 );
double u0 = A(0, 2), v0 = A(1, 2);
double fx = A(0, 0), fy = A(1, 1);
- CV_Assert( distCoeffs.size() == Size(1, 4) || distCoeffs.size() == Size(4, 1) ||
+ CV_Assert( distCoeffs.size() == Size(1, 4) || distCoeffs.size() == Size(4, 1) ||
distCoeffs.size() == Size(1, 5) || distCoeffs.size() == Size(5, 1) ||
distCoeffs.size() == Size(1, 8) || distCoeffs.size() == Size(8, 1));
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), newCameraMatrix = _newCameraMatrix.getMat();
-
+
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
-
+
CV_Assert( dst.data != src.data );
int stripe_size0 = std::min(std::max(1, (1 << 12) / std::max(src.cols, 1)), src.rows);
(_distCoeffs->rows == 1 || _distCoeffs->cols == 1) &&
(_distCoeffs->rows*_distCoeffs->cols == 4 ||
_distCoeffs->rows*_distCoeffs->cols == 5 ||
- _distCoeffs->rows*_distCoeffs->cols == 8));
+ _distCoeffs->rows*_distCoeffs->cols == 8));
_Dk = cvMat( _distCoeffs->rows, _distCoeffs->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(_distCoeffs->type)), k);
-
+
cvConvert( _distCoeffs, &_Dk );
iters = 5;
}
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat();
-
+
CV_Assert( src.isContinuous() && (src.depth() == CV_32F || src.depth() == CV_64F) &&
((src.rows == 1 && src.channels() == 2) || src.cols*src.channels() == 2));
-
+
_dst.create(src.size(), src.type(), -1, true);
Mat dst = _dst.getMat();
-
+
CvMat _csrc = src, _cdst = dst, _ccameraMatrix = cameraMatrix;
CvMat matR, matP, _cdistCoeffs, *pR=0, *pP=0, *pD=0;
if( R.data )
double beta = 1 + 2*alpha;
double v = x*x + y*y + 1, iv = 1/v;
double u = sqrt(beta*v + alpha*alpha);
-
+
double k = (u - alpha)*iv;
double kv = (v*beta/u - (u - alpha)*2)*iv*iv;
double kx = kv*x, ky = kv*y;
-
+
if( projType == PROJ_SPHERICAL_ORTHO )
{
if(J)
double iR = 1/(alpha + 1);
double x1 = std::max(std::min(x*k*iR, 1.), -1.);
double y1 = std::max(std::min(y*k*iR, 1.), -1.);
-
+
if(J)
{
double fx1 = iR/sqrt(1 - x1*x1);
return Point2f();
}
-
+
static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType)
{
static int avgiter = 0, avgn = 0;
-
+
double eps = 1e-12;
Vec2d p(_p.x, _p.y), q(_p.x, _p.y), err;
Vec4d J;
int i, maxiter = 5;
-
+
for( i = 0; i < maxiter; i++ )
{
Point2f p1 = mapPointSpherical(Point2f((float)q[0], (float)q[1]), alpha, &J, projType);
err = Vec2d(p1.x, p1.y) - p;
if( err[0]*err[0] + err[1]*err[1] < eps )
break;
-
+
Vec4d JtJ(J[0]*J[0] + J[2]*J[2], J[0]*J[1] + J[2]*J[3],
J[0]*J[1] + J[2]*J[3], J[1]*J[1] + J[3]*J[3]);
double d = JtJ[0]*JtJ[3] - JtJ[1]*JtJ[2];
d = d ? 1./d : 0;
Vec4d iJtJ(JtJ[3]*d, -JtJ[1]*d, -JtJ[2]*d, JtJ[0]*d);
Vec2d JtErr(J[0]*err[0] + J[2]*err[1], J[1]*err[0] + J[3]*err[1]);
-
+
q -= Vec2d(iJtJ[0]*JtErr[0] + iJtJ[1]*JtErr[1], iJtJ[2]*JtErr[0] + iJtJ[3]*JtErr[1]);
//Matx22d J(kx*x + k, kx*y, ky*x, ky*y + k);
//q -= Vec2d((J.t()*J).inv()*(J.t()*err));
}
-
+
if( i < maxiter )
{
avgiter += i;
if( avgn == 1500 )
printf("avg iters = %g\n", (double)avgiter/avgn);
}
-
+
return i < maxiter ? Point2f((float)q[0], (float)q[1]) : Point2f(-FLT_MAX, -FLT_MAX);
}
}
-
+
float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeffs0,
Size imageSize, int destImageWidth, int m1type,
OutputArray _map1, OutputArray _map2, int projType, double _alpha )
Point2f dcenter((destImageWidth-1)*0.5f, 0.f);
float xmin = FLT_MAX, xmax = -FLT_MAX, ymin = FLT_MAX, ymax = -FLT_MAX;
int N = 9;
- std::vector<Point2f> u(1), v(1);
- Mat _u(u), I = Mat::eye(3,3,CV_64F);
+ std::vector<Point2f> uvec(1), vvec(1);
+ Mat I = Mat::eye(3,3,CV_64F);
float alpha = (float)_alpha;
-
+
int ndcoeffs = distCoeffs0.cols*distCoeffs0.rows*distCoeffs0.channels();
CV_Assert((distCoeffs0.cols == 1 || distCoeffs0.rows == 1) &&
(ndcoeffs == 4 || ndcoeffs == 5 || ndcoeffs == 8));
CV_Assert(cameraMatrix0.size() == Size(3,3));
distCoeffs0.convertTo(distCoeffs,CV_64F);
cameraMatrix0.convertTo(cameraMatrix,CV_64F);
-
+
alpha = std::min(alpha, 0.999f);
-
+
for( int i = 0; i < N; i++ )
for( int j = 0; j < N; j++ )
{
Point2f p((float)j*imageSize.width/(N-1), (float)i*imageSize.height/(N-1));
- u[0] = p;
- undistortPoints(_u, v, cameraMatrix, distCoeffs, I, I);
- Point2f q = mapPointSpherical(v[0], alpha, 0, projType);
+ uvec[0] = p;
+ undistortPoints(uvec, vvec, cameraMatrix, distCoeffs, I, I);
+ Point2f q = mapPointSpherical(vvec[0], alpha, 0, projType);
if( xmin > q.x ) xmin = q.x;
if( xmax < q.x ) xmax = q.x;
if( ymin > q.y ) ymin = q.y;
if( ymax < q.y ) ymax = q.y;
}
-
+
float scale = (float)std::min(dcenter.x/fabs(xmax), dcenter.x/fabs(xmin));
Size dsize(destImageWidth, cvCeil(std::max(scale*fabs(ymin)*2, scale*fabs(ymax)*2)));
dcenter.y = (dsize.height - 1)*0.5f;
-
+
Mat mapxy(dsize, CV_32FC2);
double k1 = k[0], k2 = k[1], k3 = k[2], p1 = k[3], p2 = k[4], k4 = k[5], k5 = k[6], k6 = k[7];
double fx = cameraMatrix.at<double>(0,0), fy = cameraMatrix.at<double>(1,1), cx = scenter.x, cy = scenter.y;
-
+
for( int y = 0; y < dsize.height; y++ )
{
Point2f* mxy = mapxy.ptr<Point2f>(y);
double kr = 1 + ((k3*r2 + k2)*r2 + k1)*r2/(1 + ((k6*r2 + k5)*r2 + k4)*r2);
double u = fx*(q.x*kr + p1*_2xy + p2*(r2 + 2*x2)) + cx;
double v = fy*(q.y*kr + p1*(r2 + 2*y2) + p2*_2xy) + cy;
-
+
mxy[x] = Point2f((float)u, (float)v);
}
}
-
+
if(m1type == CV_32FC2)
{
_map1.create(mapxy.size(), mapxy.type());
}
else
convertMaps(mapxy, Mat(), _map1, _map2, m1type, false);
-
+
return scale;
}
// the whole testing is done here, run_func() is not utilized in this test
int CV_FindContourTest::validate_test_results( int /*test_case_idx*/ )
{
- int i, code = cvtest::TS::OK;
+ int code = cvtest::TS::OK;
cvCmpS( img[0], 0, img[0], CV_CMP_GT );
Mat _img[4];
for( int i = 0; i < 4; i++ )
_img[i] = cvarrToMat(img[i]);
-
+
code = cvtest::cmpEps2(ts, _img[0], _img[3], 0, true, "Comparing original image with the map of filled contours" );
if( code < 0 )
CvTreeNodeIterator iterator2;
int count3;
- for( i = 0; i < 2; i++ )
+ for(int i = 0; i < 2; i++ )
{
CvTreeNodeIterator iterator;
cvInitTreeNodeIterator( &iterator, i == 0 ? contours : contours2, INT_MAX );
goto _exit_;
}
- for( i = 0; i < seq1->total; i++ )
+ for(int i = 0; i < seq1->total; i++ )
{
CvPoint pt1;
CvPoint pt2;
void* result;
double low_high_range;
CvScalar low, high;
-
+
bool test_cpp;
};
}
-void CV_BaseShapeDescrTest::generate_point_set( void* points )
+void CV_BaseShapeDescrTest::generate_point_set( void* pointsSet )
{
RNG& rng = ts->get_rng();
int i, k, n, total, point_type;
}
memset( &reader, 0, sizeof(reader) );
- if( CV_IS_SEQ(points) )
+ if( CV_IS_SEQ(pointsSet) )
{
- CvSeq* ptseq = (CvSeq*)points;
+ CvSeq* ptseq = (CvSeq*)pointsSet;
total = ptseq->total;
point_type = CV_SEQ_ELTYPE(ptseq);
cvStartReadSeq( ptseq, &reader );
}
else
{
- CvMat* ptm = (CvMat*)points;
+ CvMat* ptm = (CvMat*)pointsSet;
assert( CV_IS_MAT(ptm) && CV_IS_MAT_CONT(ptm->type) );
total = ptm->rows + ptm->cols - 1;
point_type = CV_MAT_TYPE(ptm->type);
}
generate_point_set( points );
-
+
test_cpp = (cvtest::randInt(rng) & 16) == 0;
return 1;
}
for( i = 0; i < point_count; i++ )
{
int idx = 0, on_edge = 0;
- double result = cvTsPointPolygonTest( p[i], h, hull_count, &idx, &on_edge );
+ double pptresult = cvTsPointPolygonTest( p[i], h, hull_count, &idx, &on_edge );
- if( result < 0 )
+ if( pptresult < 0 )
{
ts->printf( cvtest::TS::LOG, "The point #%d is outside of the convex hull\n", i );
code = cvtest::TS::FAIL_BAD_ACCURACY;
goto _exit_;
}
- if( result < FLT_EPSILON && !on_edge )
+ if( pptresult < FLT_EPSILON && !on_edge )
mask->data.ptr[idx] = (uchar)1;
}
for( i = 0; i < point_count; i++ )
{
int idx = 0, on_edge = 0;
- double result = cvTsPointPolygonTest( p[i], box_pt, 4, &idx, &on_edge );
- if( result < -eps )
+ double pptresult = cvTsPointPolygonTest( p[i], box_pt, 4, &idx, &on_edge );
+ if( pptresult < -eps )
{
ts->printf( cvtest::TS::LOG, "The point #%d is outside of the box\n", i );
code = cvtest::TS::FAIL_BAD_ACCURACY;
goto _exit_;
}
- if( result < eps )
+ if( pptresult < eps )
{
for( j = 0; j < 4; j++ )
{
}
-void CV_FitEllipseTest::generate_point_set( void* points )
+void CV_FitEllipseTest::generate_point_set( void* pointsSet )
{
RNG& rng = ts->get_rng();
int i, total, point_type;
}
memset( &reader, 0, sizeof(reader) );
- if( CV_IS_SEQ(points) )
+ if( CV_IS_SEQ(pointsSet) )
{
- CvSeq* ptseq = (CvSeq*)points;
+ CvSeq* ptseq = (CvSeq*)pointsSet;
total = ptseq->total;
point_type = CV_SEQ_ELTYPE(ptseq);
cvStartReadSeq( ptseq, &reader );
}
else
{
- CvMat* ptm = (CvMat*)points;
+ CvMat* ptm = (CvMat*)pointsSet;
assert( CV_IS_MAT(ptm) && CV_IS_MAT_CONT(ptm->type) );
total = ptm->rows + ptm->cols - 1;
point_type = CV_MAT_TYPE(ptm->type);
{
public:
CV_FitEllipseSmallTest() {}
- ~CV_FitEllipseSmallTest() {}
+ ~CV_FitEllipseSmallTest() {}
protected:
void run(int)
{
c[0].push_back(Point(8, 6)*scale+ofs);
c[0].push_back(Point(8, 2)*scale+ofs);
c[0].push_back(Point(6, 0)*scale+ofs);
-
+
RotatedRect e = fitEllipse(c[0]);
CV_Assert( fabs(e.center.x - 4) <= 1. &&
fabs(e.center.y - 4) <= 1. &&
}
-void CV_FitLineTest::generate_point_set( void* points )
+void CV_FitLineTest::generate_point_set( void* pointsSet )
{
RNG& rng = ts->get_rng();
int i, k, n, total, point_type;
memset( &reader, 0, sizeof(reader) );
- if( CV_IS_SEQ(points) )
+ if( CV_IS_SEQ(pointsSet) )
{
- CvSeq* ptseq = (CvSeq*)points;
+ CvSeq* ptseq = (CvSeq*)pointsSet;
total = ptseq->total;
point_type = CV_MAT_DEPTH(CV_SEQ_ELTYPE(ptseq));
cvStartReadSeq( ptseq, &reader );
}
else
{
- CvMat* ptm = (CvMat*)points;
+ CvMat* ptm = (CvMat*)pointsSet;
assert( CV_IS_MAT(ptm) && CV_IS_MAT_CONT(ptm->type) );
total = ptm->rows + ptm->cols - 1;
point_type = CV_MAT_DEPTH(CV_MAT_TYPE(ptm->type));
}
-void CV_ContourMomentsTest::generate_point_set( void* points )
+void CV_ContourMomentsTest::generate_point_set( void* pointsSet )
{
RNG& rng = ts->get_rng();
float max_sz;
max_r_scale = cvtest::randReal(rng)*max_max_r_scale*0.01;
angle = cvtest::randReal(rng)*360;
- cvTsGenerateTousledBlob( center, axes, max_r_scale, angle, points, rng );
+ cvTsGenerateTousledBlob( center, axes, max_r_scale, angle, pointsSet, rng );
if( points1 )
points1->flags = CV_SEQ_MAGIC_VAL + CV_SEQ_POLYGON;
{
public:
CV_PerimeterAreaSliceTest();
- ~CV_PerimeterAreaSliceTest();
-protected:
+ ~CV_PerimeterAreaSliceTest();
+protected:
void run(int);
};
Ptr<CvMemStorage> storage = cvCreateMemStorage();
RNG& rng = theRNG();
const double min_r = 90, max_r = 120;
-
+
for( int i = 0; i < 100; i++ )
{
ts->update_context( this, i, true );
CvPoint center;
center.x = rng.uniform(cvCeil(max_r), cvFloor(640-max_r));
center.y = rng.uniform(cvCeil(max_r), cvFloor(480-max_r));
-
+
for( int j = 0; j < n; j++ )
{
CvPoint pt;
pt.y = cvRound(center.y - r*sin(phi));
cvSeqPush(contour, &pt);
}
-
+
CvSlice slice;
for(;;)
{
/*printf( "%d. (%d, %d) of %d, length = %d, length1 = %d\n",
i, slice.start_index, slice.end_index,
contour->total, cvSliceLength(slice, contour), cslice->total );
-
+
double area0 = cvContourArea(cslice);
- double area1 = cvContourArea(contour, slice);
+ double area1 = cvContourArea(contour, slice);
if( area0 != area1 )
{
ts->printf(cvtest::TS::LOG,
"The contour area slice is computed differently (%g vs %g)\n", area0, area1 );
- ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}*/
{
ts->printf(cvtest::TS::LOG,
"The contour arc length is computed differently (%g vs %g)\n", len0, len1 );
- ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+ ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
}
Mat _ielement(element->nRows, element->nCols, CV_32S, element->values);
Mat _element;
_ielement.convertTo(_element, CV_8U);
- Point anchor(element->anchorX, element->anchorY);
- int border = BORDER_REPLICATE;
+ Point _anchor(element->anchorX, element->anchorY);
+ int _border = BORDER_REPLICATE;
if( optype == CV_MOP_ERODE )
{
- cvtest::erode( src, dst, _element, anchor, border );
+ cvtest::erode( src, dst, _element, _anchor, _border );
}
else if( optype == CV_MOP_DILATE )
{
- cvtest::dilate( src, dst, _element, anchor, border );
+ cvtest::dilate( src, dst, _element, _anchor, _border );
}
else
{
Mat temp;
if( optype == CV_MOP_OPEN )
{
- cvtest::erode( src, temp, _element, anchor, border );
- cvtest::dilate( temp, dst, _element, anchor, border );
+ cvtest::erode( src, temp, _element, _anchor, _border );
+ cvtest::dilate( temp, dst, _element, _anchor, _border );
}
else if( optype == CV_MOP_CLOSE )
{
- cvtest::dilate( src, temp, _element, anchor, border );
- cvtest::erode( temp, dst, _element, anchor, border );
+ cvtest::dilate( src, temp, _element, _anchor, _border );
+ cvtest::erode( temp, dst, _element, _anchor, _border );
}
else if( optype == CV_MOP_GRADIENT )
{
- cvtest::erode( src, temp, _element, anchor, border );
- cvtest::dilate( src, dst, _element, anchor, border );
+ cvtest::erode( src, temp, _element, _anchor, _border );
+ cvtest::dilate( src, dst, _element, _anchor, _border );
cvtest::add( dst, 1, temp, -1, Scalar::all(0), dst, dst.type() );
}
else if( optype == CV_MOP_TOPHAT )
{
- cvtest::erode( src, temp, _element, anchor, border );
- cvtest::dilate( temp, dst, _element, anchor, border );
+ cvtest::erode( src, temp, _element, _anchor, _border );
+ cvtest::dilate( temp, dst, _element, _anchor, _border );
cvtest::add( src, 1, dst, -1, Scalar::all(0), dst, dst.type() );
}
else if( optype == CV_MOP_BLACKHAT )
{
- cvtest::dilate( src, temp, _element, anchor, border );
- cvtest::erode( temp, dst, _element, anchor, border );
+ cvtest::dilate( src, temp, _element, _anchor, _border );
+ cvtest::erode( temp, dst, _element, _anchor, _border );
cvtest::add( dst, 1, src, -1, Scalar::all(0), dst, dst.type() );
}
else
void prepare_to_validation( int );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
-
+
/*int write_default_params(CvFileStorage* fs);
void get_timing_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types
CvSize** whole_sizes, bool *are_images );
RNG& rng = ts->get_rng();
int depth, cn;
int i;
- double buf[8];
+ double buff[8];
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
depth = cvtest::randInt(rng) % 3;
types[INPUT_OUTPUT][1] = types[REF_INPUT_OUTPUT][1] = CV_8UC1;
types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1;
sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(9,1);
-
+
if( !use_mask )
sizes[INPUT_OUTPUT][1] = sizes[REF_INPUT_OUTPUT][1] = cvSize(0,0);
else
CvSize sz = sizes[INPUT_OUTPUT][0];
sizes[INPUT_OUTPUT][1] = sizes[REF_INPUT_OUTPUT][1] = cvSize(sz.width+2,sz.height+2);
}
-
+
seed_pt.x = cvtest::randInt(rng) % sizes[INPUT_OUTPUT][0].width;
seed_pt.y = cvtest::randInt(rng) % sizes[INPUT_OUTPUT][0].height;
l_diff = u_diff = Scalar::all(0.);
else
{
- Mat m( 1, 8, CV_16S, buf );
+ Mat m( 1, 8, CV_16S, buff );
rng.fill( m, RNG::NORMAL, Scalar::all(0), Scalar::all(32) );
for( i = 0; i < 4; i++ )
{
new_val = Scalar::all(0.);
for( i = 0; i < cn; i++ )
new_val.val[i] = cvtest::randReal(rng)*255;
-
+
test_cpp = (cvtest::randInt(rng) & 256) == 0;
}
void CV_FloodFillTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
{
RNG& rng = ts->get_rng();
-
+
if( i != INPUT && i != INPUT_OUTPUT )
{
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
return;
}
-
+
if( j == 0 )
{
Mat tmp = arr;
int flags = connectivity + (mask_only ? CV_FLOODFILL_MASK_ONLY : 0) +
(range_type == 1 ? CV_FLOODFILL_FIXED_RANGE : 0) + (new_mask_val << 8);
double* odata = test_mat[OUTPUT][0].ptr<double>();
-
+
if(!test_cpp)
{
CvConnectedComp comp;
int cols = _img->cols, rows = _img->rows;
int u0 = 0, u1 = 0, u2 = 0;
double s0 = 0, s1 = 0, s2 = 0;
-
+
if( CV_MAT_DEPTH(_img->type) == CV_8U || CV_MAT_DEPTH(_img->type) == CV_32S )
{
tmp = cvCreateMat( rows, cols, CV_MAKETYPE(CV_32F,CV_MAT_CN(_img->type)) );
cvSeqPush( seq, &p );
}
}
- }
+ }
}
r.x = r.width = seed_pt.x;
int prepare_test_case( int test_case_idx );
int validate_test_results( int test_case_idx );
virtual void init_hist( int test_case_idx, int i );
-
+
virtual void get_hist_params( int test_case_idx );
virtual float** get_hist_ranges( int test_case_idx );
int uniform;
int gen_random_hist;
double gen_hist_max_val, gen_hist_sparse_nz_ratio;
-
+
int init_ranges;
int img_type;
int img_max_log_size;
max_log_size = cvtest::clipInt( max_log_size, 1, 20 );
img_max_log_size = cvReadInt( find_param( fs, "max_log_array_size" ), img_max_log_size );
img_max_log_size = cvtest::clipInt( img_max_log_size, 1, 9 );
-
+
max_cdims = cvReadInt( find_param( fs, "max_cdims" ), max_cdims );
max_cdims = cvtest::clipInt( max_cdims, 1, 6 );
max_dim_size = cvRound(pow(hist_size,1./cdims));
total_size = 1;
uniform = cvtest::randInt(rng) % 2;
- hist_type = cvtest::randInt(rng) % 2 ? CV_HIST_SPARSE : CV_HIST_ARRAY;
-
+ hist_type = cvtest::randInt(rng) % 2 ? CV_HIST_SPARSE : CV_HIST_ARRAY;
+
for( i = 0; i < cdims; i++ )
{
dims[i] = cvtest::randInt(rng) % (max_dim_size + 2) + 2;
if( !uniform )
- dims[i] = MIN(dims[i], max_ni_dim_size);
+ dims[i] = MIN(dims[i], max_ni_dim_size);
total_size *= dims[i];
}
float** CV_BaseHistTest::get_hist_ranges( int /*test_case_idx*/ )
{
double _low = low + range_delta, _high = high - range_delta;
-
+
if( !init_ranges )
return 0;
-
+
ranges.resize(cdims);
-
+
if( uniform )
{
_ranges.resize(cdims*2);
for( i = 0; i < cdims; i++ )
dims_sum += dims[i] + 1;
_ranges.resize(dims_sum);
-
+
for( i = 0; i < cdims; i++ )
{
int j, n = dims[i];
if( (pow(q,(double)n)-1)/(q-1.) >= _high-_low )
break;
}
-
+
if( j == 0 )
{
delta = (_high-_low)/n;
q = 1 + j*0.1;
delta = cvFloor((_high-_low)*(q-1)/(pow(q,(double)n) - 1));
delta = MAX(delta, 1.);
- }
+ }
val = _low;
-
+
for( j = 0; j <= n; j++ )
{
_ranges[j+ofs] = (float)MIN(val,_high);
ofs += n + 1;
}
}
-
+
return &ranges[0];
}
if( gen_random_hist )
{
RNG& rng = ts->get_rng();
-
+
if( hist_type == CV_HIST_ARRAY )
{
Mat h = cvarrToMat(hist[hist_i]->bins);
else
{
CvArr* arr = hist[hist_i]->bins;
- int i, j, total_size = 1, nz_count;
+ int i, j, totalSize = 1, nz_count;
int idx[CV_MAX_DIM];
for( i = 0; i < cdims; i++ )
- total_size *= dims[i];
+ totalSize *= dims[i];
- nz_count = cvtest::randInt(rng) % MAX( total_size/4, 100 );
- nz_count = MIN( nz_count, total_size );
+ nz_count = cvtest::randInt(rng) % MAX( totalSize/4, 100 );
+ nz_count = MIN( nz_count, totalSize );
// a zero number of non-zero elements should be allowed
for( i = 0; i < nz_count; i++ )
get_hist_params( test_case_idx );
r = get_hist_ranges( test_case_idx );
hist.resize(hist_count);
-
+
for( i = 0; i < hist_count; i++ )
{
hist[i] = cvCreateHist( cdims, dims, hist_type, r, uniform );
int prepare_test_case( int test_case_idx );
int validate_test_results( int test_case_idx );
void init_hist( int test_case_idx, int i );
-
+
CvMat* indices;
CvMat* values;
CvMat* values0;
iters = (cvtest::randInt(rng) % MAX(total_size/10,100)) + 1;
iters = MIN( iters, total_size*9/10 + 1 );
-
+
indices = cvCreateMat( 1, iters*cdims, CV_32S );
values = cvCreateMat( 1, iters, CV_32F );
values0 = cvCreateMat( 1, iters, CV_32F );
if( GET_BIT(lin_idx) )
values0->data.fl[i] = (float)(lin_idx+1);
}
-
+
cvReleaseMat( &bit_mask );
}
{
int code = cvtest::TS::OK;
int i, j, iters = values->cols;
-
+
for( i = 0; i < iters; i++ )
{
float v = values->data.fl[i], v0 = values0->data.fl[i];
}
if( !eq || total_size == 1 )
break;
- }
+ }
min_val0 = (float)(-cvtest::randReal(rng)*10 - FLT_EPSILON);
max_val0 = (float)(cvtest::randReal(rng)*10 + FLT_EPSILON + gen_hist_max_val);
int CV_MinMaxHistTest::validate_test_results( int /*test_case_idx*/ )
{
int code = cvtest::TS::OK;
-
+
if( cvIsNaN(min_val) || cvIsInf(min_val) ||
cvIsNaN(max_val) || cvIsInf(max_val) )
{
if( hist_type != CV_HIST_ARRAY && test_cpp )
{
cv::SparseMat h((CvSparseMat*)hist[0]->bins);
- cv::normalize(h, h, factor, CV_L1);
+ cv::normalize(h, h, factor, CV_L1);
cvReleaseSparseMat((CvSparseMat**)&hist[0]->bins);
hist[0]->bins = (CvSparseMat*)h;
}
{
int code = cvtest::TS::OK;
double sum = 0;
-
+
if( hist_type == CV_HIST_ARRAY )
{
int i;
CvSparseMat* sparse = (CvSparseMat*)hist[0]->bins;
CvSparseMatIterator iterator;
CvSparseNode *node;
-
+
for( node = cvInitSparseMatIterator( sparse, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
if( hist_type == CV_HIST_ARRAY )
{
orig_nz_count = total_size;
-
+
values = cvCreateMat( 1, total_size, CV_32F );
memcpy( values->data.fl, cvPtr1D( hist[0]->bins, 0 ), total_size*sizeof(float) );
}
node != 0; node = cvGetNextSparseNode( &iterator ), i++ )
{
const int* idx = CV_NODE_IDX(sparse,node);
-
+
OPENCV_ASSERT( i < orig_nz_count, "CV_ThreshHistTest::prepare_test_case", "Buffer overflow" );
values->data.fl[i] = *(float*)CV_NODE_VAL(sparse,node);
}
}
}
-
+
if( code > 0 && hist_type == CV_HIST_SPARSE )
{
if( sparse->heap->active_count > 0 )
{
float* ptr0 = (float*)cvPtr1D( hist[0]->bins, 0 );
float* ptr1 = (float*)cvPtr1D( hist[1]->bins, 0 );
-
+
for( i = 0; i < total_size; i++ )
{
double v0 = ptr0[i], v1 = ptr1[i];
const int* idx = CV_NODE_IDX(sparse0, node);
double v0 = *(float*)CV_NODE_VAL(sparse0, node);
double v1 = (float)cvGetRealND(sparse1, idx);
-
+
result0[CV_COMP_CORREL] += v0*v1;
result0[CV_COMP_INTERSECT] += MIN(v0,v1);
if( fabs(v0) > DBL_EPSILON )
void CV_CalcHistTest::clear()
{
int i;
-
+
for( i = 0; i <= CV_MAX_DIM; i++ )
cvReleaseImage( &images[i] );
img_type == CV_8U ? IPL_DEPTH_8U : IPL_DEPTH_32F, nch );
channels[i] = cvtest::randInt(rng) % nch;
Mat images_i = cvarrToMat(images[i]);
-
+
cvtest::randUni( rng, images_i, Scalar::all(low), Scalar::all(high) );
}
else if( i == CV_MAX_DIM && cvtest::randInt(rng) % 2 )
// create mask
images[i] = cvCreateImage( img_size, IPL_DEPTH_8U, 1 );
Mat images_i = cvarrToMat(images[i]);
-
+
// make ~25% pixels in the mask non-zero
cvtest::randUni( rng, images_i, Scalar::all(-2), Scalar::all(2) );
}
{
float val[CV_MAX_DIM];
int idx[CV_MAX_DIM];
-
+
if( mptr && !mptr[x] )
continue;
if( img_depth == IPL_DEPTH_8U )
{
ts->printf( cvtest::TS::LOG, "The histogram does not match to the reference one\n" );
code = cvtest::TS::FAIL_BAD_ACCURACY;
-
+
}
if( code < 0 )
void CV_CalcBackProjectTest::clear()
{
int i;
-
+
for( i = 0; i < CV_MAX_DIM+3; i++ )
cvReleaseImage( &images[i] );
{
int idx = cvtest::randInt(rng) % img_len;
double val = cvtest::randReal(rng)*(high - low) + low;
-
+
if( img_type == CV_8U )
((uchar*)data)[idx] = (uchar)cvRound(val);
else
float val[CV_MAX_DIM];
float bin_val = 0;
int idx[CV_MAX_DIM];
-
+
if( img_depth == IPL_DEPTH_8U )
for( k = 0; k < cdims; k++ )
val[k] = plane[k].ptr[x*nch[k]];
void CV_CalcBackProjectPatchTest::clear()
{
int i;
-
+
for( i = 0; i < CV_MAX_DIM+2; i++ )
cvReleaseImage( &images[i] );
{
int idx = cvtest::randInt(rng) % img_len;
double val = cvtest::randReal(rng)*(high - low) + low;
-
+
if( img_type == CV_8U )
((uchar*)data)[idx] = (uchar)cvRound(val);
else
double factor, int* channels )
{
CvHistogram* model = 0;
-
+
IplImage imgstub[CV_MAX_DIM], *img[CV_MAX_DIM];
IplROI roi;
int i, dims;
for( x = 0; x < size.width; x++ )
{
double result;
-
+
roi.xOffset = x;
roi.yOffset = y;
roi.width = patch_size.width;
cvTsCalcBackProjectPatch( images, images[CV_MAX_DIM+1],
patch_size, hist[0], method, factor, channels );
-
+
Mat a = cvarrToMat(images[CV_MAX_DIM]), b = cvarrToMat(images[CV_MAX_DIM+1]);
code = cvtest::cmpEps2( ts, a, b, err_level, true, "BackProjectPatch result" );
int CV_BayesianProbTest::prepare_test_case( int test_case_idx )
{
RNG& rng = ts->get_rng();
-
+
hist_count = (cvtest::randInt(rng) % (MAX_HIST/2-1) + 2)*2;
hist_count = MIN( hist_count, MAX_HIST );
int code = CV_BaseHistTest::prepare_test_case( test_case_idx );
TEST(Imgproc_Hist_CalcBackProject, accuracy) { CV_CalcBackProjectTest test; test.safe_run(); }
TEST(Imgproc_Hist_CalcBackProjectPatch, accuracy) { CV_CalcBackProjectPatchTest test; test.safe_run(); }
TEST(Imgproc_Hist_BayesianProb, accuracy) { CV_BayesianProbTest test; test.safe_run(); }
-
+
/* End Of File */
if( test_mat[INPUT_OUTPUT][0].cols >= img.cols &&
test_mat[INPUT_OUTPUT][0].rows >= img.rows )
space_scale = spatial_scale_zoom;
-
+
for( i = 0; i < img.rows; i++ )
{
uchar* ptr = img.ptr(i);
}*/
cv::Mat src(1, cols*cn, CV_32F, &buffer[0]);
cv::Mat dst(1, cols*cn, depth, ptr);
- src.convertTo(dst, dst.type());
+ src.convertTo(dst, dst.type());
}
return code;
CvMat* x_idx = cvCreateMat( 1, dst->cols, CV_32SC1 );
CvMat* y_idx = cvCreateMat( 1, dst->rows, CV_32SC1 );
int* x_tab = x_idx->data.i;
- int elem_size = CV_ELEM_SIZE(src->type);
+ int elem_size = CV_ELEM_SIZE(src->type);
int drows = dst->rows, dcols = dst->cols;
if( interpolation == CV_INTER_NN )
{
double scale_x = (double)src->cols/dcols;
double scale_y = (double)src->rows/drows;
-
+
for( j = 0; j < dcols; j++ )
{
double f = ((j+0.5)*scale_x - 0.5);
{
uchar* dptr = dst->data.ptr + dst->step*i;
const uchar* sptr0 = src->data.ptr + src->step*y_idx->data.i[i];
-
+
for( j = 0; j < dcols; j++, dptr += elem_size )
{
const uchar* sptr = sptr0 + x_tab[j];
xs -= ixs;
ys -= iys;
-
+
switch( depth )
{
case CV_8U:
RNG& rng = ts->get_rng();
int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
const Mat& src = test_mat[INPUT][0];
- const Mat& dst = test_mat[INPUT_OUTPUT][0];
+ const Mat& dst = test_mat[INPUT_OUTPUT][0];
Mat& mat = test_mat[INPUT][1];
CvPoint2D32f center;
double scale, angle;
if( code <= 0 )
return code;
- double buf[6];
- Mat tmp( 2, 3, mat.type(), buf );
+ double buffer[6];
+ Mat tmp( 2, 3, mat.type(), buffer );
center.x = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.cols);
center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows);
RNG& rng = ts->get_rng();
int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
const CvMat& src = test_mat[INPUT][0];
- const CvMat& dst = test_mat[INPUT_OUTPUT][0];
+ const CvMat& dst = test_mat[INPUT_OUTPUT][0];
Mat& mat = test_mat[INPUT][1];
Point2f s[4], d[4];
int i;
s[3] = Point2f(0,src.rows-1.f);
d[3] = Point2f(0,dst.rows-1.f);
- float buf[16];
- Mat tmp( 1, 16, CV_32FC1, buf );
+ float bufer[16];
+ Mat tmp( 1, 16, CV_32FC1, bufer );
rng.fill( tmp, CV_RAND_NORMAL, Scalar::all(0.), Scalar::all(0.1) );
for( i = 0; i < 4; i++ )
{
- s[i].x += buf[i*4]*src.cols/2;
- s[i].y += buf[i*4+1]*src.rows/2;
- d[i].x += buf[i*4+2]*dst.cols/2;
- d[i].y += buf[i*4+3]*dst.rows/2;
+ s[i].x += bufer[i*4]*src.cols/2;
+ s[i].y += bufer[i*4+1]*src.rows/2;
+ d[i].x += bufer[i*4+2]*dst.cols/2;
+ d[i].y += bufer[i*4+3]*dst.rows/2;
}
cv::getPerspectiveTransform( s, d ).convertTo( mat, mat.depth() );
double xs = x*m[0] + y*m[1] + m[2];
double ys = x*m[3] + y*m[4] + m[5];
double ds = x*m[6] + y*m[7] + m[8];
-
+
ds = ds ? 1./ds : 0;
xs *= ds;
ys *= ds;
-
+
mapx.at<float>(y, x) = (float)xs;
mapy.at<float>(y, x) = (float)ys;
}
void fill_array( int test_case_idx, int i, int j, Mat& arr );
private:
- bool useCPlus;
- cv::Mat input0;
- cv::Mat input1;
- cv::Mat input2;
- cv::Mat input_new_cam;
- cv::Mat input_output;
-
- bool zero_new_cam;
- bool zero_distortion;
+ bool useCPlus;
+ cv::Mat input0;
+ cv::Mat input1;
+ cv::Mat input2;
+ cv::Mat input_new_cam;
+ cv::Mat input_output;
+
+ bool zero_new_cam;
+ bool zero_distortion;
};
//spatial_scale_zoom = spatial_scale_decimate;
test_array[INPUT].push_back(NULL);
test_array[INPUT].push_back(NULL);
- test_array[INPUT].push_back(NULL);
+ test_array[INPUT].push_back(NULL);
spatial_scale_decimate = spatial_scale_zoom;
}
RNG& rng = ts->get_rng();
CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
int type = types[INPUT][0];
- type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) );
+ type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) );
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = type;
types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
sizes[INPUT][1] = cvSize(3,3);
sizes[INPUT][2] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
- types[INPUT][3] = types[INPUT][1];
- sizes[INPUT][3] = sizes[INPUT][1];
+ types[INPUT][3] = types[INPUT][1];
+ sizes[INPUT][3] = sizes[INPUT][1];
interpolation = CV_INTER_LINEAR;
}
void CV_UndistortTest::run_func()
{
- if (!useCPlus)
- {
+ if (!useCPlus)
+ {
CvMat a = test_mat[INPUT][1], k = test_mat[INPUT][2];
- cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k);
- }
- else
- {
- if (zero_distortion)
- {
- cv::undistort(input0,input_output,input1,cv::Mat());
- }
- else
- {
- cv::undistort(input0,input_output,input1,input2);
- }
- }
+ cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k);
+ }
+ else
+ {
+ if (zero_distortion)
+ {
+ cv::undistort(input0,input_output,input1,cv::Mat());
+ }
+ else
+ {
+ cv::undistort(input0,input_output,input1,input2);
+ }
+ }
}
const Mat& src = test_mat[INPUT][0];
double k[4], a[9] = {0,0,0,0,0,0,0,0,1};
- double new_cam[9] = {0,0,0,0,0,0,0,0,1};
+ double new_cam[9] = {0,0,0,0,0,0,0,0,1};
double sz = MAX(src.rows, src.cols);
-
- Mat& _new_cam0 = test_mat[INPUT][3];
+
+ Mat& _new_cam0 = test_mat[INPUT][3];
Mat _new_cam(test_mat[INPUT][3].rows,test_mat[INPUT][3].cols,CV_64F,new_cam);
Mat& _a0 = test_mat[INPUT][1];
Mat _a(3,3,CV_64F,a);
_a.convertTo(_a0, _a0.depth());
- zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;
+ zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;
_k.convertTo(_k0, _k0.depth());
- zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;
+ zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;
_new_cam.convertTo(_new_cam0, _new_cam0.depth());
- //Testing C++ code
- useCPlus = ((cvtest::randInt(rng) % 2)!=0);
- if (useCPlus)
- {
- input0 = test_mat[INPUT][0];
- input1 = test_mat[INPUT][1];
- input2 = test_mat[INPUT][2];
- input_new_cam = test_mat[INPUT][3];
- }
+ //Testing C++ code
+ useCPlus = ((cvtest::randInt(rng) % 2)!=0);
+ if (useCPlus)
+ {
+ input0 = test_mat[INPUT][0];
+ input1 = test_mat[INPUT][1];
+ input2 = test_mat[INPUT][2];
+ input_new_cam = test_mat[INPUT][3];
+ }
return code;
}
void CV_UndistortTest::prepare_to_validation( int /*test_case_idx*/ )
{
- if (useCPlus)
- {
+ if (useCPlus)
+ {
Mat& output = test_mat[INPUT_OUTPUT][0];
input_output.convertTo(output, output.type());
- }
+ }
Mat& src = test_mat[INPUT][0];
Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
Mat& dst0 = test_mat[INPUT_OUTPUT][0];
void fill_array( int test_case_idx, int i, int j, Mat& arr );
private:
- bool dualChannel;
+ bool dualChannel;
};
CvSize sz = sizes[OUTPUT][0];
types[INPUT][0] = types[INPUT][1] = depth;
- dualChannel = cvtest::randInt(rng)%2 == 0;
- types[OUTPUT][0] = types[OUTPUT][1] =
+ dualChannel = cvtest::randInt(rng)%2 == 0;
+ types[OUTPUT][0] = types[OUTPUT][1] =
types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = dualChannel ? CV_32FC2 : CV_32F;
sizes[INPUT][0] = cvSize(3,3);
sizes[INPUT][1] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
void CV_UndistortMapTest::run_func()
{
CvMat a = test_mat[INPUT][0], k = test_mat[INPUT][1];
-
- if (!dualChannel )
- cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] );
- else
- cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 );
+
+ if (!dualChannel )
+ cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] );
+ else
+ cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 );
}
_a.convertTo(_a0, _a0.depth());
_k.convertTo(_k0, _k0.depth());
- if (dualChannel)
- {
+ if (dualChannel)
+ {
test_mat[REF_OUTPUT][1] = Scalar::all(0);
- test_mat[OUTPUT][1] = Scalar::all(0);
- }
+ test_mat[OUTPUT][1] = Scalar::all(0);
+ }
return code;
}
{
int sstep = (int)(src.step / sizeof(float));
int scols = src.cols, srows = src.rows;
-
+
CV_Assert( src.depth() == CV_32F && src.type() == dst.type() );
int cn = dst.channels();
int src_depth = cvtest::randInt(rng) % 2, dst_depth;
int cn = cvtest::randInt(rng) % 2 ? 3 : 1;
CvSize src_size, dst_size;
-
+
dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F;
if( src_depth < CV_32F && cvtest::randInt(rng) % 2 )
dst_depth = CV_32F;
-
+
types[INPUT][0] = CV_MAKETYPE(src_depth,cn);
types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn);
dst_size.width = MIN(dst_size.width,src_size.width);
dst_size.height = MIN(dst_size.width,src_size.height);
sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = dst_size;
-
+
center.x = (float)(cvtest::randReal(rng)*src_size.width);
center.y = (float)(cvtest::randReal(rng)*src_size.height);
interpolation = CV_INTER_LINEAR;
-
+
test_cpp = (cvtest::randInt(rng) & 256) == 0;
}
RNG& rng = ts->get_rng();
int msz, src_depth = cvtest::randInt(rng) % 2, dst_depth;
int cn = cvtest::randInt(rng) % 2 ? 3 : 1;
-
+
dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F;
if( src_depth < CV_32F && cvtest::randInt(rng) % 2 )
dst_depth = CV_32F;
-
+
types[INPUT][0] = CV_MAKETYPE(src_depth,cn);
types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn);
center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows);
angle = cvtest::randReal(rng)*360;
scale = cvtest::randReal(rng)*0.2 + 0.9;
-
+
// y = Ax + b -> x = A^-1(y - b) = A^-1*y - A^-1*b
scale = 1./scale;
angle = angle*(CV_PI/180.);
points_vector.push_back(p21);
points_vector.push_back(p22);
- points_vector.push_back(p23);
+ points_vector.push_back(p23);
std::vector<float> line;
}
else if( depth == CV_16S )
{
- float min_val = SHRT_MIN-100.f, max_val = SHRT_MAX+100.f;
+ float min_val = SHRT_MIN-100.f;
+ max_val = SHRT_MAX+100.f;
thresh_val = (float)(cvtest::randReal(rng)*(max_val - min_val) + min_val);
max_val = (float)(cvtest::randReal(rng)*(max_val - min_val) + min_val);
if( cvtest::randInt(rng)%4 == 0 )
{
public:
CvImage() : image(0), refcount(0) {}
- CvImage( CvSize size, int depth, int channels )
+ CvImage( CvSize _size, int _depth, int _channels )
{
- image = cvCreateImage( size, depth, channels );
+ image = cvCreateImage( _size, _depth, _channels );
refcount = image ? new int(1) : 0;
}
CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
- void create( CvSize size, int depth, int channels )
+ void create( CvSize _size, int _depth, int _channels )
{
if( !image || !refcount ||
- image->width != size.width || image->height != size.height ||
- image->depth != depth || image->nChannels != channels )
- attach( cvCreateImage( size, depth, channels ));
+ image->width != _size.width || image->height != _size.height ||
+ image->depth != _depth || image->nChannels != _channels )
+ attach( cvCreateImage( _size, _depth, _channels ));
}
void release() { detach(); }
int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
- void set_roi(CvRect roi) { cvSetImageROI(image,roi); }
+ void set_roi(CvRect _roi) { cvSetImageROI(image,_roi); }
void reset_roi() { cvResetImageROI(image); }
- void set_coi(int coi) { cvSetImageCOI(image,coi); }
+ void set_coi(int _coi) { cvSetImageCOI(image,_coi); }
int depth() const { return image ? image->depth : 0; }
int channels() const { return image ? image->nChannels : 0; }
int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; }
{
public:
CvMatrix() : matrix(0) {}
- CvMatrix( int rows, int cols, int type )
- { matrix = cvCreateMat( rows, cols, type ); }
+ CvMatrix( int _rows, int _cols, int _type )
+ { matrix = cvCreateMat( _rows, _cols, _type ); }
- CvMatrix( int rows, int cols, int type, CvMat* hdr,
- void* data=0, int step=CV_AUTOSTEP )
- { matrix = cvInitMatHeader( hdr, rows, cols, type, data, step ); }
+ CvMatrix( int _rows, int _cols, int _type, CvMat* hdr,
+ void* _data=0, int _step=CV_AUTOSTEP )
+ { matrix = cvInitMatHeader( hdr, _rows, _cols, _type, _data, _step ); }
CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
- CvMatrix( int rows, int cols, int type, void* data, int step=CV_AUTOSTEP )
- { matrix = cvCreateMatHeader( rows, cols, type );
- cvSetData( matrix, data, step ); }
+ CvMatrix( int _rows, int _cols, int _type, void* _data, int _step=CV_AUTOSTEP )
+ { matrix = cvCreateMatHeader( _rows, _cols, _type );
+ cvSetData( matrix, _data, _step ); }
CvMatrix( CvMat* m )
{ matrix = m; }
addref();
}
- void create( int rows, int cols, int type )
+ void create( int _rows, int _cols, int _type )
{
if( !matrix || !matrix->refcount ||
- matrix->rows != rows || matrix->cols != cols ||
- CV_MAT_TYPE(matrix->type) != type )
- set( cvCreateMat( rows, cols, type ), false );
+ matrix->rows != _rows || matrix->cols != _cols ||
+ CV_MAT_TYPE(matrix->type) != _type )
+ set( cvCreateMat( _rows, _cols, _type ), false );
}
void addref() const
const uchar* data() const { return matrix ? matrix->data.ptr : 0; }
int step() const { return matrix ? matrix->step : 0; }
- void set_data( void* data, int step=CV_AUTOSTEP )
- { cvSetData( matrix, data, step ); }
+ void set_data( void* _data, int _step=CV_AUTOSTEP )
+ { cvSetData( matrix, _data, _step ); }
uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
const uchar* row(int i) const
: x(0), y(0), image(NULL)
{}
- BaseKeypoint(int x, int y, IplImage* image)
- : x(x), y(y), image(image)
+ BaseKeypoint(int _x, int _y, IplImage* _image)
+ : x(_x), y(_y), image(_image)
{}
};
virtual void Process(IplImage* pImg, IplImage* /*pFG*/)
{
- int i;
double MinTv = pImg->width/1440.0; /* minimal threshold for speed difference */
double MinTv2 = MinTv*MinTv;
- for(i=m_Tracks.GetBlobNum(); i>0; --i)
+ for(int i=m_Tracks.GetBlobNum(); i>0; --i)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
pF->state = 0;
if(m_Wnd)
{ /* Debug output: */
- int i;
if(m_pDebugImg==NULL)
m_pDebugImg = cvCloneImage(pImg);
else
cvCopy(pImg, m_pDebugImg);
- for(i=m_TrackDataBase.GetBlobNum(); i>0; --i)
+ for(int i=m_TrackDataBase.GetBlobNum(); i>0; --i)
{ /* Draw all elements in track data base: */
int j;
DefTrackForDist* pF = (DefTrackForDist*)m_TrackDataBase.GetBlob(i-1);
pF->close = 0;
} /* Draw all elements in track data base. */
- for(i=m_Tracks.GetBlobNum(); i>0; --i)
+ for(int i=m_Tracks.GetBlobNum(); i>0; --i)
{ /* Draw all elements for all trajectories: */
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
int j;
{ /* Find a neighbour on current frame
* for each blob from previous frame:
*/
- CvBlob* pB = m_BlobList.GetBlob(i-1);
- DefBlobTracker* pBT = (DefBlobTracker*)pB;
+ CvBlob* pBl = m_BlobList.GetBlob(i-1);
+ DefBlobTracker* pBT = (DefBlobTracker*)pBl;
//int BlobID = CV_BLOB_ID(pB);
//CvBlob* pBBest = NULL;
//double DistBest = -1;
assert(results->cols == k);
assert(dist->cols == k);
- for (int j = 0; j < d->rows; ++j) {
- const typename __treetype::scalar_type* dj =
- (const typename __treetype::scalar_type*) dptr;
+ for (int j = 0; j < d->rows; ++j)
+ {
+ const typename __treetype::scalar_type* dj = (const typename __treetype::scalar_type*) dptr;
int* resultsj = (int*) resultsptr;
double* distj = (double*) distptr;
tr->find_nn_bbf(dj, k, emax, nn);
assert((int)nn.size() <= k);
- for (unsigned int j = 0; j < nn.size(); ++j) {
- *resultsj++ = *nn[j].p;
- *distj++ = nn[j].dist;
+ for (unsigned int i = 0; i < nn.size(); ++i)
+ {
+ *resultsj++ = *nn[i].p;
+ *distj++ = nn[i].dist;
}
std::fill(resultsj, resultsj + k - nn.size(), -1);
std::fill(distj, distj + k - nn.size(), 0);
min_val = max_val = step = 0;
}
- CvParamGrid( double min_val, double max_val, double log_step )
- {
- this->min_val = min_val;
- this->max_val = max_val;
- step = log_step;
- }
+ CvParamGrid( double min_val, double max_val, double log_step );
//CvParamGrid( int param_id );
bool check() const;
CV_PROP_RW double step;
};
+inline CvParamGrid::CvParamGrid( double _min_val, double _max_val, double _log_step )
+{
+ min_val = _min_val;
+ max_val = _max_val;
+ step = _log_step;
+}
+
class CV_EXPORTS_W CvNormalBayesClassifier : public CvStatModel
{
public:
CvNormalBayesClassifier( const CvMat* trainData, const CvMat* responses,
const CvMat* varIdx=0, const CvMat* sampleIdx=0 );
-
+
virtual bool train( const CvMat* trainData, const CvMat* responses,
const CvMat* varIdx = 0, const CvMat* sampleIdx=0, bool update=false );
-
+
virtual float predict( const CvMat* samples, CV_OUT CvMat* results=0 ) const;
CV_WRAP virtual void clear();
bool update=false );
CV_WRAP virtual float predict( const cv::Mat& samples, CV_OUT cv::Mat* results=0 ) const;
#endif
-
+
virtual void write( CvFileStorage* storage, const char* name ) const;
virtual void read( CvFileStorage* storage, CvFileNode* node );
virtual bool train( const CvMat* trainData, const CvMat* responses,
const CvMat* sampleIdx=0, bool is_regression=false,
int maxK=32, bool updateBase=false );
-
+
virtual float find_nearest( const CvMat* samples, int k, CV_OUT CvMat* results=0,
const float** neighbors=0, CV_OUT CvMat* neighborResponses=0, CV_OUT CvMat* dist=0 ) const;
-
+
#ifndef SWIG
CV_WRAP CvKNearest( const cv::Mat& trainData, const cv::Mat& responses,
const cv::Mat& sampleIdx=cv::Mat(), bool isRegression=false, int max_k=32 );
-
+
CV_WRAP virtual bool train( const cv::Mat& trainData, const cv::Mat& responses,
const cv::Mat& sampleIdx=cv::Mat(), bool isRegression=false,
- int maxK=32, bool updateBase=false );
-
+ int maxK=32, bool updateBase=false );
+
virtual float find_nearest( const cv::Mat& samples, int k, cv::Mat* results=0,
const float** neighbors=0, cv::Mat* neighborResponses=0,
cv::Mat* dist=0 ) const;
CV_WRAP virtual float find_nearest( const cv::Mat& samples, int k, CV_OUT cv::Mat& results,
CV_OUT cv::Mat& neighborResponses, CV_OUT cv::Mat& dists) const;
#endif
-
+
virtual void clear();
int get_max_k() const;
int get_var_count() const;
int get_sample_count() const;
bool is_regression() const;
-
+
virtual float write_results( int k, int k1, int start, int end,
const float* neighbor_responses, const float* dist, CvMat* _results,
CvMat* _neighbor_responses, CvMat* _dist, Cv32suf* sort_buf ) const;
virtual bool train( const CvMat* trainData, const CvMat* responses,
const CvMat* varIdx=0, const CvMat* sampleIdx=0,
CvSVMParams params=CvSVMParams() );
-
+
virtual bool train_auto( const CvMat* trainData, const CvMat* responses,
const CvMat* varIdx, const CvMat* sampleIdx, CvSVMParams params,
int kfold = 10,
virtual float predict( const CvMat* sample, bool returnDFVal=false ) const;
virtual float predict( const CvMat* samples, CvMat* results ) const;
-
+
#ifndef SWIG
CV_WRAP CvSVM( const cv::Mat& trainData, const cv::Mat& responses,
const cv::Mat& varIdx=cv::Mat(), const cv::Mat& sampleIdx=cv::Mat(),
CvSVMParams params=CvSVMParams() );
-
+
CV_WRAP virtual bool train( const cv::Mat& trainData, const cv::Mat& responses,
const cv::Mat& varIdx=cv::Mat(), const cv::Mat& sampleIdx=cv::Mat(),
CvSVMParams params=CvSVMParams() );
-
+
CV_WRAP virtual bool train_auto( const cv::Mat& trainData, const cv::Mat& responses,
const cv::Mat& varIdx, const cv::Mat& sampleIdx, CvSVMParams params,
int k_fold = 10,
bool balanced=false);
CV_WRAP virtual float predict( const cv::Mat& sample, bool returnDFVal=false ) const;
#endif
-
+
CV_WRAP virtual int get_support_vector_count() const;
virtual const float* get_support_vector(int i) const;
virtual CvSVMParams get_params() const { return params; };
// Default parameters
enum {DEFAULT_NCLUSTERS=5, DEFAULT_MAX_ITERS=100};
-
+
// The initial step
enum {START_E_STEP=1, START_M_STEP=2, START_AUTO_STEP=0};
CV_WRAP EM(int nclusters=EM::DEFAULT_NCLUSTERS, int covMatType=EM::COV_MAT_DIAGONAL,
const TermCriteria& termCrit=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS,
EM::DEFAULT_MAX_ITERS, FLT_EPSILON));
-
+
virtual ~EM();
CV_WRAP virtual void clear();
OutputArray logLikelihoods=noArray(),
OutputArray labels=noArray(),
OutputArray probs=noArray());
-
+
CV_WRAP virtual bool trainE(InputArray samples,
InputArray means0,
InputArray covs0=noArray(),
OutputArray logLikelihoods=noArray(),
OutputArray labels=noArray(),
OutputArray probs=noArray());
-
+
CV_WRAP virtual bool trainM(InputArray samples,
InputArray probs0,
OutputArray logLikelihoods=noArray(),
OutputArray labels=noArray(),
OutputArray probs=noArray());
-
+
CV_WRAP Vec2d predict(InputArray sample,
OutputArray probs=noArray()) const;
virtual void read(const FileNode& fn);
protected:
-
+
virtual void setTrainData(int startStep, const Mat& samples,
const Mat* probs0,
const Mat* means0,
int buf_count, buf_size;
bool shared;
int is_buf_16u;
-
+
CvMat* cat_count;
CvMat* cat_ofs;
CvMat* cat_map;
const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(),
const cv::Mat& missingDataMask=cv::Mat(),
CvDTreeParams params=CvDTreeParams() );
-
+
CV_WRAP virtual CvDTreeNode* predict( const cv::Mat& sample, const cv::Mat& missingDataMask=cv::Mat(),
bool preprocessedInput=false ) const;
CV_WRAP virtual cv::Mat getVarImportance();
#endif
-
+
virtual const CvMat* get_var_importance();
CV_WRAP virtual void clear();
virtual void try_split_node( CvDTreeNode* n );
virtual void split_node_data( CvDTreeNode* n );
virtual CvDTreeSplit* find_best_split( CvDTreeNode* n );
- virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
virtual CvDTreeSplit* find_split_cat_class( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
- virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
- virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
virtual CvDTreeSplit* find_surrogate_split_ord( CvDTreeNode* n, int vi, uchar* ext_buf = 0 );
virtual CvDTreeSplit* find_surrogate_split_cat( CvDTreeNode* n, int vi, uchar* ext_buf = 0 );
const CvMat* sampleIdx=0, const CvMat* varType=0,
const CvMat* missingDataMask=0,
CvRTParams params=CvRTParams() );
-
+
virtual bool train( CvMLData* data, CvRTParams params=CvRTParams() );
virtual float predict( const CvMat* sample, const CvMat* missing = 0 ) const;
virtual float predict_prob( const CvMat* sample, const CvMat* missing = 0 ) const;
CV_WRAP virtual float predict_prob( const cv::Mat& sample, const cv::Mat& missing = cv::Mat() ) const;
CV_WRAP virtual cv::Mat getVarImportance();
#endif
-
+
CV_WRAP virtual void clear();
virtual const CvMat* get_var_importance();
virtual float get_proximity( const CvMat* sample1, const CvMat* sample2,
const CvMat* missing1 = 0, const CvMat* missing2 = 0 ) const;
-
+
virtual float calc_error( CvMLData* data, int type , std::vector<float>* resp = 0 ); // type in {CV_TRAIN_ERROR, CV_TEST_ERROR}
- virtual float get_train_error();
+ virtual float get_train_error();
virtual void read( CvFileStorage* fs, CvFileNode* node );
virtual void write( CvFileStorage* fs, const char* name ) const;
{
protected:
virtual double calc_node_dir( CvDTreeNode* node );
- virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
virtual CvDTreeSplit* find_split_cat_class( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
- virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
- virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
virtual void split_node_data( CvDTreeNode* n );
};
virtual void try_split_node( CvDTreeNode* n );
virtual CvDTreeSplit* find_surrogate_split_ord( CvDTreeNode* n, int vi, uchar* ext_buf = 0 );
virtual CvDTreeSplit* find_surrogate_split_cat( CvDTreeNode* n, int vi, uchar* ext_buf = 0 );
- virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_ord_class( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
virtual CvDTreeSplit* find_split_cat_class( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
- virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_ord_reg( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
- virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi,
+ virtual CvDTreeSplit* find_split_cat_reg( CvDTreeNode* n, int vi,
float init_quality = 0, CvDTreeSplit* _split = 0, uchar* ext_buf = 0 );
virtual void calc_node_value( CvDTreeNode* n );
virtual double calc_node_dir( CvDTreeNode* n );
const CvMat* sampleIdx=0, const CvMat* varType=0,
const CvMat* missingDataMask=0,
CvBoostParams params=CvBoostParams() );
-
+
virtual bool train( const CvMat* trainData, int tflag,
const CvMat* responses, const CvMat* varIdx=0,
const CvMat* sampleIdx=0, const CvMat* varType=0,
const CvMat* missingDataMask=0,
CvBoostParams params=CvBoostParams(),
bool update=false );
-
+
virtual bool train( CvMLData* data,
CvBoostParams params=CvBoostParams(),
bool update=false );
const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(),
const cv::Mat& missingDataMask=cv::Mat(),
CvBoostParams params=CvBoostParams() );
-
+
CV_WRAP virtual bool train( const cv::Mat& trainData, int tflag,
const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(),
const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(),
const cv::Mat& missingDataMask=cv::Mat(),
CvBoostParams params=CvBoostParams(),
bool update=false );
-
+
CV_WRAP virtual float predict( const cv::Mat& sample, const cv::Mat& missing=cv::Mat(),
const cv::Range& slice=cv::Range::all(), bool rawMode=false,
bool returnSum=false ) const;
#endif
-
+
virtual float calc_error( CvMLData* _data, int type , std::vector<float> *resp = 0 ); // type in {CV_TRAIN_ERROR, CV_TEST_ERROR}
CV_WRAP virtual void prune( CvSlice slice );
// DataType: CLASS CvGBTrees
// Gradient Boosting Trees (GBT) algorithm implementation.
-//
+//
// data - training dataset
// params - parameters of the CvGBTrees
// weak - array[0..(class_count-1)] of CvSeq
// missing - mask of the missing values in the training set. This
// matrix has the same size as train_data. 1 - missing
// value, 0 - not a missing value.
-// class_labels - output class labels map.
+// class_labels - output class labels map.
// rng - random number generator. Used for spliting the
// training set.
// class_count - count of output classes.
/*
// DataType: ENUM
// Loss functions implemented in CvGBTrees.
- //
+ //
// SQUARED_LOSS
// problem: regression
// loss = (x - x')^2
- //
+ //
// ABSOLUTE_LOSS
// problem: regression
// loss = abs(x - x')
- //
+ //
// HUBER_LOSS
// problem: regression
// loss = delta*( abs(x - x') - delta/2), if abs(x - x') > delta
//
// DEVIANCE_LOSS
// problem: classification
- //
- */
+ //
+ */
enum {SQUARED_LOSS=0, ABSOLUTE_LOSS, HUBER_LOSS=3, DEVIANCE_LOSS};
-
-
+
+
/*
// Default constructor. Creates a model only (without training).
// Should be followed by one form of the train(...) function.
//
// API
// CvGBTrees();
-
+
// INPUT
// OUTPUT
// RESULT
const CvMat* sampleIdx=0, const CvMat* varType=0,
const CvMat* missingDataMask=0,
CvGBTreesParams params=CvGBTreesParams() );
-
+
// INPUT
// trainData - a set of input feature vectors.
// size of matrix is
const CvMat* missingDataMask=0,
CvGBTreesParams params=CvGBTreesParams() );
-
+
/*
// Destructor.
*/
virtual ~CvGBTrees();
-
-
+
+
/*
// Gradient tree boosting model training
//
const CvMat* missingDataMask=0,
CvGBTreesParams params=CvGBTreesParams(),
bool update=false );
-
+
// INPUT
// trainData - a set of input feature vectors.
// size of matrix is
const CvMat* missingDataMask=0,
CvGBTreesParams params=CvGBTreesParams(),
bool update=false );
-
-
+
+
/*
// Gradient tree boosting model training
//
// virtual bool train( CvMLData* data,
CvGBTreesParams params=CvGBTreesParams(),
bool update=false ) {return false;};
-
+
// INPUT
// data - training set.
// params - parameters of GTB algorithm.
CvGBTreesParams params=CvGBTreesParams(),
bool update=false );
-
+
/*
// Response value prediction
//
// virtual float predict_serial( const CvMat* sample, const CvMat* missing=0,
CvMat* weak_responses=0, CvSlice slice = CV_WHOLE_SEQ,
int k=-1 ) const;
-
+
// INPUT
// sample - input sample of the same type as in the training set.
// missing - missing values mask. missing=0 if there are no
// slice = CV_WHOLE_SEQ when all trees are used.
// k - number of ensemble used.
// k is in {-1,0,1,..,<count of output classes-1>}.
- // in the case of classification problem
+ // in the case of classification problem
// <count of output classes-1> ensembles are built.
// If k = -1 ordinary prediction is the result,
// otherwise function gives the prediction of the
virtual float predict_serial( const CvMat* sample, const CvMat* missing=0,
CvMat* weakResponses=0, CvSlice slice = CV_WHOLE_SEQ,
int k=-1 ) const;
-
+
/*
// Response value prediction.
// Parallel version (in the case of TBB existence)
// virtual float predict( const CvMat* sample, const CvMat* missing=0,
CvMat* weak_responses=0, CvSlice slice = CV_WHOLE_SEQ,
int k=-1 ) const;
-
+
// INPUT
// sample - input sample of the same type as in the training set.
// missing - missing values mask. missing=0 if there are no
// slice = CV_WHOLE_SEQ when all trees are used.
// k - number of ensemble used.
// k is in {-1,0,1,..,<count of output classes-1>}.
- // in the case of classification problem
+ // in the case of classification problem
// <count of output classes-1> ensembles are built.
// If k = -1 ordinary prediction is the result,
// otherwise function gives the prediction of the
// OUTPUT
// RESULT
// Predicted value.
- */
+ */
virtual float predict( const CvMat* sample, const CvMat* missing=0,
CvMat* weakResponses=0, CvSlice slice = CV_WHOLE_SEQ,
int k=-1 ) const;
//
// API
// virtual void clear();
-
+
// INPUT
// OUTPUT
// delete data, weak, orig_response, sum_response,
std::vector<float> *resp = 0 );
/*
- //
+ //
// Write parameters of the gtb model and data. Write learned model.
//
// API
/*
- //
+ //
// Read parameters of the gtb model and data. Read learned model.
//
// API
*/
virtual void read( CvFileStorage* fs, CvFileNode* node );
-
+
// new-style C++ interface
CV_WRAP CvGBTrees( const cv::Mat& trainData, int tflag,
const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(),
const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(),
const cv::Mat& missingDataMask=cv::Mat(),
CvGBTreesParams params=CvGBTreesParams() );
-
+
CV_WRAP virtual bool train( const cv::Mat& trainData, int tflag,
const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(),
const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(),
CV_WRAP virtual float predict( const cv::Mat& sample, const cv::Mat& missing=cv::Mat(),
const cv::Range& slice = cv::Range::all(),
int k=-1 ) const;
-
+
protected:
/*
//
// API
// virtual void find_gradient( const int k = 0);
-
+
// INPUT
// k - used for classification problem, determining current
// tree ensemble.
*/
virtual void find_gradient( const int k = 0);
-
+
/*
- //
+ //
// Change values in tree leaves according to the used loss function.
//
// API
/*
- //
+ //
// Find optimal constant prediction value according to the used loss
// function.
// The goal is to find a constant which gives the minimal summary loss
*/
virtual float find_optimal_value( const CvMat* _Idx );
-
+
/*
- //
+ //
// Randomly split the whole training set in two parts according
// to params.portion.
//
/*
- //
+ //
// Internal recursive function giving an array of subtree tree leaves.
//
// API
// RESULT
*/
void leaves_get( CvDTreeNode** leaves, int& count, CvDTreeNode* node );
-
-
+
+
/*
- //
+ //
// Get leaves of the tree.
//
// API
*/
CvDTreeNode** GetLeaves( const CvDTree* dtree, int& len );
-
+
/*
- //
+ //
// Is it a regression or a classification.
//
// API
/*
- //
+ //
// Write parameters of the gtb model.
//
// API
/*
- //
+ //
// Read parameters of the gtb model and data.
//
// API
// RESULT
*/
virtual void read_params( CvFileStorage* fs, CvFileNode* fnode );
- int get_len(const CvMat* mat) const;
+ int get_len(const CvMat* mat) const;
+
-
CvDTreeTrainData* data;
CvGBTreesParams params;
virtual void create( const CvMat* layerSizes,
int activateFunc=CvANN_MLP::SIGMOID_SYM,
double fparam1=0, double fparam2=0 );
-
+
virtual int train( const CvMat* inputs, const CvMat* outputs,
const CvMat* sampleWeights, const CvMat* sampleIdx=0,
CvANN_MLP_TrainParams params = CvANN_MLP_TrainParams(),
int flags=0 );
virtual float predict( const CvMat* inputs, CV_OUT CvMat* outputs ) const;
-
+
#ifndef SWIG
CV_WRAP CvANN_MLP( const cv::Mat& layerSizes,
int activateFunc=CvANN_MLP::SIGMOID_SYM,
double fparam1=0, double fparam2=0 );
-
+
CV_WRAP virtual void create( const cv::Mat& layerSizes,
int activateFunc=CvANN_MLP::SIGMOID_SYM,
- double fparam1=0, double fparam2=0 );
-
+ double fparam1=0, double fparam2=0 );
+
CV_WRAP virtual int train( const cv::Mat& inputs, const cv::Mat& outputs,
const cv::Mat& sampleWeights, const cv::Mat& sampleIdx=cv::Mat(),
CvANN_MLP_TrainParams params = CvANN_MLP_TrainParams(),
- int flags=0 );
-
+ int flags=0 );
+
CV_WRAP virtual float predict( const cv::Mat& inputs, CV_OUT cv::Mat& outputs ) const;
#endif
-
+
CV_WRAP virtual void clear();
// possible activation functions
virtual ~CvMLData();
// returns:
- // 0 - OK
+ // 0 - OK
// -1 - file can not be opened or is not correct
int read_csv( const char* filename );
const CvMat* get_responses();
const CvMat* get_missing() const;
- void set_header_lines_number( int n );
- int get_header_lines_number() const;
+ void set_header_lines_number( int n );
+ int get_header_lines_number() const;
void set_response_idx( int idx ); // old response become predictors, new response_idx = idx
// if idx < 0 there will be no response
const CvMat* get_train_sample_idx() const;
const CvMat* get_test_sample_idx() const;
void mix_train_and_test_idx();
-
+
const CvMat* get_var_idx();
void chahge_var_idx( int vi, bool state ); // misspelled (saved for back compitability),
// use change_var_idx
void set_var_types( const char* str ); // str examples:
// "ord[0-17],cat[18]", "ord[0,2,4,10-12], cat[1,3,5-9,13,14]",
// "cat", "ord" (all vars are categorical/ordered)
- void change_var_type( int var_idx, int type); // type in { CV_VAR_ORDERED, CV_VAR_CATEGORICAL }
-
+ void change_var_type( int var_idx, int type); // type in { CV_VAR_ORDERED, CV_VAR_CATEGORICAL }
+
void set_delimiter( char ch );
char get_delimiter() const;
void set_miss_ch( char ch );
char get_miss_ch() const;
-
+
const std::map<std::string, int>& get_class_labels_map() const;
protected:
void str_to_flt_elem( const char* token, float& flt_elem, int& type);
void free_train_test_idx();
-
+
char delimiter;
char miss_ch;
//char flt_separator;
CvMat* var_idx_out; // mat
CvMat* var_types_out; // mat
- int header_lines_number;
+ int header_lines_number;
int response_idx;
int train_sample_count;
bool mix;
-
+
int total_class_count;
std::map<std::string, int> class_map;
namespace cv
{
-
+
typedef CvStatModel StatModel;
typedef CvParamGrid ParamGrid;
typedef CvNormalBayesClassifier NormalBayesClassifier;
template<> CV_EXPORTS void Ptr<CvDTreeSplit>::delete_obj();
CV_EXPORTS bool initModule_ml(void);
-
+
}
#endif // __cplusplus
n *= cols;
xf -= n; df -= n;
-
+
for( i = 0; i < n; i++ )
df[i] *= xf[i];
}
xf[j] = (xf[j] + bias[j])*scale;
df[j] = -fabs(xf[j]);
}
-
+
cvExp( _df, _df );
n *= cols;
}
struct rprop_loop {
- rprop_loop(const CvANN_MLP* _point, double**& _weights, int& _count, int& _ivcount, CvVectors* _x0,
+ rprop_loop(const CvANN_MLP* _point, double**& _weights, int& _count, int& _ivcount, CvVectors* _x0,
int& _l_count, CvMat*& _layer_sizes, int& _ovcount, int& _max_count,
- CvVectors* _u, const double*& _sw, double& _inv_count, CvMat*& _dEdw, int& _dcount0, double* _E, int _buf_sz)
+ CvVectors* _u, const double*& _sw, double& _inv_count, CvMat*& _dEdw, int& _dcount0, double* _E, int _buf_sz)
{
point = _point;
weights = _weights;
E = _E;
buf_sz = _buf_sz;
}
-
+
const CvANN_MLP* point;
double** weights;
int count;
double* E;
int buf_sz;
-
+
void operator()( const cv::BlockedRange& range ) const
{
double* buf_ptr;
double** x = 0;
- double **df = 0;
+ double **df = 0;
int total = 0;
-
+
for(int i = 0; i < l_count; i++ )
total += layer_sizes->data.i[i];
CvMat* buf;
for(int si = range.begin(); si < range.end(); si++ )
{
if (si % dcount0 != 0) continue;
- int n1, n2, j, k;
+ int n1, n2, k;
double* w;
CvMat _w, _dEdw, hdr1, hdr2, ghdr1, ghdr2, _df;
CvMat *x1, *x2, *grad1, *grad2, *temp;
// grab and preprocess input data
if( x0->type == CV_32F )
- {
+ {
for(int i = 0; i < dcount; i++ )
{
const float* x0data = x0->data.fl[si+i];
double* xdata = x[0]+i*ivcount;
- for( j = 0; j < ivcount; j++ )
+ for(int j = 0; j < ivcount; j++ )
xdata[j] = x0data[j]*w[j*2] + w[j*2+1];
}
- }
+ }
else
for(int i = 0; i < dcount; i++ )
{
const double* x0data = x0->data.db[si+i];
double* xdata = x[0]+i*ivcount;
- for( j = 0; j < ivcount; j++ )
+ for(int j = 0; j < ivcount; j++ )
xdata[j] = x0data[j]*w[j*2] + w[j*2+1];
- }
+ }
cvInitMatHeader( x1, dcount, ivcount, CV_64F, x[0] );
// forward pass, compute y[i]=w*x[i-1], x[i]=f(y[i]), df[i]=f'(y[i])
double* gdata = grad1->data.db + i*ovcount;
double sweight = sw ? sw[si+i] : inv_count, E1 = 0;
- for( j = 0; j < ovcount; j++ )
+ for(int j = 0; j < ovcount; j++ )
{
double t = udata[j]*w[j*2] + w[j*2+1] - xdata[j];
gdata[j] = t*sweight;
}
*E += sweight*E1;
}
-
+
// backward pass, update dEdw
#ifdef HAVE_TBB
static tbb::spin_mutex mutex;
{
double* dst = _dEdw.data.db + n1*n2;
const double* src = grad1->data.db + k*n2;
- for( j = 0; j < n2; j++ )
+ for(int j = 0; j < n2; j++ )
dst[j] += src[j];
}
-
+
if (i > 1)
cvInitMatHeader( &_w, n1, n2, CV_64F, weights[i] );
#ifdef HAVE_TBB
int CvANN_MLP::train_rprop( CvVectors x0, CvVectors u, const double* sw )
{
- const int max_buf_sz = 1 << 16;
+ const int max_buf_size = 1 << 16;
CvMat* dw = 0;
CvMat* dEdw = 0;
CvMat* prev_dEdw_sign = 0;
cvZero( prev_dEdw_sign );
inv_count = 1./count;
- dcount0 = max_buf_sz/(2*total);
+ dcount0 = max_buf_size/(2*total);
dcount0 = MAX( dcount0, 1 );
dcount0 = MIN( dcount0, count );
buf_sz = dcount0*(total + max_count)*2;
double E = 0;
// first, iterate through all the samples and compute dEdw
- cv::parallel_for(cv::BlockedRange(0, count),
- rprop_loop(this, weights, count, ivcount, &x0, l_count, layer_sizes,
+ cv::parallel_for(cv::BlockedRange(0, count),
+ rprop_loop(this, weights, count, ivcount, &x0, l_count, layer_sizes,
ovcount, max_count, &u, sw, inv_count, dEdw, dcount0, &E, buf_sz)
);
void CvANN_MLP::create( const Mat& _layer_sizes, int _activ_func,
double _f_param1, double _f_param2 )
{
- CvMat layer_sizes = _layer_sizes;
- create( &layer_sizes, _activ_func, _f_param1, _f_param2 );
+ CvMat cvlayer_sizes = _layer_sizes;
+ create( &cvlayer_sizes, _activ_func, _f_param1, _f_param2 );
}
int CvANN_MLP::train( const Mat& _inputs, const Mat& _outputs,
{
CvMat inputs = _inputs, outputs = _outputs, sweights = _sample_weights, sidx = _sample_idx;
return train(&inputs, &outputs, sweights.data.ptr ? &sweights : 0,
- sidx.data.ptr ? &sidx : 0, _params, flags);
+ sidx.data.ptr ? &sidx : 0, _params, flags);
}
float CvANN_MLP::predict( const Mat& _inputs, Mat& _outputs ) const
CV_Assert(layer_sizes != 0);
_outputs.create(_inputs.rows, layer_sizes->data.i[layer_sizes->cols-1], _inputs.type());
CvMat inputs = _inputs, outputs = _outputs;
-
- return predict(&inputs, &outputs);
+
+ return predict(&inputs, &outputs);
}
/* End of file. */
void
-CvBoostTree::scale( double scale )
+CvBoostTree::scale( double _scale )
{
CvDTreeNode* node = root;
CvDTreeNode* parent;
for(;;)
{
- node->value *= scale;
+ node->value *= _scale;
if( !node->left )
break;
node = node->left;
int i, best_i = -1;
double L = 0, R = weights[n];
double best_val = init_quality, lsum = 0, rsum = node->value*R;
-
+
// compensate for missing values
for( i = n1; i < n; i++ )
{
{
R += counts[i];
rsum += sum[i];
- sum[i] = fabs(counts[i]) > DBL_EPSILON ? sum[i]/counts[i] : 0;
+ sum[i] = fabs(counts[i]) > DBL_EPSILON ? sum[i]/counts[i] : 0;
sum_ptr[i] = sum + i;
}
__BEGIN__;
int i;
-
+
set_params( _params );
cvReleaseMat( &active_vars );
if ( (_params.boost_type == LOGIT) || (_params.boost_type == GENTLE) )
data->do_responses_copy();
-
+
update_weights( 0 );
for( i = 0; i < params.weak_count; i++ )
}
bool CvBoost::train( CvMLData* _data,
- CvBoostParams params,
+ CvBoostParams _params,
bool update )
{
bool result = false;
const CvMat* var_idx = _data->get_var_idx();
CV_CALL( result = train( values, CV_ROW_SAMPLE, response, var_idx,
- train_sidx, var_types, missing, params, update ) );
+ train_sidx, var_types, missing, _params, update ) );
__END__;
// invert the subsample mask
cvXorS( subsample_mask, cvScalar(1.), subsample_mask );
data->get_vectors( subsample_mask, values, missing, 0 );
-
+
_sample = cvMat( 1, data->var_count, CV_32F );
_mask = cvMat( 1, data->var_count, CV_8U );
}
-const CvMat*
+const CvMat*
CvBoost::get_active_vars( bool absolute_idx )
{
CvMat* mask = 0;
CvMat* inv_map = 0;
CvMat* result = 0;
-
+
CV_FUNCNAME( "CvBoost::get_active_vars" );
__BEGIN__;
-
+
if( !weak )
CV_ERROR( CV_StsError, "The boosted tree ensemble has not been trained yet" );
int i, j, nactive_vars;
CvBoostTree* wtree;
const CvDTreeNode* node;
-
+
assert(!active_vars && !active_vars_abs);
mask = cvCreateMat( 1, data->var_count, CV_8U );
inv_map = cvCreateMat( 1, data->var_count, CV_32S );
}
nactive_vars = cvCountNonZero(mask);
-
+
//if ( nactive_vars > 0 )
{
active_vars = cvCreateMat( 1, nactive_vars, CV_32S );
j++;
}
}
-
+
// second pass: now compute the condensed indices
cvStartReadSeq( weak, &reader );
"floating-point vector of the same number of components as the length of input slice" );
wstep = CV_IS_MAT_CONT(weak_responses->type) ? 1 : weak_responses->step/sizeof(float);
}
-
+
int var_count = active_vars->cols;
const int* vtype = data->var_type->data.i;
const int* cmap = data->cat_map->data.i;
CvBoostTree* wtree;
const CvDTreeNode* node;
CV_READ_SEQ_ELEM( wtree, reader );
-
+
node = wtree->get_root();
while( node->left )
{
{
const int* avars = active_vars->data.i;
const uchar* m = _missing ? _missing->data.ptr : 0;
-
+
// full-featured version
for( i = 0; i < weak_count; i++ )
{
CvBoostTree* wtree;
const CvDTreeNode* node;
CV_READ_SEQ_ELEM( wtree, reader );
-
+
node = wtree->get_root();
while( node->left )
{
{
CvMat sample, miss;
int si = sidx ? sidx[i] : i;
- cvGetRow( values, &sample, si );
- if( missing )
- cvGetRow( missing, &miss, si );
+ cvGetRow( values, &sample, si );
+ if( missing )
+ cvGetRow( missing, &miss, si );
float r = (float)predict( &sample, missing ? &miss : 0 );
if( pred_resp )
pred_resp[i] = r;
CvMat sample, miss;
int si = sidx ? sidx[i] : i;
cvGetRow( values, &sample, si );
- if( missing )
- cvGetRow( missing, &miss, si );
+ if( missing )
+ cvGetRow( missing, &miss, si );
float r = (float)predict( &sample, missing ? &miss : 0 );
if( pred_resp )
pred_resp[i] = r;
float d = r - response->data.fl[si*r_step];
err += d*d;
}
- err = sample_count ? err / (float)sample_count : -FLT_MAX;
+ err = sample_count ? err / (float)sample_count : -FLT_MAX;
}
return err;
}
default_model_name = "my_boost_tree";
active_vars = active_vars_abs = orig_response = sum_response = weak_eval =
subsample_mask = weights = subtree_weights = 0;
-
+
train( _train_data, _tflag, _responses, _var_idx, _sample_idx,
_var_type, _missing_mask, _params );
-}
+}
bool
weak_count = weak->total;
slice.start_index = 0;
}
-
+
if( !(weak_responses->data && weak_responses->type() == CV_32FC1 &&
(weak_responses->cols == 1 || weak_responses->rows == 1) &&
weak_responses->cols + weak_responses->rows - 1 == weak_count) )
CV_FUNCNAME( "CvERTreeTrainData::set_data" );
__BEGIN__;
-
+
int sample_all = 0, r_type, cv_n;
int total_c_count = 0;
int tree_block_size, temp_block_size, max_split_size, nv_size, cv_size = 0;
int vi, i, size;
char err[100];
const int *sidx = 0, *vidx = 0;
-
+
if ( _params.use_surrogates )
CV_ERROR(CV_StsBadArg, "CvERTrees do not support surrogate splits");
-
+
if( _update_data && data_root )
{
CV_ERROR(CV_StsBadArg, "CvERTrees do not support data update");
CV_ERROR( CV_StsBadArg, "The array of _responses must be an integer or "
"floating-point vector containing as many elements as "
"the total number of samples in the training data matrix" );
-
+
is_buf_16u = false;
- if ( sample_count < 65536 )
- is_buf_16u = true;
-
+ if ( sample_count < 65536 )
+ is_buf_16u = true;
+
r_type = CV_VAR_CATEGORICAL;
if( _var_type )
CV_CALL( var_type0 = cvPreprocessVarType( _var_type, var_idx, var_count, &r_type ));
CV_CALL( var_type = cvCreateMat( 1, var_count+2, CV_32SC1 ));
-
+
cat_var_count = 0;
ord_var_count = -1;
buf_size = (work_var_count + 1)*sample_count;
shared = _shared;
buf_count = shared ? 2 : 1;
-
+
if ( is_buf_16u )
{
CV_CALL( buf = cvCreateMat( buf_count, buf_size, CV_16UC1 ));
{
CV_CALL( buf = cvCreateMat( buf_count, buf_size, CV_32SC1 ));
CV_CALL( int_ptr = (int**)cvAlloc( sample_count*sizeof(int_ptr[0]) ));
- }
+ }
size = is_classifier ? cat_var_count+1 : cat_var_count;
size = !size ? 1 : size;
CV_CALL( cat_count = cvCreateMat( 1, size, CV_32SC1 ));
CV_CALL( cat_ofs = cvCreateMat( 1, size, CV_32SC1 ));
-
+
size = is_classifier ? (cat_var_count + 1)*params.max_categories : cat_var_count*params.max_categories;
size = !size ? 1 : size;
CV_CALL( cat_map = cvCreateMat( 1, size, CV_32SC1 ));
{
int c_count, prev_label;
int* c_map;
-
+
if (is_buf_16u)
udst = (unsigned short*)(buf->data.s + ci*sample_count);
else
idst = buf->data.i + ci*sample_count;
-
+
// copy data
for( i = 0; i < sample_count; i++ )
{
_idst[i] = val;
pair16u32s_ptr[i].u = udst + i;
pair16u32s_ptr[i].i = _idst + i;
- }
+ }
else
{
idst[i] = val;
// replace labels for missing values with -1
for( ; i < sample_count; i++ )
*int_ptr[i] = -1;
- }
+ }
}
else if( ci < 0 ) // process ordered variable
{
if( cv_n )
{
- unsigned short* udst = 0;
- int* idst = 0;
+ unsigned short* usdst = 0;
+ int* idst2 = 0;
if (is_buf_16u)
{
- udst = (unsigned short*)(buf->data.s + (get_work_var_count()-1)*sample_count);
+ usdst = (unsigned short*)(buf->data.s + (get_work_var_count()-1)*sample_count);
for( i = vi = 0; i < sample_count; i++ )
{
- udst[i] = (unsigned short)vi++;
+ usdst[i] = (unsigned short)vi++;
vi &= vi < cv_n ? -1 : 0;
}
int a = (*rng)(sample_count);
int b = (*rng)(sample_count);
unsigned short unsh = (unsigned short)vi;
- CV_SWAP( udst[a], udst[b], unsh );
+ CV_SWAP( usdst[a], usdst[b], unsh );
}
}
else
{
- idst = buf->data.i + (get_work_var_count()-1)*sample_count;
+ idst2 = buf->data.i + (get_work_var_count()-1)*sample_count;
for( i = vi = 0; i < sample_count; i++ )
{
- idst[i] = vi++;
+ idst2[i] = vi++;
vi &= vi < cv_n ? -1 : 0;
}
{
int a = (*rng)(sample_count);
int b = (*rng)(sample_count);
- CV_SWAP( idst[a], idst[b], vi );
+ CV_SWAP( idst2[a], idst2[b], vi );
}
}
}
- if ( cat_map )
+ if ( cat_map )
cat_map->cols = MAX( total_c_count, 1 );
max_split_size = cvAlign(sizeof(CvDTreeSplit) +
const float** ord_values, const int** missing, int* sample_indices_buf )
{
int vidx = var_idx ? var_idx->data.i[vi] : vi;
- int node_sample_count = n->sample_count;
+ int node_sample_count = n->sample_count;
// may use missing_buf as buffer for sample indices!
const int* sample_indices = get_sample_indices(n, sample_indices_buf ? sample_indices_buf : missing_buf);
if( !is_buf_16u )
cat_values = buf->data.i + n->buf_idx*buf->cols + ci*sample_count + n->offset;
else {
- const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols +
+ const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols +
ci*sample_count + n->offset);
for( int i = 0; i < n->sample_count; i++ )
cat_values_buf[i] = short_values[i];
void CvERTreeTrainData::get_vectors( const CvMat* _subsample_idx,
float* values, uchar* missing,
- float* responses, bool get_class_idx )
+ float* _responses, bool get_class_idx )
{
CvMat* subsample_idx = 0;
CvMat* subsample_co = 0;
}
// copy responses
- if( responses )
+ if( _responses )
{
if( is_classifier )
{
int idx = sidx ? sidx[i] : i;
int val = get_class_idx ? src[idx] :
cat_map->data.i[cat_ofs->data.i[cat_var_count]+src[idx]];
- responses[i] = (float)val;
+ _responses[i] = (float)val;
}
}
- else
+ else
{
float* _values_buf = (float*)(uchar*)inn_buf;
int* sample_idx_buf = (int*)(_values_buf + sample_count);
for( i = 0; i < count; i++ )
{
int idx = sidx ? sidx[i] : i;
- responses[i] = _values[idx];
+ _responses[i] = _values[idx];
}
}
}
CvDTreeNode* CvERTreeTrainData::subsample_data( const CvMat* _subsample_idx )
{
CvDTreeNode* root = 0;
-
+
CV_FUNCNAME( "CvERTreeTrainData::subsample_data" );
__BEGIN__;
const float epsilon = FLT_EPSILON*2;
const float split_delta = (1 + FLT_EPSILON) * FLT_EPSILON;
- int n = node->sample_count, i;
+ int n = node->sample_count;
int m = data->get_num_classes();
cv::AutoBuffer<uchar> inn_buf;
for (; smpi < n; smpi++)
{
float ptemp = values[smpi];
- int m = missing[smpi];
- if (m) continue;
+ int ms = missing[smpi];
+ if (ms) continue;
if ( ptemp < pmin)
pmin = ptemp;
if ( ptemp > pmax)
if (split_val - pmin <= FLT_EPSILON)
split_val = pmin + split_delta;
if (pmax - split_val <= FLT_EPSILON)
- split_val = pmax - split_delta;
+ split_val = pmax - split_delta;
// calculate Gini index
if ( !priors )
cv::AutoBuffer<int> lrc(m*2);
int *lc = lrc, *rc = lc + m;
int L = 0, R = 0;
-
+
// init arrays of class instance counters on both sides of the split
- for( i = 0; i < m; i++ )
+ for(int i = 0; i < m; i++ )
{
lc[i] = 0;
rc[i] = 0;
{
int r = responses[si];
float val = values[si];
- int m = missing[si];
- if (m) continue;
+ int ms = missing[si];
+ if (ms) continue;
if ( val < split_val )
{
lc[r]++;
cv::AutoBuffer<double> lrc(m*2);
double *lc = lrc, *rc = lc + m;
double L = 0, R = 0;
-
+
// init arrays of class instance counters on both sides of the split
- for( i = 0; i < m; i++ )
+ for(int i = 0; i < m; i++ )
{
lc[i] = 0;
rc[i] = 0;
{
int r = responses[si];
float val = values[si];
- int m = missing[si];
+ int ms = missing[si];
double p = priors[r];
- if (m) continue;
+ if (ms) continue;
if ( val < split_val )
{
lc[r] += p;
}
best_val = (lbest_val*R + rbest_val*L) / (L*R);
}
-
+
}
CvDTreeSplit* split = 0;
{
int ci = data->get_var_type(vi);
int n = node->sample_count;
- int cm = data->get_num_classes();
+ int cm = data->get_num_classes();
int vm = data->cat_count->data.i[ci];
double best_val = init_quality;
CvDTreeSplit *split = 0;
const int* labels = data->get_cat_var_data( node, vi, ext_buf );
const int* responses = data->get_class_labels( node, ext_buf + n );
-
- const double* priors = data->have_priors ? data->priors_mult->data.db : 0;
+
+ const double* priors = data->have_priors ? data->priors_mult->data.db : 0;
// create random class mask
cv::AutoBuffer<int> valid_cidx(vm);
if (var_class_mask->data.ptr[mask_class_idx])
{
lc[r]++;
- L++;
+ L++;
split->subset[var_class_idx >> 5] |= 1 << (var_class_idx & 31);
}
else
{
lbest_val += lc[i]*lc[i];
rbest_val += rc[i]*rc[i];
- }
+ }
best_val = (lbest_val*R + rbest_val*L) / ((double)(L*R));
}
else
continue;
double p = priors[si];
int mask_class_idx = valid_cidx[var_class_idx];
-
+
if (var_class_mask->data.ptr[mask_class_idx])
{
lc[r]+=(int)p;
- L+=p;
+ L+=p;
split->subset[var_class_idx >> 5] |= 1 << (var_class_idx & 31);
}
else
split->quality = (float)best_val;
cvReleaseMat(&var_class_mask);
- }
- }
+ }
+ }
return split;
}
if (split_val - pmin <= FLT_EPSILON)
split_val = pmin + split_delta;
if (pmax - split_val <= FLT_EPSILON)
- split_val = pmax - split_delta;
+ split_val = pmax - split_delta;
for (int si = 0; si < n; si++)
{
else
{
rsum += r;
- R++;
+ R++;
}
}
best_val = (lsum*lsum*R + rsum*rsum*L)/((double)L*R);
if (var_class_mask->data.ptr[mask_class_idx])
{
lsum += r;
- L++;
+ L++;
split->subset[var_class_idx >> 5] |= 1 << (var_class_idx & 31);
}
else
split->quality = (float)best_val;
cvReleaseMat(&var_class_mask);
- }
- }
+ }
+ }
return split;
}
{
int ci = data->get_var_type(vi);
if (ci >= 0) continue;
-
+
int n1 = node->get_num_valid(vi), nr1 = 0;
float* values_buf = (float*)(uchar*)inn_buf;
int* missing_buf = (int*)(values_buf + n);
for( i = 0; i < n; i++ )
nr1 += ((!missing[i]) & dir[i]);
left->set_num_valid(vi, n1 - nr1);
- right->set_num_valid(vi, nr1);
+ right->set_num_valid(vi, nr1);
}
// split categorical vars, responses and cv_labels using new_idx relocation table
for( vi = 0; vi < data->get_work_var_count() + data->ord_var_count; vi++ )
if (data->is_buf_16u)
{
- unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols +
+ unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols +
ci*scount + left->offset);
- unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*buf->cols +
+ unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*buf->cols +
ci*scount + right->offset);
-
+
for( i = 0; i < n; i++ )
{
int d = dir[i];
}
else
{
- int *ldst = buf->data.i + left->buf_idx*buf->cols +
+ int *ldst = buf->data.i + left->buf_idx*buf->cols +
ci*scount + left->offset;
- int *rdst = buf->data.i + right->buf_idx*buf->cols +
+ int *rdst = buf->data.i + right->buf_idx*buf->cols +
ci*scount + right->offset;
-
+
for( i = 0; i < n; i++ )
{
int d = dir[i];
*ldst = idx;
ldst++;
}
-
+
}
if( vi < data->var_count )
left->set_num_valid(vi, n1 - nr1);
right->set_num_valid(vi, nr1);
}
- }
+ }
}
// split sample indices
temp_buf[i] = sample_idx_src[i];
int pos = data->get_work_var_count();
-
+
if (data->is_buf_16u)
{
- unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
+ unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
pos*scount + left->offset);
- unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols +
+ unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols +
pos*scount + right->offset);
-
+
for (i = 0; i < n; i++)
{
int d = dir[i];
}
else
{
- int* ldst = buf->data.i + left->buf_idx*buf->cols +
+ int* ldst = buf->data.i + left->buf_idx*buf->cols +
pos*scount + left->offset;
- int* rdst = buf->data.i + right->buf_idx*buf->cols +
+ int* rdst = buf->data.i + right->buf_idx*buf->cols +
pos*scount + right->offset;
for (i = 0; i < n; i++)
{
}
}
}
-
+
// deallocate the parent node data that is not needed anymore
- data->free_node_data(node);
+ data->free_node_data(node);
}
CvERTrees::CvERTrees()
__END__
return result;
-
+
}
-bool CvERTrees::train( CvMLData* data, CvRTParams params)
+bool CvERTrees::train( CvMLData* _data, CvRTParams params)
{
bool result = false;
__BEGIN__;
- CV_CALL( result = CvRTrees::train( data, params) );
+ CV_CALL( result = CvRTrees::train( _data, params) );
__END__;
const int dims = data->var_count;
float maximal_response = 0;
- CvMat* oob_sample_votes = 0;
+ CvMat* oob_sample_votes = 0;
CvMat* oob_responses = 0;
float* oob_samples_perm_ptr= 0;
// initialize these variable to avoid warning C4701
CvMat oob_predictions_sum = cvMat( 1, 1, CV_32FC1 );
CvMat oob_num_of_predictions = cvMat( 1, 1, CV_32FC1 );
-
+
nsamples = data->sample_count;
nclasses = data->get_num_classes();
cvGetRow( oob_responses, &oob_predictions_sum, 0 );
cvGetRow( oob_responses, &oob_num_of_predictions, 1 );
}
-
+
CV_CALL(oob_samples_perm_ptr = (float*)cvAlloc( sizeof(float)*nsamples*dims ));
CV_CALL(samples_ptr = (float*)cvAlloc( sizeof(float)*nsamples*dims ));
CV_CALL(missing_ptr = (uchar*)cvAlloc( sizeof(uchar)*nsamples*dims ));
- CV_CALL(true_resp_ptr = (float*)cvAlloc( sizeof(float)*nsamples ));
+ CV_CALL(true_resp_ptr = (float*)cvAlloc( sizeof(float)*nsamples ));
CV_CALL(data->get_vectors( 0, samples_ptr, missing_ptr, true_resp_ptr ));
{
maximal_response = (float)MAX( MAX( fabs(minval), fabs(maxval) ), 0 );
}
}
-
+
trees = (CvForestTree**)cvAlloc( sizeof(trees[0])*max_ntrees );
memset( trees, 0, sizeof(trees[0])*max_ntrees );
sample.data.fl += dims, missing.data.ptr += dims )
{
CvDTreeNode* predicted_node = 0;
-
+
// predict oob samples
if( !predicted_node )
CV_CALL(predicted_node = tree->predict(&sample, &missing, true));
}
result = true;
-
+
cvFree( &oob_samples_perm_ptr );
cvFree( &samples_ptr );
cvFree( &missing_ptr );
cvFree( &true_resp_ptr );
-
+
cvReleaseMat( &sample_idx_for_tree );
cvReleaseMat( &oob_sample_votes );
//===========================================================================\r
\r
bool\r
-CvGBTrees::train( CvMLData* data, CvGBTreesParams params, bool update )\r
+CvGBTrees::train( CvMLData* _data, CvGBTreesParams _params, bool update )\r
{\r
bool result;\r
- result = train ( data->get_values(), CV_ROW_SAMPLE,\r
- data->get_responses(), data->get_var_idx(),\r
- data->get_train_sample_idx(), data->get_var_types(),\r
- data->get_missing(), params, update);\r
+ result = train ( _data->get_values(), CV_ROW_SAMPLE,\r
+ _data->get_responses(), _data->get_var_idx(),\r
+ _data->get_train_sample_idx(), _data->get_var_types(),\r
+ _data->get_missing(), _params, update);\r
//update is not supported\r
return result;\r
}\r
{\r
\r
float err = 0.0f;\r
- const CvMat* sample_idx = (type == CV_TRAIN_ERROR) ?\r
+ const CvMat* _sample_idx = (type == CV_TRAIN_ERROR) ?\r
_data->get_train_sample_idx() :\r
_data->get_test_sample_idx();\r
const CvMat* response = _data->get_responses();\r
\r
- int n = sample_idx ? get_len(sample_idx) : 0;\r
+ int n = _sample_idx ? get_len(_sample_idx) : 0;\r
n = (type == CV_TRAIN_ERROR && n == 0) ? _data->get_values()->rows : n;\r
\r
if (!n)\r
pred_resp = new float[n];\r
\r
Sample_predictor predictor = Sample_predictor(this, pred_resp, _data->get_values(),\r
- _data->get_missing(), sample_idx);\r
+ _data->get_missing(), _sample_idx);\r
\r
//#ifdef HAVE_TBB\r
// tbb::parallel_for(cv::BlockedRange(0,n), predictor, tbb::auto_partitioner());\r
cv::parallel_for(cv::BlockedRange(0,n), predictor);\r
//#endif\r
\r
- int* sidx = sample_idx ? sample_idx->data.i : 0;\r
+ int* sidx = _sample_idx ? _sample_idx->data.i : 0;\r
int r_step = CV_IS_MAT_CONT(response->type) ?\r
1 : response->step / CV_ELEM_SIZE(response->type);\r
\r
const cv::Mat& responses, const cv::Mat& varIdx,\r
const cv::Mat& sampleIdx, const cv::Mat& varType,\r
const cv::Mat& missingDataMask,\r
- CvGBTreesParams params )\r
+ CvGBTreesParams _params )\r
{\r
data = 0;\r
weak = 0;\r
\r
clear();\r
\r
- train(trainData, tflag, responses, varIdx, sampleIdx, varType, missingDataMask, params, false);\r
+ train(trainData, tflag, responses, varIdx, sampleIdx, varType, missingDataMask, _params, false);\r
}\r
\r
bool CvGBTrees::train( const cv::Mat& trainData, int tflag,\r
const cv::Mat& responses, const cv::Mat& varIdx,\r
const cv::Mat& sampleIdx, const cv::Mat& varType,\r
const cv::Mat& missingDataMask,\r
- CvGBTreesParams params,\r
+ CvGBTreesParams _params,\r
bool update )\r
{\r
CvMat _trainData = trainData, _responses = responses;\r
\r
return train( &_trainData, tflag, &_responses, varIdx.empty() ? 0 : &_varIdx,\r
sampleIdx.empty() ? 0 : &_sampleIdx, varType.empty() ? 0 : &_varType,\r
- missingDataMask.empty() ? 0 : &_missingDataMask, params, update);\r
+ missingDataMask.empty() ? 0 : &_missingDataMask, _params, update);\r
}\r
\r
-float CvGBTrees::predict( const cv::Mat& sample, const cv::Mat& missing,\r
+float CvGBTrees::predict( const cv::Mat& sample, const cv::Mat& _missing,\r
const cv::Range& slice, int k ) const\r
{\r
- CvMat _sample = sample, _missing = missing;\r
- return predict(&_sample, missing.empty() ? 0 : &_missing, 0,\r
+ CvMat _sample = sample, miss = _missing;\r
+ return predict(&_sample, _missing.empty() ? 0 : &miss, 0,\r
slice==cv::Range::all() ? CV_WHOLE_SEQ : cvSlice(slice.start, slice.end), k);\r
}\r
ok = true;
__END__;
-
+
if( responses && responses->data.ptr != _responses->data.ptr )
cvReleaseMat(&responses);
result = _result;
buf_sz = _buf_sz;
}
-
+
const CvKNearest* pointer;
int k;
const CvMat* _samples;
CvMat* _dist;
float* result;
int buf_sz;
-
+
void operator()( const cv::BlockedRange& range ) const
{
cv::AutoBuffer<float> buf(buf_sz);
int _max_k, bool _update_base )
{
CvMat tdata = _train_data, responses = _responses, sidx = _sample_idx;
-
+
return train(&tdata, &responses, sidx.data.ptr ? &sidx : 0, _is_regression, _max_k, _update_base );
}
Mat* _dist ) const
{
CvMat s = _samples, results, *presults = 0, nresponses, *pnresponses = 0, dist, *pdist = 0;
-
+
if( _results )
{
if(!(_results->data && (_results->type() == CV_32F ||
_results->create(_samples.rows, 1, CV_32F);
presults = &(results = *_results);
}
-
+
if( _neighbor_responses )
{
if(!(_neighbor_responses->data && _neighbor_responses->type() == CV_32F &&
_neighbor_responses->create(_samples.rows, k, CV_32F);
pnresponses = &(nresponses = *_neighbor_responses);
}
-
+
if( _dist )
{
if(!(_dist->data && _dist->type() == CV_32F &&
_dist->create(_samples.rows, k, CV_32F);
pdist = &(dist = *_dist);
}
-
+
return find_nearest(&s, k, presults, _neighbors, pnresponses, pdist );
}
-float CvKNearest::find_nearest( const cv::Mat& samples, int k, CV_OUT cv::Mat& results,
+float CvKNearest::find_nearest( const cv::Mat& _samples, int k, CV_OUT cv::Mat& results,
CV_OUT cv::Mat& neighborResponses, CV_OUT cv::Mat& dists) const
{
- return find_nearest(samples, k, &results, 0, &neighborResponses, &dists);
+ return find_nearest(_samples, k, &results, 0, &neighborResponses, &dists);
}
/* End of file */
double* cov_data = cov->data.db + i*_var_count;
double s1val = sum1[i];
double avg1 = avg_data[i];
- int count = count_data[i];
+ int _count = count_data[i];
for( j = 0; j <= i; j++ )
{
double avg2 = avg2_data[j];
- double cov_val = prod_data[j] - avg1 * sum2[j] - avg2 * s1val + avg1 * avg2 * count;
- cov_val = (count > 1) ? cov_val / (count - 1) : cov_val;
+ double cov_val = prod_data[j] - avg1 * sum2[j] - avg2 * s1val + avg1 * avg2 * _count;
+ cov_val = (_count > 1) ? cov_val / (_count - 1) : cov_val;
cov_data[j] = cov_val;
}
}
value = _value;
var_count1 = _var_count1;
}
-
+
CvMat* c;
CvMat** cov_rotate_mats;
CvMat** inv_eigen_values;
CvMat* results;
float* value;
int var_count1;
-
+
void operator()( const cv::BlockedRange& range ) const
{
int cls = -1;
- int rtype = 0, rstep = 0;
+ int rtype = 0, rstep = 0;
int nclasses = cls_labels->cols;
int _var_count = avg[0]->cols;
-
+
if (results)
{
rtype = CV_MAT_TYPE(results->type);
// allocate memory and initializing headers for calculating
cv::AutoBuffer<double> buffer(nclasses + var_count1);
CvMat diff = cvMat( 1, var_count1, CV_64FC1, &buffer[0] );
-
+
for(int k = range.begin(); k < range.end(); k += 1 )
{
int ival;
cov_rotate_mats = 0;
c = 0;
default_model_name = "my_nb";
-
+
CvMat tdata = _train_data, responses = _responses, vidx = _var_idx, sidx = _sample_idx;
train(&tdata, &responses, vidx.data.ptr ? &vidx : 0,
sidx.data.ptr ? &sidx : 0);
float CvNormalBayesClassifier::predict( const Mat& _samples, Mat* _results ) const
{
CvMat samples = _samples, results, *presults = 0;
-
+
if( _results )
{
if( !(_results->data && _results->type() == CV_32F &&
_results->create(_samples.rows, 1, CV_32F);
presults = &(results = *_results);
}
-
+
return predict(&samples, presults);
}
return grow_forest( params.term_crit );
}
-bool CvRTrees::train( CvMLData* data, CvRTParams params )
+bool CvRTrees::train( CvMLData* _data, CvRTParams params )
{
- const CvMat* values = data->get_values();
- const CvMat* response = data->get_responses();
- const CvMat* missing = data->get_missing();
- const CvMat* var_types = data->get_var_types();
- const CvMat* train_sidx = data->get_train_sample_idx();
- const CvMat* var_idx = data->get_var_idx();
+ const CvMat* values = _data->get_values();
+ const CvMat* response = _data->get_responses();
+ const CvMat* missing = _data->get_missing();
+ const CvMat* var_types = _data->get_var_types();
+ const CvMat* train_sidx = _data->get_train_sample_idx();
+ const CvMat* var_idx = _data->get_var_idx();
return train( values, CV_ROW_SAMPLE, response, var_idx,
train_sidx, var_types, missing, params );
const int dims = data->var_count;
float maximal_response = 0;
- CvMat* oob_sample_votes = 0;
+ CvMat* oob_sample_votes = 0;
CvMat* oob_responses = 0;
float* oob_samples_perm_ptr= 0;
// initialize these variable to avoid warning C4701
CvMat oob_predictions_sum = cvMat( 1, 1, CV_32FC1 );
CvMat oob_num_of_predictions = cvMat( 1, 1, CV_32FC1 );
-
+
nsamples = data->sample_count;
nclasses = data->get_num_classes();
cvGetRow( oob_responses, &oob_predictions_sum, 0 );
cvGetRow( oob_responses, &oob_num_of_predictions, 1 );
}
-
+
oob_samples_perm_ptr = (float*)cvAlloc( sizeof(float)*nsamples*dims );
samples_ptr = (float*)cvAlloc( sizeof(float)*nsamples*dims );
missing_ptr = (uchar*)cvAlloc( sizeof(uchar)*nsamples*dims );
- true_resp_ptr = (float*)cvAlloc( sizeof(float)*nsamples );
+ true_resp_ptr = (float*)cvAlloc( sizeof(float)*nsamples );
data->get_vectors( 0, samples_ptr, missing_ptr, true_resp_ptr );
-
+
double minval, maxval;
CvMat responses = cvMat(1, nsamples, CV_32FC1, true_resp_ptr);
cvMinMaxLoc( &responses, &minval, &maxval );
cvFree( &samples_ptr );
cvFree( &missing_ptr );
cvFree( &true_resp_ptr );
-
+
cvReleaseMat( &sample_idx_mask_for_tree );
cvReleaseMat( &sample_idx_for_tree );
{
CvMat sample, miss;
int si = sidx ? sidx[i] : i;
- cvGetRow( values, &sample, si );
- if( missing )
- cvGetRow( missing, &miss, si );
+ cvGetRow( values, &sample, si );
+ if( missing )
+ cvGetRow( missing, &miss, si );
float r = (float)predict( &sample, missing ? &miss : 0 );
if( pred_resp )
pred_resp[i] = r;
CvMat sample, miss;
int si = sidx ? sidx[i] : i;
cvGetRow( values, &sample, si );
- if( missing )
- cvGetRow( missing, &miss, si );
+ if( missing )
+ cvGetRow( missing, &miss, si );
float r = (float)predict( &sample, missing ? &miss : 0 );
if( pred_resp )
pred_resp[i] = r;
float d = r - response->data.fl[si*r_step];
err += d*d;
}
- err = sample_count ? err / (float)sample_count : -FLT_MAX;
+ err = sample_count ? err / (float)sample_count : -FLT_MAX;
}
return err;
}
float *responses_ptr = (float*)cvAlloc( sizeof(float)*sample_count );
data->get_vectors( 0, values_ptr, missing_ptr, responses_ptr);
-
+
if (data->is_classifier)
{
int err_count = 0;
float *vp = values_ptr;
- uchar *mp = missing_ptr;
+ uchar *mp = missing_ptr;
for (int si = 0; si < sample_count; si++, vp += var_count, mp += var_count)
{
CvMat sample = cvMat( 1, var_count, CV_32FC1, vp );
}
else
CV_Error( CV_StsBadArg, "This method is not supported for regression problems" );
-
+
cvFree( &values_ptr );
cvFree( &missing_ptr );
- cvFree( &responses_ptr );
+ cvFree( &responses_ptr );
return err;
}
float CvRTrees::predict_prob( const CvMat* sample, const CvMat* missing) const
{
- if( nclasses == 2 ) //classification
+ if( nclasses == 2 ) //classification
{
cv::AutoBuffer<int> _votes(nclasses);
int* votes = _votes;
CvDTreeNode* predicted_node = trees[k]->predict( sample, missing );
int class_idx = predicted_node->class_idx;
CV_Assert( 0 <= class_idx && class_idx < nclasses );
-
+
++votes[class_idx];
}
-
- return float(votes[1])/ntrees;
+
+ return float(votes[1])/ntrees;
}
else // regression
- CV_Error(CV_StsBadArg, "This function works for binary classification problems only...");
-
+ CV_Error(CV_StsBadArg, "This function works for binary classification problems only...");
+
return -1;
}
{
// initialize active variables mask
CvMat submask1;
- cvGetCols( active_var_mask, &submask1, 0, nactive_vars );
+ cvGetCols( active_var_mask, &submask1, 0, nactive_vars );
cvSet( &submask1, cvScalar(1) );
- if( nactive_vars < var_count )
- {
- CvMat submask2;
- cvGetCols( active_var_mask, &submask2, nactive_vars, var_count );
- cvZero( &submask2 );
- }
+ if( nactive_vars < var_count )
+ {
+ CvMat submask2;
+ cvGetCols( active_var_mask, &submask2, nactive_vars, var_count );
+ cvZero( &submask2 );
+ }
}
}
CvSVMKernel* _kernel, double* _alpha, CvSVMSolutionInfo& _si )
{
int i;
- double p = _kernel->params->p, C = _kernel->params->C;
+ double p = _kernel->params->p, _C = _kernel->params->C;
if( !create( _sample_count, _var_count, _samples, 0,
- _sample_count*2, 0, C, C, _storage, _kernel, &CvSVMSolver::get_row_svr,
+ _sample_count*2, 0, _C, _C, _storage, _kernel, &CvSVMSolver::get_row_svr,
&CvSVMSolver::select_working_set, &CvSVMSolver::calc_rho ))
return false;
CvSVMKernel* _kernel, double* _alpha, CvSVMSolutionInfo& _si )
{
int i;
- double C = _kernel->params->C, sum;
+ double _C = _kernel->params->C, sum;
if( !create( _sample_count, _var_count, _samples, 0,
_sample_count*2, 0, 1., 1., _storage, _kernel, &CvSVMSolver::get_row_svr,
y = (schar*)cvMemStorageAlloc( storage, sample_count*2*sizeof(y[0]) );
alpha = (double*)cvMemStorageAlloc( storage, alpha_count*sizeof(alpha[0]) );
- sum = C * _kernel->params->nu * sample_count * 0.5;
+ sum = _C * _kernel->params->nu * sample_count * 0.5;
for( i = 0; i < sample_count; i++ )
{
- alpha[i] = alpha[i + sample_count] = MIN(sum, C);
+ alpha[i] = alpha[i + sample_count] = MIN(sum, _C);
sum -= alpha[i];
b[i] = -_y[i];
int svm_type, sample_count, var_count, sample_size;
int block_size = 1 << 16;
double* alpha;
- int i, k;
RNG* rng = &theRNG();
// all steps are logarithmic and must be > 1
double degree_step = 10, g_step = 10, coef_step = 10, C_step = 10, nu_step = 10, p_step = 10;
- double gamma = 0, C = 0, degree = 0, coef = 0, p = 0, nu = 0;
+ double gamma = 0, _C = 0, degree = 0, coef = 0, p = 0, nu = 0;
double best_degree = 0, best_gamma = 0, best_coef = 0, best_C = 0, best_nu = 0, best_p = 0;
float min_error = FLT_MAX, error;
cvZero( responses_local );
// randomly permute samples and responses
- for( i = 0; i < sample_count; i++ )
+ for(int i = 0; i < sample_count; i++ )
{
int i1 = (*rng)(sample_count);
int i2 = (*rng)(sample_count);
{
// count class samples
int num_0=0,num_1=0;
- for (i=0; i<sample_count; ++i)
+ for (int i=0; i<sample_count; ++i)
{
if (responses->data.i[i]==class_labels->data.i[0])
++num_0;
}
int* cls_lbls = class_labels ? class_labels->data.i : 0;
- C = C_grid.min_val;
+ _C = C_grid.min_val;
do
{
- params.C = C;
+ params.C = _C;
gamma = gamma_grid.min_val;
do
{
int train_size = trainset_size;
error = 0;
- for( k = 0; k < k_fold; k++ )
+ for(int k = 0; k < k_fold; k++ )
{
memcpy( samples_local, samples, sizeof(samples[0])*test_size*k );
memcpy( samples_local + test_size*k, test_samples_ptr + test_size,
EXIT;
// Compute test set error on <test_size> samples
- for( i = 0; i < test_size; i++, true_resp += resp_elem_size, test_samples_ptr++ )
+ for(int i = 0; i < test_size; i++, true_resp += resp_elem_size, test_samples_ptr++ )
{
float resp = predict( *test_samples_ptr, var_count );
error += is_regression ? powf( resp - *(float*)true_resp, 2 )
best_degree = degree;
best_gamma = gamma;
best_coef = coef;
- best_C = C;
+ best_C = _C;
best_nu = nu;
best_p = p;
}
gamma *= gamma_grid.step;
}
while( gamma < gamma_grid.max_val );
- C *= C_grid.step;
+ _C *= C_grid.step;
}
- while( C < C_grid.max_val );
+ while( _C < C_grid.max_val );
}
min_error /= (float) sample_count;
int vi, i, size;
char err[100];
const int *sidx = 0, *vidx = 0;
-
+
if( _update_data && data_root )
{
data = new CvDTreeTrainData( _train_data, _tflag, _responses, _var_idx,
sample_count = sample_all;
var_count = var_all;
-
+
if( _sample_idx )
{
CV_CALL( sample_indices = cvPreprocessIndexArray( _sample_idx, sample_all ));
var_count = var_idx->rows + var_idx->cols - 1;
}
- is_buf_16u = false;
- if ( sample_count < 65536 )
- is_buf_16u = true;
-
+ is_buf_16u = false;
+ if ( sample_count < 65536 )
+ is_buf_16u = true;
+
if( !CV_IS_MAT(_responses) ||
(CV_MAT_TYPE(_responses->type) != CV_32SC1 &&
CV_MAT_TYPE(_responses->type) != CV_32FC1) ||
CV_ERROR( CV_StsBadArg, "The array of _responses must be an integer or "
"floating-point vector containing as many elements as "
"the total number of samples in the training data matrix" );
-
+
r_type = CV_VAR_CATEGORICAL;
if( _var_type )
CV_CALL( var_type0 = cvPreprocessVarType( _var_type, var_idx, var_count, &r_type ));
CV_CALL( var_type = cvCreateMat( 1, var_count+2, CV_32SC1 ));
-
+
cat_var_count = 0;
ord_var_count = -1;
work_var_count = var_count + (is_classifier ? 1 : 0) // for responses class_labels
+ (have_labels ? 1 : 0); // for cv_labels
-
+
buf_size = (work_var_count + 1 /*for sample_indices*/) * sample_count;
shared = _shared;
buf_count = shared ? 2 : 1;
-
+
if ( is_buf_16u )
{
CV_CALL( buf = cvCreateMat( buf_count, buf_size, CV_16UC1 ));
{
CV_CALL( buf = cvCreateMat( buf_count, buf_size, CV_32SC1 ));
CV_CALL( int_ptr = (int**)cvAlloc( sample_count*sizeof(int_ptr[0]) ));
- }
+ }
size = is_classifier ? (cat_var_count+1) : cat_var_count;
size = !size ? 1 : size;
CV_CALL( cat_count = cvCreateMat( 1, size, CV_32SC1 ));
CV_CALL( cat_ofs = cvCreateMat( 1, size, CV_32SC1 ));
-
+
size = is_classifier ? (cat_var_count + 1)*params.max_categories : cat_var_count*params.max_categories;
size = !size ? 1 : size;
CV_CALL( cat_map = cvCreateMat( 1, size, CV_32SC1 ));
{
int c_count, prev_label;
int* c_map;
-
+
if (is_buf_16u)
udst = (unsigned short*)(buf->data.s + vi*sample_count);
else
idst = buf->data.i + vi*sample_count;
-
+
// copy data
for( i = 0; i < sample_count; i++ )
{
_idst[i] = val;
pair16u32s_ptr[i].u = udst + i;
pair16u32s_ptr[i].i = _idst + i;
- }
+ }
else
{
idst[i] = val;
// replace labels for missing values with -1
for( ; i < sample_count; i++ )
*int_ptr[i] = -1;
- }
+ }
}
else if( ci < 0 ) // process ordered variable
{
else
idst[i] = i;
_fdst[i] = val;
-
+
}
if (is_buf_16u)
icvSortUShAux( udst, sample_count, _fdst);
else
icvSortIntAux( idst, sample_count, _fdst );
}
-
+
if( vi < var_count )
data_root->set_num_valid(vi, num_valid);
}
if( cv_n )
{
- unsigned short* udst = 0;
- int* idst = 0;
+ unsigned short* usdst = 0;
+ int* idst2 = 0;
if (is_buf_16u)
{
- udst = (unsigned short*)(buf->data.s + (get_work_var_count()-1)*sample_count);
+ usdst = (unsigned short*)(buf->data.s + (get_work_var_count()-1)*sample_count);
for( i = vi = 0; i < sample_count; i++ )
{
- udst[i] = (unsigned short)vi++;
+ usdst[i] = (unsigned short)vi++;
vi &= vi < cv_n ? -1 : 0;
}
int a = (*rng)(sample_count);
int b = (*rng)(sample_count);
unsigned short unsh = (unsigned short)vi;
- CV_SWAP( udst[a], udst[b], unsh );
+ CV_SWAP( usdst[a], usdst[b], unsh );
}
}
else
{
- idst = buf->data.i + (get_work_var_count()-1)*sample_count;
+ idst2 = buf->data.i + (get_work_var_count()-1)*sample_count;
for( i = vi = 0; i < sample_count; i++ )
{
- idst[i] = vi++;
+ idst2[i] = vi++;
vi &= vi < cv_n ? -1 : 0;
}
{
int a = (*rng)(sample_count);
int b = (*rng)(sample_count);
- CV_SWAP( idst[a], idst[b], vi );
+ CV_SWAP( idst2[a], idst2[b], vi );
}
}
}
- if ( cat_map )
+ if ( cat_map )
cat_map->cols = MAX( total_c_count, 1 );
max_split_size = cvAlign(sizeof(CvDTreeSplit) +
if (is_buf_16u)
{
- unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
+ unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
vi*sample_count + root->offset);
for( i = 0; i < count; i++ )
{
}
else
{
- int* idst = buf->data.i + root->buf_idx*buf->cols +
+ int* idst = buf->data.i + root->buf_idx*buf->cols +
vi*sample_count + root->offset;
for( i = 0; i < count; i++ )
{
if (is_buf_16u)
{
- unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
+ unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
vi*sample_count + data_root->offset);
for( i = 0; i < num_valid; i++ )
{
}
else
{
- int* idst_idx = buf->data.i + root->buf_idx*buf->cols +
+ int* idst_idx = buf->data.i + root->buf_idx*buf->cols +
vi*sample_count + root->offset;
for( i = 0; i < num_valid; i++ )
{
const int* sample_idx_src = get_sample_indices(data_root, (int*)(uchar*)inn_buf);
if (is_buf_16u)
{
- unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
+ unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*buf->cols +
workVarCount*sample_count + root->offset);
for (i = 0; i < count; i++)
sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]];
}
else
{
- int* sample_idx_dst = buf->data.i + root->buf_idx*buf->cols +
+ int* sample_idx_dst = buf->data.i + root->buf_idx*buf->cols +
workVarCount*sample_count + root->offset;
for (i = 0; i < count; i++)
sample_idx_dst[i] = sample_idx_src[sidx[i]];
void CvDTreeTrainData::get_vectors( const CvMat* _subsample_idx,
float* values, uchar* missing,
- float* responses, bool get_class_idx )
+ float* _responses, bool get_class_idx )
{
CvMat* subsample_idx = 0;
CvMat* subsample_co = 0;
}
// copy responses
- if( responses )
+ if( _responses )
{
if( is_classifier )
{
int idx = sidx ? sidx[i] : i;
int val = get_class_idx ? src[idx] :
cat_map->data.i[cat_ofs->data.i[cat_var_count]+src[idx]];
- responses[i] = (float)val;
+ _responses[i] = (float)val;
}
}
else
for( i = 0; i < count; i++ )
{
int idx = sidx ? sidx[i] : i;
- responses[i] = _values[idx];
+ _responses[i] = _values[idx];
}
}
}
cvReleaseMat( &cat_map );
cvReleaseMat( &priors );
cvReleaseMat( &priors_mult );
-
+
node_heap = split_heap = 0;
sample_count = var_all = var_count = max_c_count = ord_var_count = cat_var_count = 0;
buf_count = buf_size = 0;
shared = false;
-
+
data_root = 0;
rng = &cv::theRNG();
const float** ord_values, const int** sorted_indices, int* sample_indices_buf )
{
int vidx = var_idx ? var_idx->data.i[vi] : vi;
- int node_sample_count = n->sample_count;
+ int node_sample_count = n->sample_count;
int td_step = train_data->step/CV_ELEM_SIZE(train_data->type);
const int* sample_indices = get_sample_indices(n, sample_indices_buf);
*sorted_indices = buf->data.i + n->buf_idx*buf->cols +
vi*sample_count + n->offset;
else {
- const unsigned short* short_indices = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols +
+ const unsigned short* short_indices = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols +
vi*sample_count + n->offset );
for( int i = 0; i < node_sample_count; i++ )
sorted_indices_buf[i] = short_indices[i];
*sorted_indices = sorted_indices_buf;
}
-
+
if( tflag == CV_ROW_SAMPLE )
{
- for( int i = 0; i < node_sample_count &&
+ for( int i = 0; i < node_sample_count &&
((((*sorted_indices)[i] >= 0) && !is_buf_16u) || (((*sorted_indices)[i] != 65535) && is_buf_16u)); i++ )
{
int idx = (*sorted_indices)[i];
}
}
else
- for( int i = 0; i < node_sample_count &&
+ for( int i = 0; i < node_sample_count &&
((((*sorted_indices)[i] >= 0) && !is_buf_16u) || (((*sorted_indices)[i] != 65535) && is_buf_16u)); i++ )
{
int idx = (*sorted_indices)[i];
idx = sample_indices[idx];
ord_values_buf[i] = *(train_data->data.fl + vidx* td_step + idx);
}
-
+
*ord_values = ord_values_buf;
}
const float* CvDTreeTrainData::get_ord_responses( CvDTreeNode* n, float* values_buf, int*sample_indices_buf )
{
- int sample_count = n->sample_count;
+ int _sample_count = n->sample_count;
int r_step = CV_IS_MAT_CONT(responses->type) ? 1 : responses->step/CV_ELEM_SIZE(responses->type);
const int* indices = get_sample_indices(n, sample_indices_buf);
- for( int i = 0; i < sample_count &&
+ for( int i = 0; i < _sample_count &&
(((indices[i] >= 0) && !is_buf_16u) || ((indices[i] != 65535) && is_buf_16u)); i++ )
{
int idx = indices[i];
values_buf[i] = *(responses->data.fl + idx * r_step);
}
-
+
return values_buf;
}
cat_values = buf->data.i + n->buf_idx*buf->cols +
vi*sample_count + n->offset;
else {
- const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols +
+ const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols +
vi*sample_count + n->offset);
for( int i = 0; i < n->sample_count; i++ )
cat_values_buf[i] = short_values[i];
const Mat& _missing_mask, CvDTreeParams _params )
{
CvMat tdata = _train_data, responses = _responses, vidx=_var_idx,
- sidx=_sample_idx, vtype=_var_type, mmask=_missing_mask;
+ sidx=_sample_idx, vtype=_var_type, mmask=_missing_mask;
return train(&tdata, _tflag, &responses, vidx.data.ptr ? &vidx : 0, sidx.data.ptr ? &sidx : 0,
vtype.data.ptr ? &vtype : 0, mmask.data.ptr ? &mmask : 0, _params);
}
const float* val = 0;
const int* sorted = 0;
data->get_ord_var_data( node, vi, val_buf, sorted_buf, &val, &sorted, sample_idx_buf);
-
+
assert( 0 <= split_point && split_point < n1-1 );
if( !data->have_priors )
{
fastFree(obj);
}
-
+
DTreeBestSplitFinder::DTreeBestSplitFinder( CvDTree* _tree, CvDTreeNode* _node)
{
tree = _tree;
}
CvDTreeSplit* split = 0;
- if( best_subset >= 0 )
+ if( best_subset >= 0 )
{
split = _split ? _split : data->new_split_cat( 0, -1.0f );
split->var_idx = vi;
{
int idx = labels[i];
if( !dir[i] && ( ((idx >= 0)&&(!data->is_buf_16u)) || ((idx != 65535)&&(data->is_buf_16u)) ))
-
+
{
int d = CV_DTREE_CAT_DIR(idx,subset);
dir[i] = (char)((d ^ inversed_mask) - inversed_mask);
{
unsigned short *ldst, *rdst, *ldst0, *rdst0;
//unsigned short tl, tr;
- ldst0 = ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
+ ldst0 = ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
vi*scount + left->offset);
rdst0 = rdst = (unsigned short*)(ldst + nl);
else
{
int *ldst0, *ldst, *rdst0, *rdst;
- ldst0 = ldst = buf->data.i + left->buf_idx*buf->cols +
+ ldst0 = ldst = buf->data.i + left->buf_idx*buf->cols +
vi*scount + left->offset;
- rdst0 = rdst = buf->data.i + right->buf_idx*buf->cols +
+ rdst0 = rdst = buf->data.i + right->buf_idx*buf->cols +
vi*scount + right->offset;
// split sorted
{
int ci = data->get_var_type(vi);
int n1 = node->get_num_valid(vi), nr1 = 0;
-
+
if( ci < 0 || (vi < data->var_count && !split_input_data) )
continue;
if (data->is_buf_16u)
{
- unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols +
+ unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*buf->cols +
vi*scount + left->offset);
- unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*buf->cols +
+ unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*buf->cols +
vi*scount + right->offset);
-
+
for( i = 0; i < n; i++ )
{
int d = dir[i];
}
else
{
- int *ldst = buf->data.i + left->buf_idx*buf->cols +
+ int *ldst = buf->data.i + left->buf_idx*buf->cols +
vi*scount + left->offset;
- int *rdst = buf->data.i + right->buf_idx*buf->cols +
+ int *rdst = buf->data.i + right->buf_idx*buf->cols +
vi*scount + right->offset;
-
+
for( i = 0; i < n; i++ )
{
int d = dir[i];
*ldst = idx;
ldst++;
}
-
+
}
if( vi < data->var_count )
left->set_num_valid(vi, n1 - nr1);
right->set_num_valid(vi, nr1);
}
- }
+ }
}
int pos = data->get_work_var_count();
if (data->is_buf_16u)
{
- unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
+ unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
pos*scount + left->offset);
- unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols +
+ unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols +
pos*scount + right->offset);
for (i = 0; i < n; i++)
{
}
else
{
- int* ldst = buf->data.i + left->buf_idx*buf->cols +
+ int* ldst = buf->data.i + left->buf_idx*buf->cols +
pos*scount + left->offset;
- int* rdst = buf->data.i + right->buf_idx*buf->cols +
+ int* rdst = buf->data.i + right->buf_idx*buf->cols +
pos*scount + right->offset;
for (i = 0; i < n; i++)
{
}
}
}
-
+
// deallocate the parent node data that is not needed anymore
- data->free_node_data(node);
+ data->free_node_data(node);
}
float CvDTree::calc_error( CvMLData* _data, int type, vector<float> *resp )
{
CvMat sample, miss;
int si = sidx ? sidx[i] : i;
- cvGetRow( values, &sample, si );
- if( missing )
- cvGetRow( missing, &miss, si );
+ cvGetRow( values, &sample, si );
+ if( missing )
+ cvGetRow( missing, &miss, si );
float r = (float)predict( &sample, missing ? &miss : 0 )->value;
if( pred_resp )
pred_resp[i] = r;
{
CvMat sample, miss;
int si = sidx ? sidx[i] : i;
- cvGetRow( values, &sample, si );
- if( missing )
- cvGetRow( missing, &miss, si );
+ cvGetRow( values, &sample, si );
+ if( missing )
+ cvGetRow( missing, &miss, si );
float r = (float)predict( &sample, missing ? &miss : 0 )->value;
if( pred_resp )
pred_resp[i] = r;
float d = r - response->data.fl[si*r_step];
err += d*d;
}
- err = sample_count ? err / (float)sample_count : -FLT_MAX;
+ err = sample_count ? err / (float)sample_count : -FLT_MAX;
}
return err;
}
}
-void CvDTree::free_prune_data(bool cut_tree)
+void CvDTree::free_prune_data(bool _cut_tree)
{
CvDTreeNode* node = root;
for( parent = node->parent; parent && parent->right == node;
node = parent, parent = parent->parent )
{
- if( cut_tree && parent->Tn <= pruned_tree_idx )
+ if( _cut_tree && parent->Tn <= pruned_tree_idx )
{
data->free_node( parent->left );
data->free_node( parent->right );
{
int a = c = cofs[ci];
int b = (ci+1 >= data->cat_ofs->cols) ? data->cat_map->cols : cofs[ci+1];
-
+
int ival = cvRound(val);
if( ival != val )
CV_Error( CV_StsBadArg,
"one of input categorical variable is not an integer" );
-
+
int sh = 0;
while( a < b )
{
CV_Assert( _means.rows == (int)sizes.size() && covs.size() == sizes.size() );
CV_Assert( !data.empty() && data.rows == total );
CV_Assert( data.type() == dataType );
-
+
labels.create( data.rows, 1, labelType );
randn( data, Scalar::all(-1.0), Scalar::all(1.0) );
for( int i = bi; i < ei; i++, p++ )
{
Mat r = data.row(i);
- r = r * (*cit) + *mit;
+ r = r * (*cit) + *mit;
if( labelType == CV_32FC1 )
labels.at<float>(p, 0) = (float)l;
else if( labelType == CV_32SC1 )
const int iters = 100;
int sizesArr[] = { 5000, 7000, 8000 };
int pointsCount = sizesArr[0]+ sizesArr[1] + sizesArr[2];
-
+
Mat data( pointsCount, 2, CV_32FC1 ), labels;
vector<int> sizes( sizesArr, sizesArr + sizeof(sizesArr) / sizeof(sizesArr[0]) );
Mat means;
vector<Mat> covs;
defaultDistribs( means, covs );
generateData( data, labels, sizes, means, covs, CV_32FC1, CV_32SC1 );
-
+
int code = cvtest::TS::OK;
float err;
Mat bestLabels;
class EM_Params
{
public:
- EM_Params(int nclusters=10, int covMatType=EM::COV_MAT_DIAGONAL, int startStep=EM::START_AUTO_STEP,
- const cv::TermCriteria& termCrit=cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, FLT_EPSILON),
- const cv::Mat* probs=0, const cv::Mat* weights=0,
- const cv::Mat* means=0, const std::vector<cv::Mat>* covs=0)
- : nclusters(nclusters), covMatType(covMatType), startStep(startStep),
- probs(probs), weights(weights), means(means), covs(covs), termCrit(termCrit)
+ EM_Params(int _nclusters=10, int _covMatType=EM::COV_MAT_DIAGONAL, int _startStep=EM::START_AUTO_STEP,
+ const cv::TermCriteria& _termCrit=cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, FLT_EPSILON),
+ const cv::Mat* _probs=0, const cv::Mat* _weights=0,
+ const cv::Mat* _means=0, const std::vector<cv::Mat>* _covs=0)
+ : nclusters(_nclusters), covMatType(_covMatType), startStep(_startStep),
+ probs(_probs), weights(_weights), means(_means), covs(_covs), termCrit(_termCrit)
{}
-
+
int nclusters;
int covMatType;
int startStep;
-
+
// all 4 following matrices should have type CV_32FC1
const cv::Mat* probs;
const cv::Mat* weights;
const cv::Mat* means;
const std::vector<cv::Mat>* covs;
-
+
cv::TermCriteria termCrit;
};
int currCode = runCase(caseIndex++, params, trainData, trainLabels, testData, testLabels, sizes);
code = currCode == cvtest::TS::OK ? code : currCode;
}
-
+
ts->set_failed_test_info( code );
}
{
public:
CV_GBTreesTest();
- ~CV_GBTreesTest();
-
+ ~CV_GBTreesTest();
+
protected:
void run(int);
int TestSaveLoad();
int checkPredictError(int test_num);
- int checkLoadSave();
-
+ int checkLoadSave();
+
string model_file_name1;
string model_file_name2;
string* datasets;
string data_path;
-
+
CvMLData* data;
CvGBTrees* gtb;
-
+
vector<float> test_resps1;
vector<float> test_resps2;
- int64 initSeed;
+ int64 initSeed;
};
CV_GBTreesTest::CV_GBTreesTest()
{
- int64 seeds[] = { CV_BIG_INT(0x00009fff4f9c8d52),
+ int64 seeds[] = { CV_BIG_INT(0x00009fff4f9c8d52),
CV_BIG_INT(0x0000a17166072c7c),
CV_BIG_INT(0x0201b32115cd1f9a),
CV_BIG_INT(0x0513cb37abcd1234),
};
int seedCount = sizeof(seeds)/sizeof(seeds[0]);
- cv::RNG& rng = cv::theRNG();
+ cv::RNG& rng = cv::theRNG();
initSeed = rng.state;
rng.state = seeds[rng(seedCount)];
if (data)
delete data;
delete[] datasets;
- cv::theRNG().state = initSeed;
+ cv::theRNG().state = initSeed;
}
int CV_GBTreesTest::TestTrainPredict(int test_num)
{
int code = cvtest::TS::OK;
-
+
int weak_count = 200;
float shrinkage = 0.1f;
float subsample_portion = 0.5f;
case (2) : loss_function_type = CvGBTrees::ABSOLUTE_LOSS; break;
case (3) : loss_function_type = CvGBTrees::HUBER_LOSS; break;
case (0) : loss_function_type = CvGBTrees::DEVIANCE_LOSS; break;
- default :
+ default :
{
ts->printf( cvtest::TS::LOG, "Bad test_num value in CV_GBTreesTest::TestTrainPredict(..) function." );
return cvtest::TS::FAIL_BAD_ARG_CHECK;
{
data = new CvMLData();
data->set_delimiter(',');
-
+
if (data->read_csv(datasets[dataset_num].c_str()))
{
ts->printf( cvtest::TS::LOG, "File reading error." );
CvTrainTestSplit spl( train_sample_count );
data->set_train_test_split( &spl );
}
-
- data->mix_train_and_test_idx();
-
-
+
+ data->mix_train_and_test_idx();
+
+
if (gtb) delete gtb;
gtb = new CvGBTrees();
bool tmp_code = true;
tmp_code = gtb->train(data, CvGBTreesParams(loss_function_type, weak_count,
shrinkage, subsample_portion,
max_depth, use_surrogates));
-
+
if (!tmp_code)
{
ts->printf( cvtest::TS::LOG, "Model training was failed.");
return cvtest::TS::FAIL_INVALID_OUTPUT;
}
-
+
code = checkPredictError(test_num);
-
+
return code;
}
{
if (!gtb)
return cvtest::TS::FAIL_GENERIC;
-
+
//float mean[] = {5.430247f, 13.5654f, 12.6569f, 13.1661f};
//float sigma[] = {0.4162694f, 3.21161f, 3.43297f, 3.00624f};
- float mean[] = {5.80226f, 12.68689f, 13.49095f, 13.19628f};
+ float mean[] = {5.80226f, 12.68689f, 13.49095f, 13.19628f};
float sigma[] = {0.4764534f, 3.166919f, 3.022405f, 2.868722f};
-
+
float current_error = gtb->calc_error(data, CV_TEST_ERROR);
-
+
if ( abs( current_error - mean[test_num]) > 6*sigma[test_num] )
{
ts->printf( cvtest::TS::LOG, "Test error is out of range:\n"
{
if (!gtb)
return cvtest::TS::FAIL_GENERIC;
-
+
model_file_name1 = cv::tempfile();
model_file_name2 = cv::tempfile();
gtb->load(model_file_name1.c_str());
gtb->calc_error(data, CV_TEST_ERROR, &test_resps2);
gtb->save(model_file_name2.c_str());
-
+
return checkLoadSave();
-
+
}
// 1. compare files
ifstream f1( model_file_name1.c_str() ), f2( model_file_name2.c_str() );
string s1, s2;
- int lineIdx = 0;
+ int lineIdx = 0;
CV_Assert( f1.is_open() && f2.is_open() );
for( ; !f1.eof() && !f2.eof(); lineIdx++ )
{
void CV_GBTreesTest::run(int)
{
- string data_path = string(ts->get_data_path());
+ string dataPath = string(ts->get_data_path());
datasets = new string[2];
- datasets[0] = data_path + string("spambase.data"); /*string("dataset_classification.csv");*/
- datasets[1] = data_path + string("housing_.data"); /*string("dataset_regression.csv");*/
+ datasets[0] = dataPath + string("spambase.data"); /*string("dataset_classification.csv");*/
+ datasets[1] = dataPath + string("housing_.data"); /*string("dataset_regression.csv");*/
int code = cvtest::TS::OK;
for (int i = 0; i < 4; i++)
{
-
+
int temp_code = TestTrainPredict(i);
if (temp_code != cvtest::TS::OK)
{
code = temp_code;
break;
}
-
+
else if (i==0)
{
temp_code = TestSaveLoad();
delete data;
data = 0;
}
-
+
delete gtb;
gtb = 0;
}
delete data;
data = 0;
-
+
ts->set_failed_test_info( code );
}
/**********************************************************************************************\
Implementation of SIFT is based on the code from http://blogs.oregonstate.edu/hess/code/sift/
Below is the original copyright.
-
+
// Copyright (c) 2006-2010, Rob Hess <hess@eecs.oregonstate.edu>
// All rights reserved.
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\**********************************************************************************************/
-
+
#include "precomp.hpp"
#include <iostream>
#include <stdarg.h>
// factor used to convert floating-point descriptor to unsigned char
static const float SIFT_INT_DESCR_FCTR = 512.f;
-
+
static const int SIFT_FIXPT_SCALE = 48;
-
-
+
+
static Mat createInitialImage( const Mat& img, bool doubleImageSize, float sigma )
{
Mat gray, gray_fpt;
else
img.copyTo(gray);
gray.convertTo(gray_fpt, CV_16S, SIFT_FIXPT_SCALE, 0);
-
+
float sig_diff;
-
+
if( doubleImageSize )
{
sig_diff = sqrtf( std::max(sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA * 4, 0.01f) );
return gray_fpt;
}
}
-
-
+
+
void SIFT::buildGaussianPyramid( const Mat& base, vector<Mat>& pyr, int nOctaves ) const
{
vector<double> sig(nOctaveLayers + 3);
pyr.resize(nOctaves*(nOctaveLayers + 3));
-
+
// precompute Gaussian sigmas using the following formula:
// \sigma_{total}^2 = \sigma_{i}^2 + \sigma_{i-1}^2
sig[0] = sigma;
double sig_total = sig_prev*k;
sig[i] = std::sqrt(sig_total*sig_total - sig_prev*sig_prev);
}
-
+
for( int o = 0; o < nOctaves; o++ )
{
for( int i = 0; i < nOctaveLayers + 3; i++ )
{
int nOctaves = (int)gpyr.size()/(nOctaveLayers + 3);
dogpyr.resize( nOctaves*(nOctaveLayers + 2) );
-
+
for( int o = 0; o < nOctaves; o++ )
{
for( int i = 0; i < nOctaveLayers + 2; i++ )
}
}
-
+
// Computes a gradient orientation histogram at a specified pixel
static float calcOrientationHist( const Mat& img, Point pt, int radius,
float sigma, float* hist, int n )
{
int i, j, k, len = (radius*2+1)*(radius*2+1);
-
+
float expf_scale = -1.f/(2.f * sigma * sigma);
AutoBuffer<float> buf(len*4 + n+4);
float *X = buf, *Y = X + len, *Mag = X, *Ori = Y + len, *W = Ori + len;
float* temphist = W + len + 2;
-
+
for( i = 0; i < n; i++ )
temphist[i] = 0.f;
-
+
for( i = -radius, k = 0; i <= radius; i++ )
{
int y = pt.y + i;
int x = pt.x + j;
if( x <= 0 || x >= img.cols - 1 )
continue;
-
+
float dx = (float)(img.at<short>(y, x+1) - img.at<short>(y, x-1));
float dy = (float)(img.at<short>(y-1, x) - img.at<short>(y+1, x));
-
+
X[k] = dx; Y[k] = dy; W[k] = (i*i + j*j)*expf_scale;
k++;
}
}
-
+
len = k;
-
+
// compute gradient values, orientations and the weights over the pixel neighborhood
exp(W, W, len);
fastAtan2(Y, X, Ori, len, true);
magnitude(X, Y, Mag, len);
-
+
for( k = 0; k < len; k++ )
{
int bin = cvRound((n/360.f)*Ori[k]);
bin += n;
temphist[bin] += W[k]*Mag[k];
}
-
+
// smooth the histogram
temphist[-1] = temphist[n-1];
temphist[-2] = temphist[n-2];
(temphist[i-1] + temphist[i+1])*(4.f/16.f) +
temphist[i]*(6.f/16.f);
}
-
+
float maxval = hist[0];
for( i = 1; i < n; i++ )
maxval = std::max(maxval, hist[i]);
-
+
return maxval;
}
-
+
//
// Interpolates a scale-space extremum's location and scale to subpixel
// accuracy to form an image feature. Rejects features with low contrast.
-// Based on Section 4 of Lowe's paper.
+// Based on Section 4 of Lowe's paper.
static bool adjustLocalExtrema( const vector<Mat>& dog_pyr, KeyPoint& kpt, int octv,
int& layer, int& r, int& c, int nOctaveLayers,
float contrastThreshold, float edgeThreshold, float sigma )
const float deriv_scale = img_scale*0.5f;
const float second_deriv_scale = img_scale;
const float cross_deriv_scale = img_scale*0.25f;
-
+
float xi=0, xr=0, xc=0, contr;
int i = 0;
-
+
for( ; i < SIFT_MAX_INTERP_STEPS; i++ )
{
int idx = octv*(nOctaveLayers+2) + layer;
const Mat& img = dog_pyr[idx];
const Mat& prev = dog_pyr[idx-1];
const Mat& next = dog_pyr[idx+1];
-
+
Vec3f dD((img.at<short>(r, c+1) - img.at<short>(r, c-1))*deriv_scale,
(img.at<short>(r+1, c) - img.at<short>(r-1, c))*deriv_scale,
(next.at<short>(r, c) - prev.at<short>(r, c))*deriv_scale);
-
+
float v2 = (float)img.at<short>(r, c)*2;
float dxx = (img.at<short>(r, c+1) + img.at<short>(r, c-1) - v2)*second_deriv_scale;
float dyy = (img.at<short>(r+1, c) + img.at<short>(r-1, c) - v2)*second_deriv_scale;
prev.at<short>(r, c+1) + prev.at<short>(r, c-1))*cross_deriv_scale;
float dys = (next.at<short>(r+1, c) - next.at<short>(r-1, c) -
prev.at<short>(r+1, c) + prev.at<short>(r-1, c))*cross_deriv_scale;
-
+
Matx33f H(dxx, dxy, dxs,
dxy, dyy, dys,
dxs, dys, dss);
-
+
Vec3f X = H.solve(dD, DECOMP_LU);
-
+
xi = -X[2];
xr = -X[1];
xc = -X[0];
-
+
if( std::abs( xi ) < 0.5f && std::abs( xr ) < 0.5f && std::abs( xc ) < 0.5f )
break;
-
+
c += cvRound( xc );
r += cvRound( xr );
layer += cvRound( xi );
-
+
if( layer < 1 || layer > nOctaveLayers ||
c < SIFT_IMG_BORDER || c >= img.cols - SIFT_IMG_BORDER ||
r < SIFT_IMG_BORDER || r >= img.rows - SIFT_IMG_BORDER )
return false;
}
-
+
/* ensure convergence of interpolation */
if( i >= SIFT_MAX_INTERP_STEPS )
return false;
-
+
{
int idx = octv*(nOctaveLayers+2) + layer;
const Mat& img = dog_pyr[idx];
(img.at<short>(r+1, c) - img.at<short>(r-1, c))*deriv_scale,
(next.at<short>(r, c) - prev.at<short>(r, c))*deriv_scale);
float t = dD.dot(Matx31f(xc, xr, xi));
-
+
contr = img.at<short>(r, c)*img_scale + t * 0.5f;
if( std::abs( contr ) * nOctaveLayers < contrastThreshold )
return false;
-
+
/* principal curvatures are computed using the trace and det of Hessian */
float v2 = img.at<short>(r, c)*2.f;
float dxx = (img.at<short>(r, c+1) + img.at<short>(r, c-1) - v2)*second_deriv_scale;
img.at<short>(r-1, c+1) + img.at<short>(r-1, c-1)) * cross_deriv_scale;
float tr = dxx + dyy;
float det = dxx * dyy - dxy * dxy;
-
+
if( det <= 0 || tr*tr*edgeThreshold >= (edgeThreshold + 1)*(edgeThreshold + 1)*det )
return false;
}
-
+
kpt.pt.x = (c + xc) * (1 << octv);
kpt.pt.y = (r + xr) * (1 << octv);
kpt.octave = octv + (layer << 8) + (cvRound((xi + 0.5)*255) << 16);
kpt.size = sigma*powf(2.f, (layer + xi) / nOctaveLayers)*(1 << octv)*2;
-
+
return true;
}
-
-
+
+
//
// Detects features at extrema in DoG scale space. Bad features are discarded
// based on contrast and ratio of principal curvatures.
const int n = SIFT_ORI_HIST_BINS;
float hist[n];
KeyPoint kpt;
-
+
keypoints.clear();
-
+
for( int o = 0; o < nOctaves; o++ )
for( int i = 1; i <= nOctaveLayers; i++ )
{
const Mat& next = dog_pyr[idx+1];
int step = (int)img.step1();
int rows = img.rows, cols = img.cols;
-
+
for( int r = SIFT_IMG_BORDER; r < rows-SIFT_IMG_BORDER; r++)
{
const short* currptr = img.ptr<short>(r);
const short* prevptr = prev.ptr<short>(r);
const short* nextptr = next.ptr<short>(r);
-
+
for( int c = SIFT_IMG_BORDER; c < cols-SIFT_IMG_BORDER; c++)
{
int val = currptr[c];
-
+
// find local extrema with pixel accuracy
if( std::abs(val) > threshold &&
((val > 0 && val >= currptr[c-1] && val >= currptr[c+1] &&
for( int j = 0; j < n; j++ )
{
int l = j > 0 ? j - 1 : n - 1;
- int r = j < n-1 ? j + 1 : 0;
-
- if( hist[j] > hist[l] && hist[j] > hist[r] && hist[j] >= mag_thr )
+ int r2 = j < n-1 ? j + 1 : 0;
+
+ if( hist[j] > hist[l] && hist[j] > hist[r2] && hist[j] >= mag_thr )
{
- float bin = j + 0.5f * (hist[l]-hist[r]) / (hist[l] - 2*hist[j] + hist[r]);
+ float bin = j + 0.5f * (hist[l]-hist[r2]) / (hist[l] - 2*hist[j] + hist[r2]);
bin = bin < 0 ? n + bin : bin >= n ? bin - n : bin;
kpt.angle = (float)((360.f/n) * bin);
keypoints.push_back(kpt);
}
}
}
-}
-
-
+}
+
+
static void calcSIFTDescriptor( const Mat& img, Point2f ptf, float ori, float scl,
int d, int n, float* dst )
{
int radius = cvRound(hist_width * 1.4142135623730951f * (d + 1) * 0.5f);
cos_t /= hist_width;
sin_t /= hist_width;
-
+
int i, j, k, len = (radius*2+1)*(radius*2+1), histlen = (d+2)*(d+2)*(n+2);
int rows = img.rows, cols = img.cols;
-
+
AutoBuffer<float> buf(len*6 + histlen);
float *X = buf, *Y = X + len, *Mag = Y, *Ori = Mag + len, *W = Ori + len;
float *RBin = W + len, *CBin = RBin + len, *hist = CBin + len;
-
+
for( i = 0; i < d+2; i++ )
{
for( j = 0; j < d+2; j++ )
for( k = 0; k < n+2; k++ )
hist[(i*(d+2) + j)*(n+2) + k] = 0.;
}
-
+
for( i = -radius, k = 0; i <= radius; i++ )
for( j = -radius; j <= radius; j++ )
{
float rbin = r_rot + d/2 - 0.5f;
float cbin = c_rot + d/2 - 0.5f;
int r = pt.y + i, c = pt.x + j;
-
+
if( rbin > -1 && rbin < d && cbin > -1 && cbin < d &&
r > 0 && r < rows - 1 && c > 0 && c < cols - 1 )
{
k++;
}
}
-
+
len = k;
fastAtan2(Y, X, Ori, len, true);
magnitude(X, Y, Mag, len);
exp(W, W, len);
-
+
for( k = 0; k < len; k++ )
{
float rbin = RBin[k], cbin = CBin[k];
float obin = (Ori[k] - ori)*bins_per_rad;
float mag = Mag[k]*W[k];
-
+
int r0 = cvFloor( rbin );
int c0 = cvFloor( cbin );
int o0 = cvFloor( obin );
rbin -= r0;
cbin -= c0;
obin -= o0;
-
+
if( o0 < 0 )
o0 += n;
if( o0 >= n )
o0 -= n;
-
+
// histogram update using tri-linear interpolation
float v_r1 = mag*rbin, v_r0 = mag - v_r1;
float v_rc11 = v_r1*cbin, v_rc10 = v_r1 - v_rc11;
float v_rco101 = v_rc10*obin, v_rco100 = v_rc10 - v_rco101;
float v_rco011 = v_rc01*obin, v_rco010 = v_rc01 - v_rco011;
float v_rco001 = v_rc00*obin, v_rco000 = v_rc00 - v_rco001;
-
+
int idx = ((r0+1)*(d+2) + c0+1)*(n+2) + o0;
hist[idx] += v_rco000;
hist[idx+1] += v_rco001;
hist[idx+(d+3)*(n+2)] += v_rco110;
hist[idx+(d+3)*(n+2)+1] += v_rco111;
}
-
+
// finalize histogram, since the orientation histograms are circular
for( i = 0; i < d; i++ )
for( j = 0; j < d; j++ )
dst[k] = saturate_cast<uchar>(dst[k]*nrm2);
}
}
-
+
static void calcDescriptors(const vector<Mat>& gpyr, const vector<KeyPoint>& keypoints,
Mat& descriptors, int nOctaveLayers )
{
int d = SIFT_DESCR_WIDTH, n = SIFT_DESCR_HIST_BINS;
-
+
for( size_t i = 0; i < keypoints.size(); i++ )
{
KeyPoint kpt = keypoints[i];
float size=kpt.size*scale;
Point2f ptf(kpt.pt.x*scale, kpt.pt.y*scale);
const Mat& img = gpyr[octv*(nOctaveLayers + 3) + layer];
-
+
calcSIFTDescriptor(img, ptf, kpt.angle, size*0.5f, d, n, descriptors.ptr<float>((int)i));
}
}
bool useProvidedKeypoints) const
{
Mat image = _image.getMat(), mask = _mask.getMat();
-
+
if( image.empty() || image.depth() != CV_8U )
CV_Error( CV_StsBadArg, "image is empty or has incorrect depth (!=CV_8U)" );
-
+
if( !mask.empty() && mask.type() != CV_8UC1 )
CV_Error( CV_StsBadArg, "mask has incorrect type (!=CV_8UC1)" );
-
+
Mat base = createInitialImage(image, false, (float)sigma);
vector<Mat> gpyr, dogpyr;
int nOctaves = cvRound(log( (double)std::min( base.cols, base.rows ) ) / log(2.) - 2);
-
+
//double t, tf = getTickFrequency();
//t = (double)getTickCount();
buildGaussianPyramid(base, gpyr, nOctaves);
buildDoGPyramid(gpyr, dogpyr);
-
+
//t = (double)getTickCount() - t;
//printf("pyramid construction time: %g\n", t*1000./tf);
-
+
if( !useProvidedKeypoints )
{
//t = (double)getTickCount();
findScaleSpaceExtrema(gpyr, dogpyr, keypoints);
KeyPointsFilter::removeDuplicated( keypoints );
-
+
if( !mask.empty() )
KeyPointsFilter::runByPixelsMask( keypoints, mask );
-
+
if( nfeatures > 0 )
KeyPointsFilter::retainBest(keypoints, nfeatures);
//t = (double)getTickCount() - t;
// filter keypoints by mask
//KeyPointsFilter::runByPixelsMask( keypoints, mask );
}
-
+
if( _descriptors.needed() )
{
//t = (double)getTickCount();
int dsize = descriptorSize();
_descriptors.create((int)keypoints.size(), dsize, CV_32F);
Mat descriptors = _descriptors.getMat();
-
+
calcDescriptors(gpyr, keypoints, descriptors, nOctaveLayers);
//t = (double)getTickCount() - t;
//printf("descriptor extraction time: %g\n", t*1000./tf);
void SIFT::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask) const
{
(*this)(image, mask, keypoints, noArray());
-}
-
+}
+
void SIFT::computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const
{
(*this)(image, Mat(), keypoints, descriptors, true);
Ptr<CvMat> winbuf = cvCreateMat( 1, imaxSize*imaxSize, CV_8U );
for( k = k1; k < k2; k++ )
{
- int i, j, kk, x, y, nangle;
+ int i, j, kk, nangle;
float* vec;
SurfHF dx_t[NX], dy_t[NY];
KeyPoint& kp = (*keypoints)[k];
resizeHaarPattern( dy_s, dy_t, NY, 4, grad_wav_size, sum->cols );
for( kk = 0, nangle = 0; kk < nOriSamples; kk++ )
{
- x = cvRound( center.x + apt[kk].x*s - (float)(grad_wav_size-1)/2 );
- y = cvRound( center.y + apt[kk].y*s - (float)(grad_wav_size-1)/2 );
+ int x = cvRound( center.x + apt[kk].x*s - (float)(grad_wav_size-1)/2 );
+ int y = cvRound( center.y + apt[kk].y*s - (float)(grad_wav_size-1)/2 );
if( y < 0 || y >= sum->rows - grad_wav_size ||
x < 0 || x >= sum->cols - grad_wav_size )
continue;
int pixel_y = start_y;
for( j = 0; j < win_size; j++, pixel_y-- )
{
- x = MAX( pixel_x, 0 );
- y = MAX( pixel_y, 0 );
+ int x = MAX( pixel_x, 0 );
+ int y = MAX( pixel_y, 0 );
x = MIN( x, img->cols-1 );
y = MIN( y, img->rows-1 );
WIN[i*win_size + j] = img->at<uchar>(y, x);
for( i = 0; i < 4; i++ )
for( j = 0; j < 4; j++ )
{
- for( y = i*5; y < i*5+5; y++ )
+ for(int y = i*5; y < i*5+5; y++ )
{
- for( x = j*5; x < j*5+5; x++ )
+ for(int x = j*5; x < j*5+5; x++ )
{
float tx = DX[y][x], ty = DY[y][x];
if( ty >= 0 )
for( i = 0; i < 4; i++ )
for( j = 0; j < 4; j++ )
{
- for( y = i*5; y < i*5+5; y++ )
+ for(int y = i*5; y < i*5+5; y++ )
{
- for( x = j*5; x < j*5+5; x++ )
+ for(int x = j*5; x < j*5+5; x++ )
{
float tx = DX[y][x], ty = DY[y][x];
vec[0] += tx; vec[1] += ty;
int label; ///< Quantization
Feature() : x(0), y(0), label(0) {}
- Feature(int x, int y, int label) : x(x), y(y), label(label) {}
+ Feature(int x, int y, int label);
void read(const FileNode& fn);
void write(FileStorage& fs) const;
};
+inline Feature::Feature(int _x, int _y, int _label) : x(_x), y(_y), label(_label) {}
+
struct CV_EXPORTS Template
{
int width;
/// Candidate feature with a score
struct Candidate
{
- Candidate(int x, int y, int label, float score)
- : f(x, y, label), score(score)
- {
- }
+ Candidate(int x, int y, int label, float score);
/// Sort candidates with high score to the front
bool operator<(const Candidate& rhs) const
size_t num_features, float distance);
};
+inline QuantizedPyramid::Candidate::Candidate(int x, int y, int label, float _score) : f(x, y, label), score(_score) {}
+
/**
* \brief Interface for modalities that plug into the LINE template matching representation.
*
{
}
- Match(int x, int y, float similarity, const std::string& class_id, int template_id)
- : x(x), y(y), similarity(similarity), class_id(class_id), template_id(template_id)
- {
- }
+ Match(int x, int y, float similarity, const std::string& class_id, int template_id);
/// Sort matches with high similarity to the front
bool operator<(const Match& rhs) const
int template_id;
};
+inline Match::Match(int _x, int _y, float _similarity, const std::string& _class_id, int _template_id)
+ : x(_x), y(_y), similarity(_similarity), class_id(_class_id), template_id(_template_id)
+ {
+ }
+
/**
* \brief Object detector using the LINE template matching algorithm with any set of
* modalities.
namespace cv
{
-
+
// class for grouping object candidates, detected by Cascade Classifier, HOG etc.
// instance of the class is to be passed to cv::partition (see cxoperations.hpp)
class CV_EXPORTS SimilarRects
{
-public:
+public:
SimilarRects(double _eps) : eps(_eps) {}
inline bool operator()(const Rect& r1, const Rect& r2) const
{
std::abs(r1.y + r1.height - r2.y - r2.height) <= delta;
}
double eps;
-};
-
+};
+
void groupRectangles(vector<Rect>& rectList, int groupThreshold, double eps, vector<int>* weights, vector<double>* levelWeights)
{
}
return;
}
-
+
vector<int> labels;
int nclasses = partition(rectList, labels, SimilarRects(eps));
-
+
vector<Rect> rrects(nclasses);
vector<int> rweights(nclasses, 0);
- vector<int> rejectLevels(nclasses, 0);
+ vector<int> rejectLevels(nclasses, 0);
vector<double> rejectWeights(nclasses, DBL_MIN);
int i, j, nlabels = (int)labels.size();
for( i = 0; i < nlabels; i++ )
rweights[cls]++;
}
if ( levelWeights && weights && !weights->empty() && !levelWeights->empty() )
- {
- for( i = 0; i < nlabels; i++ )
- {
- int cls = labels[i];
+ {
+ for( i = 0; i < nlabels; i++ )
+ {
+ int cls = labels[i];
if( (*weights)[i] > rejectLevels[cls] )
{
rejectLevels[cls] = (*weights)[i];
}
else if( ( (*weights)[i] == rejectLevels[cls] ) && ( (*levelWeights)[i] > rejectWeights[cls] ) )
rejectWeights[cls] = (*levelWeights)[i];
- }
- }
-
+ }
+ }
+
for( i = 0; i < nclasses; i++ )
{
Rect r = rrects[i];
saturate_cast<int>(r.width*s),
saturate_cast<int>(r.height*s));
}
-
+
rectList.clear();
if( weights )
weights->clear();
- if( levelWeights )
- levelWeights->clear();
-
+ if( levelWeights )
+ levelWeights->clear();
+
for( i = 0; i < nclasses; i++ )
{
Rect r1 = rrects[i];
int n1 = levelWeights ? rejectLevels[i] : rweights[i];
- double w1 = rejectWeights[i];
+ double w1 = rejectWeights[i];
if( n1 <= groupThreshold )
continue;
// filter out small face rectangles inside large rectangles
for( j = 0; j < nclasses; j++ )
{
int n2 = rweights[j];
-
+
if( j == i || n2 <= groupThreshold )
continue;
Rect r2 = rrects[j];
-
+
int dx = saturate_cast<int>( r2.width * eps );
int dy = saturate_cast<int>( r2.height * eps );
-
+
if( i != j &&
r1.x >= r2.x - dx &&
r1.y >= r2.y - dy &&
(n2 > std::max(3, n1) || n1 < 3) )
break;
}
-
+
if( j == nclasses )
{
rectList.push_back(r1);
if( weights )
weights->push_back(n1);
- if( levelWeights )
- levelWeights->push_back(w1);
+ if( levelWeights )
+ levelWeights->push_back(w1);
}
}
}
class MeanshiftGrouping
{
public:
- MeanshiftGrouping(const Point3d& densKer, const vector<Point3d>& posV,
- const vector<double>& wV, double, int maxIter = 20)
+ MeanshiftGrouping(const Point3d& densKer, const vector<Point3d>& posV,
+ const vector<double>& wV, double, int maxIter = 20)
{
- densityKernel = densKer;
+ densityKernel = densKer;
weightsV = wV;
positionsV = posV;
positionsCount = (int)posV.size();
- meanshiftV.resize(positionsCount);
+ meanshiftV.resize(positionsCount);
distanceV.resize(positionsCount);
- iterMax = maxIter;
-
- for (unsigned i = 0; i<positionsV.size(); i++)
- {
- meanshiftV[i] = getNewValue(positionsV[i]);
- distanceV[i] = moveToMode(meanshiftV[i]);
- meanshiftV[i] -= positionsV[i];
- }
+ iterMax = maxIter;
+
+ for (unsigned i = 0; i<positionsV.size(); i++)
+ {
+ meanshiftV[i] = getNewValue(positionsV[i]);
+ distanceV[i] = moveToMode(meanshiftV[i]);
+ meanshiftV[i] -= positionsV[i];
+ }
}
-
- void getModes(vector<Point3d>& modesV, vector<double>& resWeightsV, const double eps)
+
+ void getModes(vector<Point3d>& modesV, vector<double>& resWeightsV, const double eps)
{
- for (size_t i=0; i <distanceV.size(); i++)
- {
- bool is_found = false;
- for(size_t j=0; j<modesV.size(); j++)
- {
- if ( getDistance(distanceV[i], modesV[j]) < eps)
- {
- is_found=true;
- break;
- }
- }
- if (!is_found)
- {
- modesV.push_back(distanceV[i]);
- }
- }
-
- resWeightsV.resize(modesV.size());
-
- for (size_t i=0; i<modesV.size(); i++)
- {
- resWeightsV[i] = getResultWeight(modesV[i]);
- }
+ for (size_t i=0; i <distanceV.size(); i++)
+ {
+ bool is_found = false;
+ for(size_t j=0; j<modesV.size(); j++)
+ {
+ if ( getDistance(distanceV[i], modesV[j]) < eps)
+ {
+ is_found=true;
+ break;
+ }
+ }
+ if (!is_found)
+ {
+ modesV.push_back(distanceV[i]);
+ }
+ }
+
+ resWeightsV.resize(modesV.size());
+
+ for (size_t i=0; i<modesV.size(); i++)
+ {
+ resWeightsV[i] = getResultWeight(modesV[i]);
+ }
}
protected:
- vector<Point3d> positionsV;
- vector<double> weightsV;
+ vector<Point3d> positionsV;
+ vector<double> weightsV;
- Point3d densityKernel;
- int positionsCount;
+ Point3d densityKernel;
+ int positionsCount;
- vector<Point3d> meanshiftV;
- vector<Point3d> distanceV;
- int iterMax;
- double modeEps;
+ vector<Point3d> meanshiftV;
+ vector<Point3d> distanceV;
+ int iterMax;
+ double modeEps;
- Point3d getNewValue(const Point3d& inPt) const
+ Point3d getNewValue(const Point3d& inPt) const
{
- Point3d resPoint(.0);
- Point3d ratPoint(.0);
- for (size_t i=0; i<positionsV.size(); i++)
- {
- Point3d aPt= positionsV[i];
- Point3d bPt = inPt;
- Point3d sPt = densityKernel;
-
- sPt.x *= exp(aPt.z);
- sPt.y *= exp(aPt.z);
-
- aPt.x /= sPt.x;
- aPt.y /= sPt.y;
- aPt.z /= sPt.z;
-
- bPt.x /= sPt.x;
- bPt.y /= sPt.y;
- bPt.z /= sPt.z;
-
- double w = (weightsV[i])*std::exp(-((aPt-bPt).dot(aPt-bPt))/2)/std::sqrt(sPt.dot(Point3d(1,1,1)));
-
- resPoint += w*aPt;
-
- ratPoint.x += w/sPt.x;
- ratPoint.y += w/sPt.y;
- ratPoint.z += w/sPt.z;
- }
- resPoint.x /= ratPoint.x;
- resPoint.y /= ratPoint.y;
- resPoint.z /= ratPoint.z;
- return resPoint;
+ Point3d resPoint(.0);
+ Point3d ratPoint(.0);
+ for (size_t i=0; i<positionsV.size(); i++)
+ {
+ Point3d aPt= positionsV[i];
+ Point3d bPt = inPt;
+ Point3d sPt = densityKernel;
+
+ sPt.x *= exp(aPt.z);
+ sPt.y *= exp(aPt.z);
+
+ aPt.x /= sPt.x;
+ aPt.y /= sPt.y;
+ aPt.z /= sPt.z;
+
+ bPt.x /= sPt.x;
+ bPt.y /= sPt.y;
+ bPt.z /= sPt.z;
+
+ double w = (weightsV[i])*std::exp(-((aPt-bPt).dot(aPt-bPt))/2)/std::sqrt(sPt.dot(Point3d(1,1,1)));
+
+ resPoint += w*aPt;
+
+ ratPoint.x += w/sPt.x;
+ ratPoint.y += w/sPt.y;
+ ratPoint.z += w/sPt.z;
+ }
+ resPoint.x /= ratPoint.x;
+ resPoint.y /= ratPoint.y;
+ resPoint.z /= ratPoint.z;
+ return resPoint;
}
- double getResultWeight(const Point3d& inPt) const
+ double getResultWeight(const Point3d& inPt) const
{
- double sumW=0;
- for (size_t i=0; i<positionsV.size(); i++)
- {
- Point3d aPt = positionsV[i];
- Point3d sPt = densityKernel;
-
- sPt.x *= exp(aPt.z);
- sPt.y *= exp(aPt.z);
-
- aPt -= inPt;
-
- aPt.x /= sPt.x;
- aPt.y /= sPt.y;
- aPt.z /= sPt.z;
-
- sumW+=(weightsV[i])*std::exp(-(aPt.dot(aPt))/2)/std::sqrt(sPt.dot(Point3d(1,1,1)));
- }
- return sumW;
+ double sumW=0;
+ for (size_t i=0; i<positionsV.size(); i++)
+ {
+ Point3d aPt = positionsV[i];
+ Point3d sPt = densityKernel;
+
+ sPt.x *= exp(aPt.z);
+ sPt.y *= exp(aPt.z);
+
+ aPt -= inPt;
+
+ aPt.x /= sPt.x;
+ aPt.y /= sPt.y;
+ aPt.z /= sPt.z;
+
+ sumW+=(weightsV[i])*std::exp(-(aPt.dot(aPt))/2)/std::sqrt(sPt.dot(Point3d(1,1,1)));
+ }
+ return sumW;
}
-
- Point3d moveToMode(Point3d aPt) const
+
+ Point3d moveToMode(Point3d aPt) const
{
- Point3d bPt;
- for (int i = 0; i<iterMax; i++)
- {
- bPt = aPt;
- aPt = getNewValue(bPt);
- if ( getDistance(aPt, bPt) <= modeEps )
- {
- break;
- }
- }
- return aPt;
+ Point3d bPt;
+ for (int i = 0; i<iterMax; i++)
+ {
+ bPt = aPt;
+ aPt = getNewValue(bPt);
+ if ( getDistance(aPt, bPt) <= modeEps )
+ {
+ break;
+ }
+ }
+ return aPt;
}
double getDistance(Point3d p1, Point3d p2) const
{
- Point3d ns = densityKernel;
- ns.x *= exp(p2.z);
- ns.y *= exp(p2.z);
- p2 -= p1;
- p2.x /= ns.x;
- p2.y /= ns.y;
- p2.z /= ns.z;
- return p2.dot(p2);
+ Point3d ns = densityKernel;
+ ns.x *= exp(p2.z);
+ ns.y *= exp(p2.z);
+ p2 -= p1;
+ p2.x /= ns.x;
+ p2.y /= ns.y;
+ p2.z /= ns.z;
+ return p2.dot(p2);
}
};
//new grouping function with using meanshift
-static void groupRectangles_meanshift(vector<Rect>& rectList, double detectThreshold, vector<double>* foundWeights,
- vector<double>& scales, Size winDetSize)
+static void groupRectangles_meanshift(vector<Rect>& rectList, double detectThreshold, vector<double>* foundWeights,
+ vector<double>& scales, Size winDetSize)
{
int detectionCount = (int)rectList.size();
vector<Point3d> hits(detectionCount), resultHits;
vector<double> hitWeights(detectionCount), resultWeights;
Point2d hitCenter;
- for (int i=0; i < detectionCount; i++)
+ for (int i=0; i < detectionCount; i++)
{
hitWeights[i] = (*foundWeights)[i];
hitCenter = (rectList[i].tl() + rectList[i].br())*(0.5); //center of rectangles
msGrouping.getModes(resultHits, resultWeights, 1);
- for (unsigned i=0; i < resultHits.size(); ++i)
+ for (unsigned i=0; i < resultHits.size(); ++i)
{
double scale = exp(resultHits[i].z);
hitCenter.x = resultHits[i].x;
hitCenter.y = resultHits[i].y;
Size s( int(winDetSize.width * scale), int(winDetSize.height * scale) );
- Rect resultRect( int(hitCenter.x-s.width/2), int(hitCenter.y-s.height/2),
- int(s.width), int(s.height) );
+ Rect resultRect( int(hitCenter.x-s.width/2), int(hitCenter.y-s.height/2),
+ int(s.width), int(s.height) );
- if (resultWeights[i] > detectThreshold)
+ if (resultWeights[i] > detectThreshold)
{
rectList.push_back(resultRect);
foundWeights->push_back(resultWeights[i]);
groupRectangles(rectList, groupThreshold, eps, &rejectLevels, &levelWeights);
}
//can be used for HOG detection algorithm only
-void groupRectangles_meanshift(vector<Rect>& rectList, vector<double>& foundWeights,
- vector<double>& foundScales, double detectThreshold, Size winDetSize)
+void groupRectangles_meanshift(vector<Rect>& rectList, vector<double>& foundWeights,
+ vector<double>& foundScales, double detectThreshold, Size winDetSize)
{
- groupRectangles_meanshift(rectList, detectThreshold, &foundWeights, foundScales, winDetSize);
+ groupRectangles_meanshift(rectList, detectThreshold, &foundWeights, foundScales, winDetSize);
}
-
+
FeatureEvaluator::~FeatureEvaluator() {}
bool FeatureEvaluator::read(const FileNode&) {return true;}
{
FileNode rnode = node[CC_RECTS];
FileNodeIterator it = rnode.begin(), it_end = rnode.end();
-
+
int ri;
for( ri = 0; ri < RECT_NUM; ri++ )
{
rect[ri].r = Rect();
rect[ri].weight = 0.f;
}
-
+
for(ri = 0; it != it_end; ++it, ri++)
{
FileNodeIterator it2 = (*it).begin();
it2 >> rect[ri].r.x >> rect[ri].r.y >>
rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight;
}
-
+
tilted = (int)node[CC_TILTED] != 0;
return true;
}
featuresPtr = &(*features)[0];
FileNodeIterator it = node.begin(), it_end = node.end();
hasTiltedFeatures = false;
-
+
for(int i = 0; it != it_end; ++it, i++)
{
if(!featuresPtr[i].read(*it))
}
return true;
}
-
+
Ptr<FeatureEvaluator> HaarEvaluator::clone() const
{
HaarEvaluator* ret = new HaarEvaluator;
memcpy( ret->p, p, 4*sizeof(p[0]) );
memcpy( ret->pq, pq, 4*sizeof(pq[0]) );
ret->offset = offset;
- ret->varianceNormFactor = varianceNormFactor;
+ ret->varianceNormFactor = varianceNormFactor;
return ret;
}
int rn = image.rows+1, cn = image.cols+1;
origWinSize = _origWinSize;
normrect = Rect(1, 1, origWinSize.width-2, origWinSize.height-2);
-
+
if (image.cols < origWinSize.width || image.rows < origWinSize.height)
return false;
-
+
if( sum0.rows < rn || sum0.cols < cn )
{
sum0.create(rn, cn, CV_32S);
const double* sqdata = (const double*)sqsum.data;
size_t sumStep = sum.step/sizeof(sdata[0]);
size_t sqsumStep = sqsum.step/sizeof(sqdata[0]);
-
+
CV_SUM_PTRS( p[0], p[1], p[2], p[3], sdata, normrect, sumStep );
CV_SUM_PTRS( pq[0], pq[1], pq[2], pq[3], sqdata, normrect, sqsumStep );
-
+
size_t fi, nfeatures = features->size();
for( fi = 0; fi < nfeatures; fi++ )
if( image.cols < origWinSize.width || image.rows < origWinSize.height )
return false;
-
+
if( sum0.rows < rn || sum0.cols < cn )
sum0.create(rn, cn, CV_32S);
sum = Mat(rn, cn, CV_32S, sum0.data);
integral(image, sum);
-
+
size_t fi, nfeatures = features->size();
-
+
for( fi = 0; fi < nfeatures; fi++ )
featuresPtr[fi].updatePtrs( sum );
return true;
}
-
+
bool LBPEvaluator::setWindow( Point pt )
{
if( pt.x < 0 || pt.y < 0 ||
return false;
offset = pt.y * ((int)sum.step/sizeof(int)) + pt.x;
return true;
-}
+}
//---------------------------------------------- HOGEvaluator ---------------------------------------
bool HOGEvaluator::Feature :: read( const FileNode& node )
ret->featuresPtr = &(*ret->features)[0];
ret->offset = offset;
ret->hist = hist;
- ret->normSum = normSum;
+ ret->normSum = normSum;
return ret;
}
memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) );
histBuf += histStep + 1;
for( y = 0; y < qangle.rows; y++ )
- {
+ {
histBuf[-1] = 0.f;
float strSum = 0.f;
for( x = 0; x < qangle.cols; x++ )
Ptr<FeatureEvaluator> FeatureEvaluator::create( int featureType )
{
return featureType == HAAR ? Ptr<FeatureEvaluator>(new HaarEvaluator) :
- featureType == LBP ? Ptr<FeatureEvaluator>(new LBPEvaluator) :
+ featureType == LBP ? Ptr<FeatureEvaluator>(new LBPEvaluator) :
featureType == HOG ? Ptr<FeatureEvaluator>(new HOGEvaluator) :
Ptr<FeatureEvaluator>();
}
}
CascadeClassifier::CascadeClassifier(const string& filename)
-{
- load(filename);
+{
+ load(filename);
}
CascadeClassifier::~CascadeClassifier()
{
-}
+}
bool CascadeClassifier::empty() const
{
oldCascade.release();
data = Data();
featureEvaluator.release();
-
+
FileStorage fs(filename, FileStorage::READ);
if( !fs.isOpened() )
return false;
-
+
if( read(fs.getFirstTopLevelNode()) )
return true;
-
+
fs.release();
-
+
oldCascade = Ptr<CvHaarClassifierCascade>((CvHaarClassifierCascade*)cvLoad(filename.c_str(), 0, 0, 0));
return !oldCascade.empty();
}
-
-int CascadeClassifier::runAt( Ptr<FeatureEvaluator>& featureEvaluator, Point pt, double& weight )
+
+int CascadeClassifier::runAt( Ptr<FeatureEvaluator>& evaluator, Point pt, double& weight )
{
CV_Assert( oldCascade.empty() );
-
+
assert( data.featureType == FeatureEvaluator::HAAR ||
data.featureType == FeatureEvaluator::LBP ||
data.featureType == FeatureEvaluator::HOG );
- if( !featureEvaluator->setWindow(pt) )
+ if( !evaluator->setWindow(pt) )
return -1;
if( data.isStumpBased )
{
if( data.featureType == FeatureEvaluator::HAAR )
- return predictOrderedStump<HaarEvaluator>( *this, featureEvaluator, weight );
+ return predictOrderedStump<HaarEvaluator>( *this, evaluator, weight );
else if( data.featureType == FeatureEvaluator::LBP )
- return predictCategoricalStump<LBPEvaluator>( *this, featureEvaluator, weight );
+ return predictCategoricalStump<LBPEvaluator>( *this, evaluator, weight );
else if( data.featureType == FeatureEvaluator::HOG )
- return predictOrderedStump<HOGEvaluator>( *this, featureEvaluator, weight );
+ return predictOrderedStump<HOGEvaluator>( *this, evaluator, weight );
else
return -2;
}
else
{
if( data.featureType == FeatureEvaluator::HAAR )
- return predictOrdered<HaarEvaluator>( *this, featureEvaluator, weight );
+ return predictOrdered<HaarEvaluator>( *this, evaluator, weight );
else if( data.featureType == FeatureEvaluator::LBP )
- return predictCategorical<LBPEvaluator>( *this, featureEvaluator, weight );
+ return predictCategorical<LBPEvaluator>( *this, evaluator, weight );
else if( data.featureType == FeatureEvaluator::HOG )
- return predictOrdered<HOGEvaluator>( *this, featureEvaluator, weight );
+ return predictOrdered<HOGEvaluator>( *this, evaluator, weight );
else
return -2;
}
}
-
-bool CascadeClassifier::setImage( Ptr<FeatureEvaluator>& featureEvaluator, const Mat& image )
+
+bool CascadeClassifier::setImage( Ptr<FeatureEvaluator>& evaluator, const Mat& image )
{
- return empty() ? false : featureEvaluator->setImage(image, data.origWinSize);
+ return empty() ? false : evaluator->setImage(image, data.origWinSize);
}
void CascadeClassifier::setMaskGenerator(Ptr<MaskGenerator> _maskGenerator)
struct CascadeClassifierInvoker
{
- CascadeClassifierInvoker( CascadeClassifier& _cc, Size _sz1, int _stripSize, int _yStep, double _factor,
+ CascadeClassifierInvoker( CascadeClassifier& _cc, Size _sz1, int _stripSize, int _yStep, double _factor,
ConcurrentRectVector& _vec, vector<int>& _levels, vector<double>& _weights, bool outputLevels, const Mat& _mask)
{
classifier = &_cc;
levelWeights = outputLevels ? &_weights : 0;
mask=_mask;
}
-
+
void operator()(const BlockedRange& range) const
{
Ptr<FeatureEvaluator> evaluator = classifier->featureEvaluator->clone();
result = -(int)classifier->data.stages.size();
if( classifier->data.stages.size() + result < 4 )
{
- rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor), winSize.width, winSize.height));
+ rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor), winSize.width, winSize.height));
rejectLevels->push_back(-result);
levelWeights->push_back(gypWeight);
}
- }
+ }
else if( result > 0 )
rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor),
winSize.width, winSize.height));
}
}
}
-
+
CascadeClassifier* classifier;
ConcurrentRectVector* rectangles;
Size processingRectSize;
vector<double> *levelWeights;
Mat mask;
};
-
+
struct getRect { Rect operator ()(const CvAvgComp& e) const { return e.rect; } };
bool CascadeClassifier::detectSingleScale( const Mat& image, int stripCount, Size processingRectSize,
return featureEvaluator->setImage(image, data.origWinSize);
}
-void CascadeClassifier::detectMultiScale( const Mat& image, vector<Rect>& objects,
+void CascadeClassifier::detectMultiScale( const Mat& image, vector<Rect>& objects,
vector<int>& rejectLevels,
vector<double>& levelWeights,
double scaleFactor, int minNeighbors,
- int flags, Size minObjectSize, Size maxObjectSize,
+ int flags, Size minObjectSize, Size maxObjectSize,
bool outputRejectLevels )
{
const double GROUP_EPS = 0.2;
-
+
CV_Assert( scaleFactor > 1 && image.depth() == CV_8U );
-
+
if( empty() )
return;
if( maxObjectSize.height == 0 || maxObjectSize.width == 0 )
maxObjectSize = image.size();
-
+
Mat grayImage = image;
if( grayImage.channels() > 1 )
{
cvtColor(grayImage, temp, CV_BGR2GRAY);
grayImage = temp;
}
-
+
Mat imageBuffer(image.rows + 1, image.cols + 1, CV_8U);
vector<Rect> candidates;
Size windowSize( cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) );
Size scaledImageSize( cvRound( grayImage.cols/factor ), cvRound( grayImage.rows/factor ) );
Size processingRectSize( scaledImageSize.width - originalWindowSize.width + 1, scaledImageSize.height - originalWindowSize.height + 1 );
-
+
if( processingRectSize.width <= 0 || processingRectSize.height <= 0 )
break;
if( windowSize.width > maxObjectSize.width || windowSize.height > maxObjectSize.height )
break;
if( windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height )
continue;
-
+
Mat scaledImage( scaledImageSize, CV_8U, imageBuffer.data );
resize( grayImage, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR );
stripSize = processingRectSize.height;
#endif
- if( !detectSingleScale( scaledImage, stripCount, processingRectSize, stripSize, yStep, factor, candidates,
+ if( !detectSingleScale( scaledImage, stripCount, processingRectSize, stripSize, yStep, factor, candidates,
rejectLevels, levelWeights, outputRejectLevels ) )
break;
}
-
+
objects.resize(candidates.size());
std::copy(candidates.begin(), candidates.end(), objects.begin());
{
vector<int> fakeLevels;
vector<double> fakeWeights;
- detectMultiScale( image, objects, fakeLevels, fakeWeights, scaleFactor,
+ detectMultiScale( image, objects, fakeLevels, fakeWeights, scaleFactor,
minNeighbors, flags, minObjectSize, maxObjectSize, false );
-}
+}
bool CascadeClassifier::Data::read(const FileNode &root)
{
static const float THRESHOLD_EPS = 1e-5f;
-
+
// load stage params
string stageTypeStr = (string)root[CC_STAGE_TYPE];
if( stageTypeStr == CC_BOOST )
FileNode fn = root[CC_FEATURES];
if( fn.empty() )
return false;
-
+
return featureEvaluator->read(fn);
}
-
+
template<> void Ptr<CvHaarClassifierCascade>::delete_obj()
-{ cvReleaseHaarClassifierCascade(&obj); }
+{ cvReleaseHaarClassifierCascade(&obj); }
} // namespace cv
{
uchar binary[8] = {0,0,0,0,0,0,0,0};
uchar b = 0;
- int i, sum;
+ int sum;
sum = 0;
- for (i = 0; i < 64; i++)
+ for (int i = 0; i < 64; i++)
sum += sa.getpixel(1 + (i & 7), 1 + (i >> 3));
uchar mean = (uchar)(sum / 64);
- for (i = 0; i < 64; i++) {
+ for (int i = 0; i < 64; i++) {
b = (b << 1) + (sa.getpixel(pickup[i].x, pickup[i].y) <= mean);
if ((i & 7) == 7) {
binary[i >> 3] = b;
uchar c[5] = {0,0,0,0,0};
{
- int i, j;
uchar a[5] = {228, 48, 15, 111, 62};
int k = 5;
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
uchar t = binary[i] ^ c[4];
- for (j = k - 1; j != -1; j--) {
+ for (int j = k - 1; j != -1; j--) {
if (t == 0)
c[j] = 0;
else
deque <CvPoint> candidates;
{
int x, y;
- int r = cxy->rows;
- int c = cxy->cols;
- for (y = 0; y < r; y++) {
+ int rows = cxy->rows;
+ int cols = cxy->cols;
+ for (y = 0; y < rows; y++) {
const short *cd = (const short*)cvPtr2D(cxy, y, 0);
const short *ccd = (const short*)cvPtr2D(ccxy, y, 0);
- for (x = 0; x < c; x += 4, cd += 8, ccd += 8) {
+ for (x = 0; x < cols; x += 4, cd += 8, ccd += 8) {
__m128i v = _mm_loadu_si128((const __m128i*)cd);
__m128 cyxyxA = _mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(v, v), 16));
__m128 cyxyxB = _mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpackhi_epi16(v, v), 16));
namespace cv
{
-
+
void findDataMatrix(InputArray _image,
vector<string>& codes,
OutputArray _corners,
deque <CvDataMatrixCode> rc = cvFindDataMatrix(&m);
int i, n = (int)rc.size();
Mat corners;
-
+
if( _corners.needed() )
{
_corners.create(n, 4, CV_32SC2);
corners = _corners.getMat();
}
-
+
if( _dmtx.needed() )
_dmtx.create(n, 1, CV_8U);
-
+
codes.resize(n);
-
+
for( i = 0; i < n; i++ )
{
CvDataMatrixCode& rc_i = rc[i];
codes[i] = string(rc_i.msg);
-
+
if( corners.data )
{
const Point* srcpt = (Point*)rc_i.corners->data.ptr;
dstpt[k] = srcpt[k];
}
cvReleaseMat(&rc_i.corners);
-
+
if( _dmtx.needed() )
{
_dmtx.create(rc_i.original->rows, rc_i.original->cols, rc_i.original->type, i);
Mat image = _image.getMat();
Mat corners = _corners.getMat();
int i, n = corners.rows;
-
+
if( n > 0 )
{
CV_Assert( corners.depth() == CV_32S &&
corners.cols*corners.channels() == 8 &&
n == (int)codes.size() );
}
-
+
for( i = 0; i < n; i++ )
{
Scalar c(0, 255, 0);
Scalar c2(255, 0,0);
const Point* pt = (const Point*)corners.ptr(i);
-
+
for( int k = 0; k < 4; k++ )
line(image, pt[k], pt[(k+1)%4], c);
//int baseline = 0;
putText(image, codes[i], pt[0], CV_FONT_HERSHEY_SIMPLEX, 0.8, c2, 1, CV_AA, false);
}
}
-
+
}
Size blockSize = descriptor->blockSize;
Size blockStride = descriptor->blockStride;
Size cellSize = descriptor->cellSize;
- Size winSize = descriptor->winSize;
int i, j, nbins = descriptor->nbins;
int rawBlockSize = blockSize.width*blockSize.height;
(winSize.height/cacheStride.height)+1);
blockCache.create(cacheSize.height, cacheSize.width*blockHistogramSize);
blockCacheFlags.create(cacheSize);
- size_t i, cacheRows = blockCache.rows;
+ size_t cacheRows = blockCache.rows;
ymaxCached.resize(cacheRows);
- for( i = 0; i < cacheRows; i++ )
- ymaxCached[i] = -1;
+ for(size_t ii = 0; ii < cacheRows; ii++ )
+ ymaxCached[ii] = -1;
}
Mat_<float> weights(blockSize);
float strong_threshold;
};
-ColorGradientPyramid::ColorGradientPyramid(const Mat& src, const Mat& mask,
- float weak_threshold, size_t num_features,
- float strong_threshold)
- : src(src),
- mask(mask),
+ColorGradientPyramid::ColorGradientPyramid(const Mat& _src, const Mat& _mask,
+ float _weak_threshold, size_t _num_features,
+ float _strong_threshold)
+ : src(_src),
+ mask(_mask),
pyramid_level(0),
- weak_threshold(weak_threshold),
- num_features(num_features),
- strong_threshold(strong_threshold)
+ weak_threshold(_weak_threshold),
+ num_features(_num_features),
+ strong_threshold(_strong_threshold)
{
update();
}
{
}
-ColorGradient::ColorGradient(float weak_threshold, size_t num_features, float strong_threshold)
- : weak_threshold(weak_threshold),
- num_features(num_features),
- strong_threshold(strong_threshold)
+ColorGradient::ColorGradient(float _weak_threshold, size_t _num_features, float _strong_threshold)
+ : weak_threshold(_weak_threshold),
+ num_features(_num_features),
+ strong_threshold(_strong_threshold)
{
}
int extract_threshold;
};
-DepthNormalPyramid::DepthNormalPyramid(const Mat& src, const Mat& mask,
- int distance_threshold, int difference_threshold, size_t num_features,
- int extract_threshold)
- : mask(mask),
+DepthNormalPyramid::DepthNormalPyramid(const Mat& src, const Mat& _mask,
+ int distance_threshold, int difference_threshold, size_t _num_features,
+ int _extract_threshold)
+ : mask(_mask),
pyramid_level(0),
- num_features(num_features),
- extract_threshold(extract_threshold)
+ num_features(_num_features),
+ extract_threshold(_extract_threshold)
{
quantizedNormals(src, normal, distance_threshold, difference_threshold);
}
{
}
-DepthNormal::DepthNormal(int distance_threshold, int difference_threshold, size_t num_features,
- int extract_threshold)
- : distance_threshold(distance_threshold),
- difference_threshold(difference_threshold),
- num_features(num_features),
- extract_threshold(extract_threshold)
+DepthNormal::DepthNormal(int _distance_threshold, int _difference_threshold, size_t _num_features,
+ int _extract_threshold)
+ : distance_threshold(_distance_threshold),
+ difference_threshold(_difference_threshold),
+ num_features(_num_features),
+ extract_threshold(_extract_threshold)
{
}
{
}
-Detector::Detector(const std::vector< Ptr<Modality> >& modalities,
+Detector::Detector(const std::vector< Ptr<Modality> >& _modalities,
const std::vector<int>& T_pyramid)
- : modalities(modalities),
+ : modalities(_modalities),
pyramid_levels(static_cast<int>(T_pyramid.size())),
T_at_level(T_pyramid)
{
// Used to filter out weak matches
struct MatchPredicate
{
- MatchPredicate(float threshold) : threshold(threshold) {}
+ MatchPredicate(float _threshold) : threshold(_threshold) {}
bool operator() (const Match& m) { return m.similarity < threshold; }
float threshold;
};
int max_x = size.width - tp[start].width - border;
int max_y = size.height - tp[start].height - border;
- std::vector<Mat> similarities(modalities.size());
- Mat total_similarity;
+ std::vector<Mat> similarities2(modalities.size());
+ Mat total_similarity2;
for (int m = 0; m < (int)candidates.size(); ++m)
{
- Match& match = candidates[m];
- int x = match.x * 2 + 1; /// @todo Support other pyramid distance
- int y = match.y * 2 + 1;
+ Match& match2 = candidates[m];
+ int x = match2.x * 2 + 1; /// @todo Support other pyramid distance
+ int y = match2.y * 2 + 1;
// Require 8 (reduced) row/cols to the up/left
x = std::max(x, border);
y = std::min(y, max_y);
// Compute local similarity maps for each modality
- int num_features = 0;
+ int numFeatures = 0;
for (int i = 0; i < (int)modalities.size(); ++i)
{
const Template& templ = tp[start + i];
- num_features += static_cast<int>(templ.features.size());
- similarityLocal(lms[i], templ, similarities[i], size, T, Point(x, y));
+ numFeatures += static_cast<int>(templ.features.size());
+ similarityLocal(lms[i], templ, similarities2[i], size, T, Point(x, y));
}
- addSimilarities(similarities, total_similarity);
+ addSimilarities(similarities2, total_similarity2);
// Find best local adjustment
int best_score = 0;
int best_r = -1, best_c = -1;
- for (int r = 0; r < total_similarity.rows; ++r)
+ for (int r = 0; r < total_similarity2.rows; ++r)
{
- ushort* row = total_similarity.ptr<ushort>(r);
- for (int c = 0; c < total_similarity.cols; ++c)
+ ushort* row = total_similarity2.ptr<ushort>(r);
+ for (int c = 0; c < total_similarity2.cols; ++c)
{
int score = row[c];
if (score > best_score)
}
}
// Update current match
- match.x = (x / T - 8 + best_c) * T + offset;
- match.y = (y / T - 8 + best_r) * T + offset;
- match.similarity = (best_score * 100.f) / (4 * num_features);
+ match2.x = (x / T - 8 + best_c) * T + offset;
+ match2.y = (y / T - 8 + best_r) * T + offset;
+ match2.similarity = (best_score * 100.f) / (4 * numFeatures);
}
// Filter out any matches that drop below the similarity threshold
tps[template_id].resize(templates_fn.size());
FileNodeIterator templ_it = templates_fn.begin(), templ_it_end = templates_fn.end();
- int i = 0;
+ int idx = 0;
for ( ; templ_it != templ_it_end; ++templ_it)
{
- tps[template_id][i++].read(*templ_it);
+ tps[template_id][idx++].read(*templ_it);
}
}
//#define TOTAL_NO_PAIR_E "totalNoPairE"
#define DETECTOR_NAMES "detector_names"
-#define DETECTORS "detectors"
+#define DETECTORS "detectors"
#define IMAGE_FILENAMES "image_filenames"
#define VALIDATION "validation"
-#define FILENAME "fn"
+#define FILENAME "fn"
-#define C_SCALE_CASCADE "scale_cascade"
+#define C_SCALE_CASCADE "scale_cascade"
class CV_DetectorTest : public cvtest::BaseTest
{
virtual int prepareData( FileStorage& fs );
virtual void run( int startFrom );
virtual string& getValidationFilename();
-
- virtual void readDetector( const FileNode& fn ) = 0;
- virtual void writeDetector( FileStorage& fs, int di ) = 0;
+
+ virtual void readDetector( const FileNode& fn ) = 0;
+ virtual void writeDetector( FileStorage& fs, int di ) = 0;
int runTestCase( int detectorIdx, vector<vector<Rect> >& objects );
virtual int detectMultiScale( int di, const Mat& img, vector<Rect>& objects ) = 0;
int validate( int detectorIdx, vector<vector<Rect> >& objects );
FileNodeIterator it = fn[DETECTOR_NAMES].begin();
for( ; it != fn[DETECTOR_NAMES].end(); )
{
- string name;
- it >> name;
- detectorNames.push_back(name);
- readDetector(fn[DETECTORS][name]);
+ string _name;
+ it >> _name;
+ detectorNames.push_back(_name);
+ readDetector(fn[DETECTORS][_name]);
}
}
test_case_count = (int)detectorNames.size();
}
validationFS << "]"; // DETECTOR_NAMES
- // write detectors
- validationFS << DETECTORS << "{";
- assert( detectorNames.size() == detectorFilenames.size() );
- nit = detectorNames.begin();
- for( int di = 0; di < detectorNames.size(), nit != detectorNames.end(); ++nit, di++ )
- {
- validationFS << *nit << "{";
- writeDetector( validationFS, di );
- validationFS << "}";
- }
- validationFS << "}";
-
+ // write detectors
+ validationFS << DETECTORS << "{";
+ assert( detectorNames.size() == detectorFilenames.size() );
+ nit = detectorNames.begin();
+ for( int di = 0; di < detectorNames.size(), nit != detectorNames.end(); ++nit, di++ )
+ {
+ validationFS << *nit << "{";
+ writeDetector( validationFS, di );
+ validationFS << "}";
+ }
+ validationFS << "}";
+
// write image filenames
validationFS << IMAGE_FILENAMES << "[";
vector<string>::const_iterator it = imageFilenames.begin();
return cvtest::TS::FAIL_INVALID_TEST_DATA;
}
int code = detectMultiScale( detectorIdx, image, imgObjects );
- if( code != cvtest::TS::OK )
- return code;
+ if( code != cvtest::TS::OK )
+ return code;
objects.push_back( imgObjects );
vector<Rect> valRects;
if( node.node->data.seq != 0 )
{
- for( FileNodeIterator it = node.begin(); it != node.end(); )
+ for( FileNodeIterator it2 = node.begin(); it2 != node.end(); )
{
Rect r;
- it >> r.x >> r.y >> r.width >> r.height;
+ it2 >> r.x >> r.y >> r.width >> r.height;
valRects.push_back(r);
}
}
totalValRectCount += (int)valRects.size();
-
+
// compare rectangles
- vector<uchar> map(valRects.size(), 0);
+ vector<uchar> map(valRects.size(), 0);
for( vector<Rect>::const_iterator cr = it->begin();
cr != it->end(); ++cr )
{
{
Rect vr = valRects[minIdx];
if( map[minIdx] != 0 || (minDist > dist) || (abs(cr->width - vr.width) > wDiff) ||
- (abs(cr->height - vr.height) > hDiff) )
+ (abs(cr->height - vr.height) > hDiff) )
noPair++;
- else
- map[minIdx] = 1;
+ else
+ map[minIdx] = 1;
}
}
noPair += (int)count_if( map.begin(), map.end(), isZero );
public:
CV_CascadeDetectorTest();
protected:
- virtual void readDetector( const FileNode& fn );
- virtual void writeDetector( FileStorage& fs, int di );
+ virtual void readDetector( const FileNode& fn );
+ virtual void writeDetector( FileStorage& fs, int di );
virtual int detectMultiScale( int di, const Mat& img, vector<Rect>& objects );
- vector<int> flags;
+ vector<int> flags;
};
CV_CascadeDetectorTest::CV_CascadeDetectorTest()
void CV_CascadeDetectorTest::readDetector( const FileNode& fn )
{
- string filename;
- int flag;
- fn[FILENAME] >> filename;
- detectorFilenames.push_back(filename);
- fn[C_SCALE_CASCADE] >> flag;
- if( flag )
- flags.push_back( 0 );
- else
- flags.push_back( CV_HAAR_SCALE_IMAGE );
+ string filename;
+ int flag;
+ fn[FILENAME] >> filename;
+ detectorFilenames.push_back(filename);
+ fn[C_SCALE_CASCADE] >> flag;
+ if( flag )
+ flags.push_back( 0 );
+ else
+ flags.push_back( CV_HAAR_SCALE_IMAGE );
}
void CV_CascadeDetectorTest::writeDetector( FileStorage& fs, int di )
{
- int sc = flags[di] & CV_HAAR_SCALE_IMAGE ? 0 : 1;
- fs << FILENAME << detectorFilenames[di];
- fs << C_SCALE_CASCADE << sc;
+ int sc = flags[di] & CV_HAAR_SCALE_IMAGE ? 0 : 1;
+ fs << FILENAME << detectorFilenames[di];
+ fs << C_SCALE_CASCADE << sc;
}
int CV_CascadeDetectorTest::detectMultiScale( int di, const Mat& img,
vector<Rect>& objects)
{
- string dataPath = ts->get_data_path(), filename;
- filename = dataPath + detectorFilenames[di];
+ string dataPath = ts->get_data_path(), filename;
+ filename = dataPath + detectorFilenames[di];
CascadeClassifier cascade( filename );
- if( cascade.empty() )
- {
- ts->printf( cvtest::TS::LOG, "cascade %s can not be opened");
- return cvtest::TS::FAIL_INVALID_TEST_DATA;
- }
+ if( cascade.empty() )
+ {
+ ts->printf( cvtest::TS::LOG, "cascade %s can not be opened");
+ return cvtest::TS::FAIL_INVALID_TEST_DATA;
+ }
Mat grayImg;
cvtColor( img, grayImg, CV_BGR2GRAY );
equalizeHist( grayImg, grayImg );
cascade.detectMultiScale( grayImg, objects, 1.1, 3, flags[di] );
- return cvtest::TS::OK;
+ return cvtest::TS::OK;
}
//----------------------------------------------- HOGDetectorTest -----------------------------------
public:
CV_HOGDetectorTest();
protected:
- virtual void readDetector( const FileNode& fn );
- virtual void writeDetector( FileStorage& fs, int di );
+ virtual void readDetector( const FileNode& fn );
+ virtual void writeDetector( FileStorage& fs, int di );
virtual int detectMultiScale( int di, const Mat& img, vector<Rect>& objects );
};
void CV_HOGDetectorTest::readDetector( const FileNode& fn )
{
- string filename;
- if( fn[FILENAME].node->data.seq != 0 )
- fn[FILENAME] >> filename;
- detectorFilenames.push_back( filename);
+ string filename;
+ if( fn[FILENAME].node->data.seq != 0 )
+ fn[FILENAME] >> filename;
+ detectorFilenames.push_back( filename);
}
void CV_HOGDetectorTest::writeDetector( FileStorage& fs, int di )
{
- fs << FILENAME << detectorFilenames[di];
+ fs << FILENAME << detectorFilenames[di];
}
int CV_HOGDetectorTest::detectMultiScale( int di, const Mat& img,
else
assert(0);
hog.detectMultiScale(img, objects);
- return cvtest::TS::OK;
+ return cvtest::TS::OK;
}
TEST(Objdetect_CascadeDetector, regression) { CV_CascadeDetectorTest test; test.safe_run(); }
enum { NO, FEATHER, MULTI_BAND };\r
static Ptr<Blender> createDefault(int type, bool try_gpu = false);\r
\r
- void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes); \r
+ void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes);\r
virtual void prepare(Rect dst_roi);\r
virtual void feed(const Mat &img, const Mat &mask, Point tl);\r
virtual void blend(Mat &dst, Mat &dst_mask);\r
class CV_EXPORTS FeatherBlender : public Blender\r
{\r
public:\r
- FeatherBlender(float sharpness = 0.02f) { setSharpness(sharpness); }\r
+ FeatherBlender(float sharpness = 0.02f);\r
\r
float sharpness() const { return sharpness_; }\r
void setSharpness(float val) { sharpness_ = val; }\r
Mat dst_weight_map_;\r
};\r
\r
+inline FeatherBlender::FeatherBlender(float _sharpness) { setSharpness(_sharpness); }\r
+\r
\r
class CV_EXPORTS MultiBandBlender : public Blender\r
{\r
{ \\r
LOG_STITCHING_MSG(_msg); \\r
} \\r
- break; \\r
- } \r
+ break; \\r
+ }\r
\r
\r
#define LOG(msg) LOG_(1, msg)\r
\r
struct CV_EXPORTS GraphEdge\r
{\r
- GraphEdge(int from, int to, float weight) \r
- : from(from), to(to), weight(weight) {}\r
+ GraphEdge(int from, int to, float weight);\r
bool operator <(const GraphEdge& other) const { return weight < other.weight; }\r
bool operator >(const GraphEdge& other) const { return weight > other.weight; }\r
\r
float weight;\r
};\r
\r
+inline GraphEdge::GraphEdge(int _from, int _to, float _weight) : from(_from), to(_to), weight(_weight) {}\r
+\r
\r
class CV_EXPORTS Graph\r
{\r
void addEdge(int from, int to, float weight);\r
template <typename B> B forEach(B body) const;\r
template <typename B> B walkBreadthFirst(int from, B body) const;\r
- \r
+\r
private:\r
std::vector< std::list<GraphEdge> > edges_;\r
};\r
const cv::Mat& matchingMask() const { return matching_mask_; }
void setMatchingMask(const cv::Mat &mask)
- {
+ {
CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
- matching_mask_ = mask.clone();
+ matching_mask_ = mask.clone();
}
Ptr<detail::BundleAdjusterBase> bundleAdjuster() { return bundle_adjuster_; }
Ptr<WarperCreator> warper() { return warper_; }
const Ptr<WarperCreator> warper() const { return warper_; }
- void setWarper(Ptr<WarperCreator> warper) { warper_ = warper; }
+ void setWarper(Ptr<WarperCreator> creator) { warper_ = creator; }
Ptr<detail::ExposureCompensator> exposureCompensator() { return exposure_comp_; }
const Ptr<detail::ExposureCompensator> exposureCompensator() const { return exposure_comp_; }
Ptr<detail::Blender> blender() { return blender_; }
const Ptr<detail::Blender> blender() const { return blender_; }
- void setBlender(Ptr<detail::Blender> blender) { blender_ = blender; }
+ void setBlender(Ptr<detail::Blender> b) { blender_ = b; }
private:
Stitcher() {}
: matcher(other.matcher), features(other.features),\r
pairwise_matches(other.pairwise_matches), near_pairs(other.near_pairs) {}\r
\r
- MatchPairsBody(FeaturesMatcher &matcher, const vector<ImageFeatures> &features,\r
- vector<MatchesInfo> &pairwise_matches, vector<pair<int,int> > &near_pairs)\r
- : matcher(matcher), features(features),\r
- pairwise_matches(pairwise_matches), near_pairs(near_pairs) {}\r
+ MatchPairsBody(FeaturesMatcher &_matcher, const vector<ImageFeatures> &_features,\r
+ vector<MatchesInfo> &_pairwise_matches, vector<pair<int,int> > &_near_pairs)\r
+ : matcher(_matcher), features(_features),\r
+ pairwise_matches(_pairwise_matches), near_pairs(_near_pairs) {}\r
\r
void operator ()(const BlockedRange &r) const\r
{\r
\r
struct IncDistance\r
{\r
- IncDistance(vector<int> &dists) : dists(&dists[0]) {}\r
+ IncDistance(vector<int> &vdists) : dists(&vdists[0]) {}\r
void operator ()(const GraphEdge &edge) { dists[edge.to] = dists[edge.from] + 1; }\r
int* dists;\r
};\r
\r
struct CalcRotation\r
{\r
- CalcRotation(int num_images, const vector<MatchesInfo> &pairwise_matches, vector<CameraParams> &cameras)\r
- : num_images(num_images), pairwise_matches(&pairwise_matches[0]), cameras(&cameras[0]) {}\r
+ CalcRotation(int _num_images, const vector<MatchesInfo> &_pairwise_matches, vector<CameraParams> &_cameras)\r
+ : num_images(_num_images), pairwise_matches(&_pairwise_matches[0]), cameras(&_cameras[0]) {}\r
\r
void operator ()(const GraphEdge &edge)\r
{\r
// Compute number of correspondences\r
total_num_matches_ = 0;\r
for (size_t i = 0; i < edges_.size(); ++i)\r
- total_num_matches_ += static_cast<int>(pairwise_matches[edges_[i].first * num_images_ + \r
+ total_num_matches_ += static_cast<int>(pairwise_matches[edges_[i].first * num_images_ +\r
edges_[i].second].num_inliers);\r
\r
- CvLevMarq solver(num_images_ * num_params_per_cam_, \r
+ CvLevMarq solver(num_images_ * num_params_per_cam_,\r
total_num_matches_ * num_errs_per_measurement_,\r
term_criteria_);\r
\r
\r
svd(cameras[i].R, SVD::FULL_UV);\r
Mat R = svd.u * svd.vt;\r
- if (determinant(R) < 0) \r
+ if (determinant(R) < 0)\r
R *= -1;\r
\r
Mat rvec;\r
calcDeriv(err1_, err2_, 2 * step, jac.col(i * 7));\r
cam_params_.at<double>(i * 7, 0) = val;\r
}\r
- if (refinement_mask_.at<uchar>(0, 2)) \r
+ if (refinement_mask_.at<uchar>(0, 2))\r
{\r
val = cam_params_.at<double>(i * 7 + 1, 0);\r
cam_params_.at<double>(i * 7 + 1, 0) = val - step;\r
calcDeriv(err1_, err2_, 2 * step, jac.col(i * 7 + 1));\r
cam_params_.at<double>(i * 7 + 1, 0) = val;\r
}\r
- if (refinement_mask_.at<uchar>(1, 2)) \r
+ if (refinement_mask_.at<uchar>(1, 2))\r
{\r
val = cam_params_.at<double>(i * 7 + 2, 0);\r
cam_params_.at<double>(i * 7 + 2, 0) = val - step;\r
\r
svd(cameras[i].R, SVD::FULL_UV);\r
Mat R = svd.u * svd.vt;\r
- if (determinant(R) < 0) \r
+ if (determinant(R) < 0)\r
R *= -1;\r
\r
Mat rvec;\r
double mult = sqrt(f1 * f2);\r
err.at<double>(3 * match_idx, 0) = mult * (x1 - x2);\r
err.at<double>(3 * match_idx + 1, 0) = mult * (y1 - y2);\r
- err.at<double>(3 * match_idx + 2, 0) = mult * (z1 - z2); \r
+ err.at<double>(3 * match_idx + 2, 0) = mult * (z1 - z2);\r
\r
match_idx++;\r
}\r
continue;\r
int comp1 = comps.findSetByElem(i);\r
int comp2 = comps.findSetByElem(j);\r
- if (comp1 != comp2) \r
+ if (comp1 != comp2)\r
comps.mergeSets(comp1, comp2);\r
}\r
}\r
vector<int> indices_removed;\r
for (int i = 0; i < num_images; ++i)\r
if (comps.findSetByElem(i) == max_comp)\r
- indices.push_back(i); \r
+ indices.push_back(i);\r
else\r
indices_removed.push_back(i);\r
\r
\r
LOG("Removed some images, because can't match them or there are too similar images: (");\r
LOG(indices_removed[0] + 1);\r
- for (size_t i = 1; i < indices_removed.size(); ++i) \r
+ for (size_t i = 1; i < indices_removed.size(); ++i)\r
LOG(", " << indices_removed[i]+1);\r
LOGLN(").");\r
LOGLN("Try to decrease --match_conf value and/or check if you're stitching duplicates.");\r
}
// Warp images and their masks
- Ptr<detail::RotationWarper> warper = warper_->create(float(warped_image_scale_ * seam_work_aspect_));
+ Ptr<detail::RotationWarper> w = warper_->create(float(warped_image_scale_ * seam_work_aspect_));
for (size_t i = 0; i < imgs_.size(); ++i)
{
Mat_<float> K;
cameras_[i].K().convertTo(K, CV_32F);
- K(0,0) *= (float)seam_work_aspect_;
+ K(0,0) *= (float)seam_work_aspect_;
K(0,2) *= (float)seam_work_aspect_;
- K(1,1) *= (float)seam_work_aspect_;
+ K(1,1) *= (float)seam_work_aspect_;
K(1,2) *= (float)seam_work_aspect_;
- corners[i] = warper->warp(seam_est_imgs_[i], K, cameras_[i].R, INTER_LINEAR, BORDER_REFLECT, images_warped[i]);
+ corners[i] = w->warp(seam_est_imgs_[i], K, cameras_[i].R, INTER_LINEAR, BORDER_REFLECT, images_warped[i]);
sizes[i] = images_warped[i].size();
- warper->warp(masks[i], K, cameras_[i].R, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]);
+ w->warp(masks[i], K, cameras_[i].R, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]);
}
vector<Mat> images_warped_f(imgs_.size());
// Update warped image scale
warped_image_scale_ *= static_cast<float>(compose_work_aspect);
- warper = warper_->create((float)warped_image_scale_);
+ w = warper_->create((float)warped_image_scale_);
// Update corners and sizes
for (size_t i = 0; i < imgs_.size(); ++i)
Mat K;
cameras_[i].K().convertTo(K, CV_32F);
- Rect roi = warper->warpRoi(sz, K, cameras_[i].R);
+ Rect roi = w->warpRoi(sz, K, cameras_[i].R);
corners[i] = roi.tl();
sizes[i] = roi.size();
}
cameras_[img_idx].K().convertTo(K, CV_32F);
// Warp the current image
- warper->warp(img, K, cameras_[img_idx].R, INTER_LINEAR, BORDER_REFLECT, img_warped);
+ w->warp(img, K, cameras_[img_idx].R, INTER_LINEAR, BORDER_REFLECT, img_warped);
// Warp the current image mask
mask.create(img_size, CV_8U);
mask.setTo(Scalar::all(255));
- warper->warp(mask, K, cameras_[img_idx].R, INTER_NEAREST, BORDER_CONSTANT, mask_warped);
+ w->warp(mask, K, cameras_[img_idx].R, INTER_NEAREST, BORDER_CONSTANT, mask_warped);
// Compensate exposure
exposure_comp_->apply((int)img_idx, corners[img_idx], img_warped, mask_warped);
#include <stdio.h>
#include "lkpyramid.hpp"
-namespace
+namespace
{
static void calcSharrDeriv(const cv::Mat& src, cv::Mat& dst)
{
#ifdef HAVE_TEGRA_OPTIMIZATION
if (tegra::calcSharrDeriv(src, dst))
return;
-#endif
-
+#endif
+
int x, y, delta = (int)alignSize((cols + 2)*cn, 16);
AutoBuffer<deriv_type> _tempBuf(delta*2 + 64);
deriv_type *trow0 = alignPtr(_tempBuf + cn, 16), *trow1 = alignPtr(trow0 + delta, 16);
-
+
#if CV_SSE2
__m128i z = _mm_setzero_si128(), c3 = _mm_set1_epi16(3), c10 = _mm_set1_epi16(10);
#endif
-
+
for( y = 0; y < rows; y++ )
{
const uchar* srow0 = src.ptr<uchar>(y > 0 ? y-1 : rows > 1 ? 1 : 0);
const uchar* srow1 = src.ptr<uchar>(y);
const uchar* srow2 = src.ptr<uchar>(y < rows-1 ? y+1 : rows > 1 ? rows-2 : 0);
deriv_type* drow = dst.ptr<deriv_type>(y);
-
+
// do vertical convolution
x = 0;
#if CV_SSE2
trow0[x] = (deriv_type)t0;
trow1[x] = (deriv_type)t1;
}
-
+
// make border
int x0 = (cols > 1 ? 1 : 0)*cn, x1 = (cols > 1 ? cols-2 : 0)*cn;
for( int k = 0; k < cn; k++ )
trow0[-cn + k] = trow0[x0 + k]; trow0[colsn + k] = trow0[x1 + k];
trow1[-cn + k] = trow1[x0 + k]; trow1[colsn + k] = trow1[x1 + k];
}
-
+
// do horizontal convolution, interleave the results and store them to dst
x = 0;
#if CV_SSE2
__m128i s2 = _mm_loadu_si128((const __m128i*)(trow1 + x - cn));
__m128i s3 = _mm_load_si128((const __m128i*)(trow1 + x));
__m128i s4 = _mm_loadu_si128((const __m128i*)(trow1 + x + cn));
-
+
__m128i t0 = _mm_sub_epi16(s1, s0);
__m128i t1 = _mm_add_epi16(_mm_mullo_epi16(_mm_add_epi16(s2, s4), c3), _mm_mullo_epi16(s3, c10));
__m128i t2 = _mm_unpacklo_epi16(t0, t1);
_mm_storeu_si128((__m128i*)(drow + x*2), t2);
_mm_storeu_si128((__m128i*)(drow + x*2 + 8), t0);
}
-#endif
+#endif
for( ; x < colsn; x++ )
{
deriv_type t0 = (deriv_type)(trow0[x+cn] - trow0[x-cn]);
}
}//namespace
-
+
cv::detail::LKTrackerInvoker::LKTrackerInvoker(
const Mat& _prevImg, const Mat& _prevDeriv, const Mat& _nextImg,
const Point2f* _prevPts, Point2f* _nextPts,
const Mat& I = *prevImg;
const Mat& J = *nextImg;
const Mat& derivI = *prevDeriv;
-
+
int j, cn = I.channels(), cn2 = cn*2;
cv::AutoBuffer<deriv_type> _buf(winSize.area()*(cn + cn2));
int derivDepth = DataType<deriv_type>::depth;
-
+
Mat IWinBuf(winSize, CV_MAKETYPE(derivDepth, cn), (deriv_type*)_buf);
Mat derivIWinBuf(winSize, CV_MAKETYPE(derivDepth, cn2), (deriv_type*)_buf + winSize.area()*cn);
-
+
for( int ptidx = range.begin(); ptidx < range.end(); ptidx++ )
{
Point2f prevPt = prevPts[ptidx]*(float)(1./(1 << level));
else
nextPt = nextPts[ptidx]*2.f;
nextPts[ptidx] = nextPt;
-
+
Point2i iprevPt, inextPt;
prevPt -= halfWin;
iprevPt.x = cvFloor(prevPt.x);
iprevPt.y = cvFloor(prevPt.y);
-
+
if( iprevPt.x < -winSize.width || iprevPt.x >= derivI.cols ||
iprevPt.y < -winSize.height || iprevPt.y >= derivI.rows )
{
}
continue;
}
-
+
float a = prevPt.x - iprevPt.x;
float b = prevPt.y - iprevPt.y;
const int W_BITS = 14, W_BITS1 = 14;
int iw01 = cvRound(a*(1.f - b)*(1 << W_BITS));
int iw10 = cvRound((1.f - a)*b*(1 << W_BITS));
int iw11 = (1 << W_BITS) - iw00 - iw01 - iw10;
-
+
int dstep = (int)(derivI.step/derivI.elemSize1());
int step = (int)(I.step/I.elemSize1());
CV_Assert( step == (int)(J.step/J.elemSize1()) );
float A11 = 0, A12 = 0, A22 = 0;
-
+
#if CV_SSE2
__m128i qw0 = _mm_set1_epi32(iw00 + (iw01 << 16));
__m128i qw1 = _mm_set1_epi32(iw10 + (iw11 << 16));
__m128i qdelta = _mm_set1_epi32(1 << (W_BITS1-5-1));
__m128 qA11 = _mm_setzero_ps(), qA12 = _mm_setzero_ps(), qA22 = _mm_setzero_ps();
#endif
-
+
// extract the patch from the first image, compute covariation matrix of derivatives
int x, y;
for( y = 0; y < winSize.height; y++ )
{
const uchar* src = (const uchar*)I.data + (y + iprevPt.y)*step + iprevPt.x*cn;
const deriv_type* dsrc = (const deriv_type*)derivI.data + (y + iprevPt.y)*dstep + iprevPt.x*cn2;
-
+
deriv_type* Iptr = (deriv_type*)(IWinBuf.data + y*IWinBuf.step);
deriv_type* dIptr = (deriv_type*)(derivIWinBuf.data + y*derivIWinBuf.step);
-
+
x = 0;
-
+
#if CV_SSE2
for( ; x <= winSize.width*cn - 4; x += 4, dsrc += 4*2, dIptr += 4*2 )
{
__m128i v00, v01, v10, v11, t0, t1;
-
+
v00 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x)), z);
v01 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + cn)), z);
v10 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + step)), z);
v11 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + step + cn)), z);
-
+
t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0),
_mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1));
t0 = _mm_srai_epi32(_mm_add_epi32(t0, qdelta), W_BITS1-5);
_mm_storel_epi64((__m128i*)(Iptr + x), _mm_packs_epi32(t0,t0));
-
+
v00 = _mm_loadu_si128((const __m128i*)(dsrc));
v01 = _mm_loadu_si128((const __m128i*)(dsrc + cn2));
v10 = _mm_loadu_si128((const __m128i*)(dsrc + dstep));
v11 = _mm_loadu_si128((const __m128i*)(dsrc + dstep + cn2));
-
+
t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0),
_mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1));
t1 = _mm_add_epi32(_mm_madd_epi16(_mm_unpackhi_epi16(v00, v01), qw0),
t0 = _mm_srai_epi32(_mm_add_epi32(t0, qdelta_d), W_BITS1);
t1 = _mm_srai_epi32(_mm_add_epi32(t1, qdelta_d), W_BITS1);
v00 = _mm_packs_epi32(t0, t1); // Ix0 Iy0 Ix1 Iy1 ...
-
+
_mm_storeu_si128((__m128i*)dIptr, v00);
t0 = _mm_srai_epi32(v00, 16); // Iy0 Iy1 Iy2 Iy3
t1 = _mm_srai_epi32(_mm_slli_epi32(v00, 16), 16); // Ix0 Ix1 Ix2 Ix3
-
+
__m128 fy = _mm_cvtepi32_ps(t0);
__m128 fx = _mm_cvtepi32_ps(t1);
-
+
qA22 = _mm_add_ps(qA22, _mm_mul_ps(fy, fy));
qA12 = _mm_add_ps(qA12, _mm_mul_ps(fx, fy));
qA11 = _mm_add_ps(qA11, _mm_mul_ps(fx, fx));
}
#endif
-
+
for( ; x < winSize.width*cn; x++, dsrc += 2, dIptr += 2 )
{
int ival = CV_DESCALE(src[x]*iw00 + src[x+cn]*iw01 +
dsrc[dstep]*iw10 + dsrc[dstep+cn2]*iw11, W_BITS1);
int iyval = CV_DESCALE(dsrc[1]*iw00 + dsrc[cn2+1]*iw01 + dsrc[dstep+1]*iw10 +
dsrc[dstep+cn2+1]*iw11, W_BITS1);
-
+
Iptr[x] = (short)ival;
dIptr[0] = (short)ixval;
dIptr[1] = (short)iyval;
-
+
A11 += (float)(ixval*ixval);
A12 += (float)(ixval*iyval);
A22 += (float)(iyval*iyval);
}
}
-
+
#if CV_SSE2
float CV_DECL_ALIGNED(16) A11buf[4], A12buf[4], A22buf[4];
_mm_store_ps(A11buf, qA11);
A12 += A12buf[0] + A12buf[1] + A12buf[2] + A12buf[3];
A22 += A22buf[0] + A22buf[1] + A22buf[2] + A22buf[3];
#endif
-
+
A11 *= FLT_SCALE;
A12 *= FLT_SCALE;
A22 *= FLT_SCALE;
-
+
float D = A11*A22 - A12*A12;
float minEig = (A22 + A11 - std::sqrt((A11-A22)*(A11-A22) +
4.f*A12*A12))/(2*winSize.width*winSize.height);
-
+
if( err && (flags & CV_LKFLOW_GET_MIN_EIGENVALS) != 0 )
err[ptidx] = (float)minEig;
-
+
if( minEig < minEigThreshold || D < FLT_EPSILON )
{
if( level == 0 && status )
status[ptidx] = false;
continue;
}
-
+
D = 1.f/D;
-
+
nextPt -= halfWin;
Point2f prevDelta;
-
+
for( j = 0; j < criteria.maxCount; j++ )
{
inextPt.x = cvFloor(nextPt.x);
inextPt.y = cvFloor(nextPt.y);
-
+
if( inextPt.x < -winSize.width || inextPt.x >= J.cols ||
inextPt.y < -winSize.height || inextPt.y >= J.rows )
{
status[ptidx] = false;
break;
}
-
+
a = nextPt.x - inextPt.x;
b = nextPt.y - inextPt.y;
iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS));
qw1 = _mm_set1_epi32(iw10 + (iw11 << 16));
__m128 qb0 = _mm_setzero_ps(), qb1 = _mm_setzero_ps();
#endif
-
+
for( y = 0; y < winSize.height; y++ )
{
const uchar* Jptr = (const uchar*)J.data + (y + inextPt.y)*step + inextPt.x*cn;
const deriv_type* Iptr = (const deriv_type*)(IWinBuf.data + y*IWinBuf.step);
const deriv_type* dIptr = (const deriv_type*)(derivIWinBuf.data + y*derivIWinBuf.step);
-
+
x = 0;
-
+
#if CV_SSE2
for( ; x <= winSize.width*cn - 8; x += 8, dIptr += 8*2 )
{
__m128i v01 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + cn)), z);
__m128i v10 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + step)), z);
__m128i v11 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + step + cn)), z);
-
+
__m128i t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0),
_mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1));
__m128i t1 = _mm_add_epi32(_mm_madd_epi16(_mm_unpackhi_epi16(v00, v01), qw0),
diff0 = _mm_subs_epi16(_mm_packs_epi32(t0, t1), diff0);
diff1 = _mm_unpackhi_epi16(diff0, diff0);
diff0 = _mm_unpacklo_epi16(diff0, diff0); // It0 It0 It1 It1 ...
- v00 = _mm_loadu_si128((const __m128i*)(dIptr)); // Ix0 Iy0 Ix1 Iy1 ...
+ v00 = _mm_loadu_si128((const __m128i*)(dIptr)); // Ix0 Iy0 Ix1 Iy1 ...
v01 = _mm_loadu_si128((const __m128i*)(dIptr + 8));
v10 = _mm_mullo_epi16(v00, diff0);
v11 = _mm_mulhi_epi16(v00, diff0);
qb1 = _mm_add_ps(qb1, _mm_cvtepi32_ps(v10));
}
#endif
-
+
for( ; x < winSize.width*cn; x++, dIptr += 2 )
{
int diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 +
b2 += (float)(diff*dIptr[1]);
}
}
-
+
#if CV_SSE2
float CV_DECL_ALIGNED(16) bbuf[4];
_mm_store_ps(bbuf, _mm_add_ps(qb0, qb1));
b1 *= FLT_SCALE;
b2 *= FLT_SCALE;
-
+
Point2f delta( (float)((A12*b2 - A22*b1) * D),
(float)((A12*b1 - A11*b2) * D));
//delta = -delta;
-
+
nextPt += delta;
nextPts[ptidx] = nextPt + halfWin;
-
+
if( delta.ddot(delta) <= criteria.epsilon )
break;
-
+
if( j > 0 && std::abs(delta.x + prevDelta.x) < 0.01 &&
std::abs(delta.y + prevDelta.y) < 0.01 )
{
}
prevDelta = delta;
}
-
+
if( status[ptidx] && err && level == 0 && (flags & CV_LKFLOW_GET_MIN_EIGENVALS) == 0 )
{
- Point2f nextPt = nextPts[ptidx] - halfWin;
- Point inextPt;
-
- inextPt.x = cvFloor(nextPt.x);
- inextPt.y = cvFloor(nextPt.y);
-
- if( inextPt.x < -winSize.width || inextPt.x >= J.cols ||
- inextPt.y < -winSize.height || inextPt.y >= J.rows )
+ Point2f nextPoint = nextPts[ptidx] - halfWin;
+ Point inextPoint;
+
+ inextPoint.x = cvFloor(nextPoint.x);
+ inextPoint.y = cvFloor(nextPoint.y);
+
+ if( inextPoint.x < -winSize.width || inextPoint.x >= J.cols ||
+ inextPoint.y < -winSize.height || inextPoint.y >= J.rows )
{
if( status )
status[ptidx] = false;
continue;
}
-
- float a = nextPt.x - inextPt.x;
- float b = nextPt.y - inextPt.y;
- iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS));
- iw01 = cvRound(a*(1.f - b)*(1 << W_BITS));
- iw10 = cvRound((1.f - a)*b*(1 << W_BITS));
+
+ float aa = nextPoint.x - inextPoint.x;
+ float bb = nextPoint.y - inextPoint.y;
+ iw00 = cvRound((1.f - aa)*(1.f - bb)*(1 << W_BITS));
+ iw01 = cvRound(aa*(1.f - bb)*(1 << W_BITS));
+ iw10 = cvRound((1.f - aa)*bb*(1 << W_BITS));
iw11 = (1 << W_BITS) - iw00 - iw01 - iw10;
float errval = 0.f;
-
+
for( y = 0; y < winSize.height; y++ )
{
- const uchar* Jptr = (const uchar*)J.data + (y + inextPt.y)*step + inextPt.x*cn;
+ const uchar* Jptr = (const uchar*)J.data + (y + inextPoint.y)*step + inextPoint.x*cn;
const deriv_type* Iptr = (const deriv_type*)(IWinBuf.data + y*IWinBuf.step);
-
+
for( x = 0; x < winSize.width*cn; x++ )
{
int diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 +
}
}
}
-
+
int cv::buildOpticalFlowPyramid(InputArray _img, OutputArrayOfArrays pyramid, Size winSize, int maxLevel, bool withDerivatives,
int pyrBorder, int derivBorder, bool tryReuseInputImage)
{
if(!lvl0IsSet)
{
Mat& temp = pyramid.getMatRef(0);
-
+
if(!temp.empty())
temp.adjustROI(winSize.height, winSize.height, winSize.width, winSize.width);
if(temp.type() != img.type() || temp.cols != winSize.width*2 + img.cols || temp.rows != winSize.height * 2 + img.rows)
if (level != 0)
{
Mat& temp = pyramid.getMatRef(level * pyrstep);
-
+
if(!temp.empty())
temp.adjustROI(winSize.height, winSize.height, winSize.width, winSize.width);
if(temp.type() != img.type() || temp.cols != winSize.width*2 + sz.width || temp.rows != winSize.height * 2 + sz.height)
int level=0, i, npoints;
CV_Assert( (npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0 );
-
+
if( npoints == 0 )
{
_nextPts.release();
_err.release();
return;
}
-
+
if( !(flags & OPTFLOW_USE_INITIAL_FLOW) )
_nextPts.create(prevPtsMat.size(), prevPtsMat.type(), -1, true);
-
+
Mat nextPtsMat = _nextPts.getMat();
CV_Assert( nextPtsMat.checkVector(2, CV_32F, true) == npoints );
-
+
const Point2f* prevPts = (const Point2f*)prevPtsMat.data;
Point2f* nextPts = (Point2f*)nextPtsMat.data;
-
+
_status.create((int)npoints, 1, CV_8U, -1, true);
Mat statusMat = _status.getMat(), errMat;
CV_Assert( statusMat.isContinuous() );
uchar* status = statusMat.data;
float* err = 0;
-
+
for( i = 0; i < npoints; i++ )
status[i] = true;
-
+
if( _err.needed() )
{
_err.create((int)npoints, 1, CV_32F, -1, true);
}
else
derivI = prevPyr[level * lvlStep1 + 1];
-
+
CV_Assert(prevPyr[level * lvlStep1].size() == nextPyr[level * lvlStep2].size());
CV_Assert(prevPyr[level * lvlStep1].type() == nextPyr[level * lvlStep2].type());
#ifdef HAVE_TEGRA_OPTIMIZATION
typedef tegra::LKTrackerInvoker<cv::detail::LKTrackerInvoker> LKTrackerInvoker;
#else
- typedef cv::detail::LKTrackerInvoker LKTrackerInvoker;
+ typedef cv::detail::LKTrackerInvoker LKTrackerInvoker;
#endif
parallel_for(BlockedRange(0, npoints), LKTrackerInvoker(prevPyr[level * lvlStep1], derivI,
{
CvRect rect;
const char* src = (const char*)srcptr;
-
+
if( ip.x >= 0 )
{
src += ip.x*pix_size;
if( rect.x > win_size.width )
rect.x = win_size.width;
}
-
+
if( ip.x + win_size.width < src_size.width )
rect.width = win_size.width;
else
}
assert( rect.width <= win_size.width );
}
-
+
if( ip.y >= 0 )
{
src += ip.y * src_step;
}
else
rect.y = -ip.y;
-
+
if( ip.y + win_size.height < src_size.height )
rect.height = win_size.height;
else
rect.height = 0;
}
}
-
+
*pRect = rect;
return src - rect.x*pix_size;
}
float a, b;
double s = 0;
int i, j;
-
+
center.x -= (win_size.width-1)*0.5f;
center.y -= (win_size.height-1)*0.5f;
-
+
ip.x = cvFloor( center.x );
ip.y = cvFloor( center.y );
-
+
if( win_size.width <= 0 || win_size.height <= 0 )
return CV_BADRANGE_ERR;
-
+
a = center.x - ip.x;
b = center.y - ip.y;
a = MAX(a,0.0001f);
b1 = 1.f - b;
b2 = b;
s = (1. - a)/a;
-
+
src_step /= sizeof(src[0]);
dst_step /= sizeof(dst[0]);
-
+
if( 0 <= ip.x && ip.x + win_size.width < src_size.width &&
0 <= ip.y && ip.y + win_size.height < src_size.height )
{
// extracted rectangle is totally inside the image
src += ip.y * src_step + ip.x;
-
+
#if 0
if( icvCopySubpix_8u32f_C1R_p &&
icvCopySubpix_8u32f_C1R_p( src, src_step, dst,
dst_step*sizeof(dst[0]), win_size, a, b ) >= 0 )
return CV_OK;
#endif
-
+
for( ; win_size.height--; src += src_step, dst += dst_step )
{
float prev = (1 - a)*(b1*CV_8TO32F(src[0]) + b2*CV_8TO32F(src[src_step]));
else
{
CvRect r;
-
+
src = (const uchar*)icvAdjustRect( src, src_step*sizeof(*src),
sizeof(*src), src_size, win_size,ip, &r);
-
+
for( i = 0; i < win_size.height; i++, dst += dst_step )
{
const uchar *src2 = src + src_step;
-
+
if( i < r.y || i >= r.height )
src2 -= src_step;
-
+
for( j = 0; j < r.x; j++ )
{
float s0 = CV_8TO32F(src[r.x])*b1 +
CV_8TO32F(src2[r.x])*b2;
-
+
dst[j] = (float)(s0);
}
-
+
if( j < r.width )
{
float prev = (1 - a)*(b1*CV_8TO32F(src[j]) + b2*CV_8TO32F(src2[j]));
-
+
for( ; j < r.width; j++ )
{
float t = a12*CV_8TO32F(src[j+1]) + a22*CV_8TO32F(src2[j+1]);
prev = (float)(t*s);
}
}
-
+
for( ; j < win_size.width; j++ )
{
float s0 = CV_8TO32F(src[r.width])*b1 +
CV_8TO32F(src2[r.width])*b2;
-
+
dst[j] = (float)(s0);
}
-
+
if( i < r.height )
src = src2;
}
}
-
+
return CV_OK;
}
cv::Mat ptA(count, 1, CV_32FC2, (void*)featuresA);
cv::Mat ptB(count, 1, CV_32FC2, (void*)featuresB);
cv::Mat st, err;
-
+
if( status )
st = cv::Mat(count, 1, CV_8U, (void*)status);
if( error )
status[i] = (char)pt_status;
featuresB[i].x = Av[2];
featuresB[i].y = Av[5];
-
+
matrices[i*4] = Av[0];
matrices[i*4+1] = Av[1];
matrices[i*4+2] = Av[3];
cvResize( A, sA, CV_INTER_AREA );
cvResize( B, sB, CV_INTER_AREA );
}
-
+
A = sA;
B = sB;
}
if( count < RANSAC_SIZE0 )
return 0;
-
- CvMat _pB = cvMat(1, count, CV_32FC2, pB);
+
+ CvMat _pB = cvMat(1, count, CV_32FC2, pB);
brect = cvBoundingRect(&_pB, 1);
// RANSAC stuff:
for( k1 = 0; k1 < RANSAC_MAX_ITERS; k1++ )
{
idx[i] = cvRandInt(&rng) % count;
-
+
for( j = 0; j < i; j++ )
{
if( idx[j] == idx[i] )
b[0] = pB[idx[0]];
b[1] = pB[idx[1]];
b[2] = pB[idx[2]];
-
+
double dax1 = a[1].x - a[0].x, day1 = a[1].y - a[0].y;
double dax2 = a[2].x - a[0].x, day2 = a[2].y - a[0].y;
double dbx1 = b[1].x - b[0].x, dby1 = b[1].y - b[0].y;
m[2] /= scale;
m[5] /= scale;
cvConvert( &M, matM );
-
+
return 1;
}
FarnebackPolyExp( const Mat& src, Mat& dst, int n, double sigma )
{
int k, x, y;
-
+
assert( src.type() == CV_32FC1 );
int width = src.cols;
int height = src.rows;
float* xg = g + n*2 + 1;
float* xxg = xg + n*2 + 1;
float *row = (float*)_row + n*3;
-
+
if( sigma < FLT_EPSILON )
sigma = n*0.3;
-
+
double s = 0.;
for( x = -n; x <= n; x++ )
{
g[x] = (float)std::exp(-x*x/(2*sigma*sigma));
s += g[x];
}
-
+
s = 1./s;
for( x = -n; x <= n; x++ )
{
}
Mat_<double> G = Mat_<double>::zeros(6, 6);
-
+
for( y = -n; y <= n; y++ )
for( x = -n; x <= n; x++ )
{
G(3,3) += g[y]*g[x]*x*x*x*x;
G(5,5) += g[y]*g[x]*x*x*y*y;
}
-
+
//G[0][0] = 1.;
G(2,2) = G(0,3) = G(0,4) = G(3,0) = G(4,0) = G(1,1);
G(4,4) = G(3,3);
double ig11 = invG(1,1), ig03 = invG(0,3), ig33 = invG(3,3), ig55 = invG(5,5);
dst.create( height, width, CV_32FC(5));
-
+
for( y = 0; y < height; y++ )
{
float g0 = g[0], g1, g2;
float *srow0 = (float*)(src.data + src.step*y), *srow1 = 0;
float *drow = (float*)(dst.data + dst.step*y);
-
+
// vertical part of convolution
for( x = 0; x < width; x++ )
{
row[x*3] = srow0[x]*g0;
row[x*3+1] = row[x*3+2] = 0.f;
}
-
+
for( k = 1; k <= n; k++ )
{
g0 = g[k]; g1 = xg[k]; g2 = xxg[k];
srow0 = (float*)(src.data + src.step*std::max(y-k,0));
srow1 = (float*)(src.data + src.step*std::min(y+k,height-1));
-
+
for( x = 0; x < width; x++ )
{
float p = srow0[x] + srow1[x];
float t0 = row[x*3] + g0*p;
float t1 = row[x*3+1] + g1*(srow1[x] - srow0[x]);
float t2 = row[x*3+2] + g2*p;
-
+
row[x*3] = t0;
row[x*3+1] = t1;
row[x*3+2] = t2;
}
}
-
+
// horizontal part of convolution
for( x = 0; x < n*3; x++ )
{
row[-1-x] = row[2-x];
row[width*3+x] = row[width*3+x-3];
}
-
+
for( x = 0; x < width; x++ )
{
g0 = g[0];
// r1 ~ 1, r2 ~ x, r3 ~ y, r4 ~ x^2, r5 ~ y^2, r6 ~ xy
double b1 = row[x*3]*g0, b2 = 0, b3 = row[x*3+1]*g0,
b4 = 0, b5 = row[x*3+2]*g0, b6 = 0;
-
+
for( k = 1; k <= n; k++ )
{
double tg = row[(x+k)*3] + row[(x-k)*3];
b6 += (row[(x+k)*3+1] - row[(x-k)*3+1])*xg[k];
b5 += (row[(x+k)*3+2] + row[(x-k)*3+2])*g0;
}
-
+
// do not store r1
drow[x*5+1] = (float)(b2*ig11);
drow[x*5] = (float)(b3*ig11);
drow[x*5+4] = (float)(b6*ig55);
}
}
-
+
row -= n*3;
}
int x, y, width = _flow.cols, height = _flow.rows;
const float* R1 = (float*)_R1.data;
size_t step1 = _R1.step/sizeof(R1[0]);
-
+
matM.create(height, width, CV_32FC(5));
for( y = _y0; y < _y1; y++ )
const float* flow = (float*)(_flow.data + y*_flow.step);
const float* R0 = (float*)(_R0.data + y*_R0.step);
float* M = (float*)(matM.data + y*matM.step);
-
+
for( x = 0; x < width; x++ )
{
float dx = flow[x*2], dy = flow[x*2+1];
float r2, r3, r4, r5, r6;
fx -= x1; fy -= y1;
-
+
if( (unsigned)x1 < (unsigned)(width-1) &&
(unsigned)y1 < (unsigned)(height-1) )
{
int y0 = 0, y1;
int min_update_stripe = std::max((1 << 10)/width, block_size);
double scale = 1./(block_size*block_size);
-
+
AutoBuffer<double> _vsum((width+m*2+2)*5);
double* vsum = _vsum + (m+1)*5;
srow0 = (const float*)(matM.data + matM.step*std::max(y-m-1,0));
const float* srow1 = (const float*)(matM.data + matM.step*std::min(y+m,height-1));
-
+
// vertical blur
for( x = 0; x < width*5; x++ )
vsum[x] += srow1[x] - srow0[x];
double h2_ = h2*scale;
double idet = 1./(g11_*g22_ - g12_*g12_+1e-3);
-
+
flow[x*2] = (float)((g11_*h2_-g12_*h1_)*idet);
flow[x*2+1] = (float)((g22_*h1_-g12_*h2_)*idet);
}
int y0 = 0, y1;
int min_update_stripe = std::max((1 << 10)/width, block_size);
double sigma = m*0.3, s = 1;
-
+
AutoBuffer<float> _vsum((width+m*2+2)*5 + 16), _hsum(width*5 + 16);
AutoBuffer<float, 4096> _kernel((m+1)*5 + 16);
AutoBuffer<float*, 1024> _srow(m*2+1);
s2 = _mm_add_ps(s2, _mm_mul_ps(x0, g4));
s3 = _mm_add_ps(s3, _mm_mul_ps(x1, g4));
}
-
+
_mm_store_ps(vsum + x, s0);
_mm_store_ps(vsum + x + 4, s1);
_mm_store_ps(vsum + x + 8, s2);
#endif
for( ; x < width*5; x++ )
{
- float s = vsum[x]*kernel[0];
+ float sum = vsum[x]*kernel[0];
for( i = 1; i <= m; i++ )
- s += kernel[i]*(vsum[x - i*5] + vsum[x + i*5]);
- hsum[x] = s;
+ sum += kernel[i]*(vsum[x - i*5] + vsum[x + i*5]);
+ hsum[x] = sum;
}
for( x = 0; x < width; x++ )
h2 = hsum[x*5+4];
double idet = 1./(g11*g22 - g12*g12 + 1e-3);
-
+
flow[x*2] = (float)((g11*h2-g12*h1)*idet);
flow[x*2+1] = (float)((g22*h1-g12*h2)*idet);
}
resize( fimg, I, Size(width, height), CV_INTER_LINEAR );
FarnebackPolyExp( I, R[i], poly_n, poly_sigma );
}
-
+
FarnebackUpdateMatrices( R[0], R[1], flow, M, 0, flow.rows );
for( i = 0; i < iterations; i++ )
int x, y;
DXY() : dist(0), x(0), y(0) {}
- DXY(float dist, int x, int y) : dist(dist), x(x), y(y) {}
+ DXY(float _dist, int _x, int _y) : dist(_dist), x(_x), y(_y) {}
bool operator <(const DXY &dxy) const { return dist < dxy.dist; }
};
class CV_EXPORTS ColorInpainter : public InpainterBase
{
public:
- ColorInpainter(int method = INPAINT_TELEA, double radius = 2.)
- : method_(method), radius_(radius) {}
+ ColorInpainter(int method = INPAINT_TELEA, double radius = 2.);
virtual void inpaint(int idx, Mat &frame, Mat &mask);
Mat invMask_;
};
+inline ColorInpainter::ColorInpainter(int _method, double _radius)
+ : method_(_method), radius_(_radius) {}
+
CV_EXPORTS void calcFlowMask(
const Mat &flowX, const Mat &flowY, const Mat &errors, float maxError,
const Mat &mask0, const Mat &mask1, Mat &flowMask);
float prob; // probability of success
RansacParams() : size(0), thresh(0), eps(0), prob(0) {}
- RansacParams(int size, float thresh, float eps, float prob)
- : size(size), thresh(thresh), eps(eps), prob(prob) {}
+ RansacParams(int size, float thresh, float eps, float prob);
int niters() const
{
}
};
+inline RansacParams::RansacParams(int _size, float _thresh, float _eps, float _prob)
+ : size(_size), thresh(_thresh), eps(_eps), prob(_prob) {}
+
} // namespace videostab
} // namespace cv
class CV_EXPORTS GaussianMotionFilter : public MotionFilterBase
{
public:
- GaussianMotionFilter(int radius = 15, float stdev = -1.f) { setParams(radius, stdev); }
+ GaussianMotionFilter(int radius = 15, float stdev = -1.f);
void setParams(int radius, float stdev = -1.f);
int radius() const { return radius_; }
std::vector<float> weight_;
};
+inline GaussianMotionFilter::GaussianMotionFilter(int _radius, float _stdev) { setParams(_radius, _stdev); }
+
class CV_EXPORTS LpMotionStabilizer : public IMotionStabilizer
{
public:
public:
virtual ~StabilizerBase() {}
- void setLog(Ptr<ILog> log) { log_ = log; }
+ void setLog(Ptr<ILog> ilog) { log_ = ilog; }
Ptr<ILog> log() const { return log_; }
void setRadius(int val) { radius_ = val; }
Mat_<float> M = estimateGlobalMotionLeastSquares(subset0, subset1, model, 0);
- int ninliers = 0;
+ int numinliers = 0;
for (int i = 0; i < npoints; ++i)
{
p0 = points0_[i];
x = M(0,0)*p0.x + M(0,1)*p0.y + M(0,2);
y = M(1,0)*p0.x + M(1,1)*p0.y + M(1,2);
if (sqr(x - p1.x) + sqr(y - p1.y) < params.thresh * params.thresh)
- ninliers++;
+ numinliers++;
}
- if (ninliers >= ninliersMax)
+ if (numinliers >= ninliersMax)
{
bestM = M;
- ninliersMax = ninliers;
+ ninliersMax = numinliers;
subset0best.swap(subset0);
subset1best.swap(subset1);
}
// perform outlier rejection
- IOutlierRejector *outlierRejector = static_cast<IOutlierRejector*>(outlierRejector_);
- if (!dynamic_cast<NullOutlierRejector*>(outlierRejector))
+ IOutlierRejector *outlRejector = static_cast<IOutlierRejector*>(outlierRejector_);
+ if (!dynamic_cast<NullOutlierRejector*>(outlRejector))
{
pointsPrev_.swap(pointsPrevGood_);
points_.swap(pointsGood_);
CV_Assert(mask.size() == frame.size() && mask.type() == CV_8U);
Mat invS = at(idx, *stabilizationMotions_).inv();
- vector<Mat_<float> > motions(2*radius_ + 1);
+ vector<Mat_<float> > vmotions(2*radius_ + 1);
for (int i = -radius_; i <= radius_; ++i)
- motions[radius_ + i] = getMotion(idx, idx + i, *motions_) * invS;
+ vmotions[radius_ + i] = getMotion(idx, idx + i, *motions_) * invS;
int n;
float mean, var;
for (int i = -radius_; i <= radius_; ++i)
{
const Mat_<Point3_<uchar> > &framei = at(idx + i, *frames_);
- const Mat_<float> &Mi = motions[radius_ + i];
+ const Mat_<float> &Mi = vmotions[radius_ + i];
int xi = cvRound(Mi(0,0)*x + Mi(0,1)*y + Mi(0,2));
int yi = cvRound(Mi(1,0)*x + Mi(1,1)*y + Mi(1,2));
if (xi >= 0 && xi < framei.cols && yi >= 0 && yi < framei.rows)
void MotionInpainter::inpaint(int idx, Mat &frame, Mat &mask)
{
priority_queue<pair<float,int> > neighbors;
- vector<Mat> motions(2*radius_ + 1);
+ vector<Mat> vmotions(2*radius_ + 1);
for (int i = -radius_; i <= radius_; ++i)
{
Mat motion0to1 = getMotion(idx, idx + i, *motions_) * at(idx, *stabilizationMotions_).inv();
- motions[radius_ + i] = motion0to1;
+ vmotions[radius_ + i] = motion0to1;
if (i != 0)
{
int neighbor = neighbors.top().second;
neighbors.pop();
- Mat motion1to0 = motions[radius_ + neighbor - idx].inv();
+ Mat motion1to0 = vmotions[radius_ + neighbor - idx].inv();
// warp frame
{
stabilizers_[i]->stabilize(size, updatedMotions, range, &stabilizationMotions_[0]);
- for (int i = 0; i < size; ++i)
- stabilizationMotions[i] = stabilizationMotions_[i] * stabilizationMotions[i];
+ for (int k = 0; k < size; ++k)
+ stabilizationMotions[k] = stabilizationMotions_[k] * stabilizationMotions[k];
for (int j = 0; j + 1 < size; ++j)
{
}
-void GaussianMotionFilter::setParams(int radius, float stdev)
+void GaussianMotionFilter::setParams(int _radius, float _stdev)
{
- radius_ = radius;
- stdev_ = stdev > 0.f ? stdev : sqrt(static_cast<float>(radius));
+ radius_ = _radius;
+ stdev_ = _stdev > 0.f ? _stdev : sqrt(static_cast<float>(_radius));
float sum = 0;
weight_.resize(2*radius_ + 1);
void StabilizerBase::setUp(const Mat &firstFrame)
{
- InpainterBase *inpainter = static_cast<InpainterBase*>(inpainter_);
- doInpainting_ = dynamic_cast<NullInpainter*>(inpainter) == 0;
+ InpainterBase *inpaint = static_cast<InpainterBase*>(inpainter_);
+ doInpainting_ = dynamic_cast<NullInpainter*>(inpaint) == 0;
if (doInpainting_)
{
inpainter_->setMotionModel(motionEstimator_->motionModel());
void TwoPassStabilizer::runPrePassIfNecessary()
{
if (!isPrePassDone_)
- {
+ {
// check if we must do wobble suppression
- WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
- doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
+ WobbleSuppressorBase *wobble = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
+ doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobble) == 0;
// estimate motions
for (int i = -radius_; i <= 0; ++i)
at(i, frames_) = firstFrame;
- WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
- doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
+ WobbleSuppressorBase *wobble = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
+ doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobble) == 0;
if (doWobbleSuppression_)
{
wobbleSuppressor_->setFrameCount(frameCount_);