void AdaptiveManifoldFilterN::computeEigenVector(const vector<Mat>& X, const Mat1b& mask, Mat1f& vecDst, int num_pca_iterations, const Mat1f& vecRand) { int cnNum = (int)X.size(); int height = X[0].rows; int width = X[0].cols; vecDst.create(1, cnNum); CV_Assert(vecRand.size() == Size(cnNum, 1) && vecDst.size() == Size(cnNum, 1)); CV_Assert(mask.rows == height && mask.cols == width); const float *pVecRand = vecRand.ptr<float>(); Mat1d vecDstd(1, cnNum, 0.0); double *pVecDst = vecDstd.ptr<double>(); Mat1f Xw(height, width); for (int iter = 0; iter < num_pca_iterations; iter++) { for (int i = 0; i < height; i++) { const uchar *maskRow = mask.ptr<uchar>(i); float *mulRow = Xw.ptr<float>(i); //first multiplication for (int cn = 0; cn < cnNum; cn++) { const float *srcRow = X[cn].ptr<float>(i); const float cnVal = pVecRand[cn]; if (cn == 0) { for (int j = 0; j < width; j++) mulRow[j] = cnVal*srcRow[j]; } else { for (int j = 0; j < width; j++) mulRow[j] += cnVal*srcRow[j]; } } for (int j = 0; j < width; j++) if (!maskRow[j]) mulRow[j] = 0.0f; //second multiplication for (int cn = 0; cn < cnNum; cn++) { float curCnSum = 0.0f; const float *srcRow = X[cn].ptr<float>(i); for (int j = 0; j < width; j++) curCnSum += mulRow[j]*srcRow[j]; //TODO: parallel reduce pVecDst[cn] += curCnSum; } } } divide(vecDstd, norm(vecDstd), vecDst); }
void AdaptiveManifoldFilterN::computeOrientation(const vector<Mat>& X, const Mat1f& vec, Mat1f& dst) { int height = X[0].rows; int width = X[0].cols; int cnNum = (int)X.size(); dst.create(height, width); CV_DbgAssert(vec.rows == 1 && vec.cols == cnNum); const float *pVec = vec.ptr<float>(); for (int i = 0; i < height; i++) { float *dstRow = dst.ptr<float>(i); for (int cn = 0; cn < cnNum; cn++) { const float *srcRow = X[cn].ptr<float>(i); const float cnVal = pVec[cn]; if (cn == 0) { for (int j = 0; j < width; j++) dstRow[j] = cnVal*srcRow[j]; } else { for (int j = 0; j < width; j++) dstRow[j] += cnVal*srcRow[j]; } } } }
void computeEigenVector(const Mat1f& X, const Mat1b& mask, Mat1f& dst, int num_pca_iterations, const Mat1f& rand_vec) { CV_DbgAssert( X.cols == rand_vec.cols ); CV_DbgAssert( X.rows == mask.size().area() ); CV_DbgAssert( rand_vec.rows == 1 ); dst.create(rand_vec.size()); rand_vec.copyTo(dst); Mat1f t(X.size()); float* dst_row = dst[0]; for (int i = 0; i < num_pca_iterations; ++i) { t.setTo(Scalar::all(0)); for (int y = 0, ind = 0; y < mask.rows; ++y) { const uchar* mask_row = mask[y]; for (int x = 0; x < mask.cols; ++x, ++ind) { if (mask_row[x]) { const float* X_row = X[ind]; float* t_row = t[ind]; float dots = 0.0; for (int c = 0; c < X.cols; ++c) dots += dst_row[c] * X_row[c]; for (int c = 0; c < X.cols; ++c) t_row[c] = dots * X_row[c]; } } } dst.setTo(0.0); for (int k = 0; k < X.rows; ++k) { const float* t_row = t[k]; for (int c = 0; c < X.cols; ++c) { dst_row[c] += t_row[c]; } } } double n = norm(dst); divide(dst, n, dst); }
void smoothDepth( const Mat1f &scale_map, const Mat1d &ii_depth_map, const Mat_<uint32_t>& ii_depth_count, float base_scale, Mat1f &depth_out ) { float nan = std::numeric_limits<float>::quiet_NaN(); depth_out.create( ii_depth_map.rows-1, ii_depth_map.cols-1 ); for ( int y = 0; y < ii_depth_map.rows-1; y++ ) { for ( int x = 0; x < ii_depth_map.cols-1; ++x ) { float s = scale_map[y][x] * base_scale + 0.5f; if ( isnan(s) ) { depth_out(y,x) = nan; continue; } if ( s < 5 ) s=5; const int s_floor = s; const float t = s - s_floor; if ( !checkBounds( ii_depth_map, x, y, 1 ) ) { depth_out(y,x) = nan; continue; } depth_out(y,x) = (1.0-t) * meanDepth( ii_depth_map, ii_depth_count, x, y, s_floor ) + t * meanDepth( ii_depth_map, ii_depth_count, x, y, s_floor+1 ); } } }