static void computeCorrespsFiltered(const Mat& K, const Mat& K_inv, const Mat& Rt, const Mat& depth0, const Mat& validMask0, const Mat& depth1, const Mat& selectMask1, float maxDepthDiff, Mat& corresps, const Mat& normals0, const Mat& transformedNormals1, const Mat& image0, const Mat& image1) { const double maxNormalsDiff = 30; // in degrees const double maxColorDiff = 50; const double maxNormalAngleDev = 75; // in degrees computeCorresps(K, K_inv, Rt, depth0, validMask0, depth1, selectMask1, maxDepthDiff, corresps); const Point3f Oz_inv(0,0,-1); // TODO replace by vector to camera position? for(int v0 = 0; v0 < corresps.rows; v0++) { for(int u0 = 0; u0 < corresps.cols; u0++) { int c = corresps.at<int>(v0, u0); if(c != -1) { Point3f curNormal = normals0.at<Point3f>(v0,u0); curNormal *= 1./cv::norm(curNormal); if(std::abs(curNormal.ddot(Oz_inv)) < std::cos(maxNormalAngleDev / 180 * CV_PI)) { corresps.at<int>(v0, u0) = -1; continue; } int u1, v1; get2shorts(c, u1, v1); Point3f transfPrevNormal = transformedNormals1.at<Point3f>(v1,u1); transfPrevNormal *= 1./cv::norm(transfPrevNormal); if(std::abs(curNormal.ddot(transfPrevNormal)) < std::cos(maxNormalsDiff / 180 * CV_PI)) { corresps.at<int>(v0, u0) = -1; continue; } if(std::abs(image0.at<uchar>(v0,u0) - image1.at<uchar>(v1,u1)) > maxColorDiff) { corresps.at<int>(v0, u0) = -1; continue; } } } } }
static Mat angularError( const Mat_<Point2f>& flow1, const Mat_<Point2f>& flow2 ) { Mat result(flow1.size(), CV_32FC1); for ( int i = 0; i < flow1.rows; ++i ) { for ( int j = 0; j < flow1.cols; ++j ) { const Point2f u1_2d = flow1(i, j); const Point2f u2_2d = flow2(i, j); const Point3f u1(u1_2d.x, u1_2d.y, 1); const Point3f u2(u2_2d.x, u2_2d.y, 1); if ( isFlowCorrect(u1) && isFlowCorrect(u2) ) result.at<float>(i, j) = acos((float)(u1.ddot(u2) / norm(u1) * norm(u2))); else result.at<float>(i, j) = std::numeric_limits<float>::quiet_NaN(); } } return result; }