IMPEM2D_BEGIN_NAMESPACE ResultAlign2D get_complete_alignment(const cv::Mat &input, cv::Mat &m_to_align, bool apply) { IMP_LOG_TERSE("starting complete 2D alignment " << std::endl); cv::Mat autoc1, autoc2, aux1, aux2, aux3; algebra::Transformation2D transformation1, transformation2; ResultAlign2D RA; get_autocorrelation2d(input, autoc1); get_autocorrelation2d(m_to_align, autoc2); RA = get_rotational_alignment(autoc1, autoc2, false); double angle1 = RA.first.get_rotation().get_angle(); get_transformed(m_to_align, aux1, RA.first); // rotate RA = get_translational_alignment(input, aux1); algebra::Vector2D shift1 = RA.first.get_translation(); transformation1.set_rotation(angle1); transformation1.set_translation(shift1); get_transformed(m_to_align, aux2, transformation1); double ccc1 = get_cross_correlation_coefficient(input, aux2); // Check for both angles that can be the solution double angle2; if (angle1 < PI) { angle2 = angle1 + PI; } else { angle2 = angle1 - PI; } // rotate algebra::Rotation2D R2(angle2); algebra::Transformation2D tr(R2); get_transformed(m_to_align, aux3, tr); RA = get_translational_alignment(input, aux3); algebra::Vector2D shift2 = RA.first.get_translation(); transformation2.set_rotation(angle2); transformation2.set_translation(shift2); get_transformed(m_to_align, aux3, transformation2); double ccc2 = get_cross_correlation_coefficient(input, aux3); if (ccc2 > ccc1) { if (apply) { aux3.copyTo(m_to_align); } IMP_LOG_VERBOSE(" Transformation= " << transformation2 << " cross_correlation = " << ccc2 << std::endl); return em2d::ResultAlign2D(transformation2, ccc2); } else { if (apply) { aux2.copyTo(m_to_align); } IMP_LOG_VERBOSE(" Transformation= " << transformation1 << " cross_correlation = " << ccc1 << std::endl); return em2d::ResultAlign2D(transformation1, ccc1); } }
ResultAlign2D get_rotational_alignment(const cv::Mat &input, cv::Mat &m_to_align,bool apply) { IMP_LOG_TERSE( "starting 2D rotational alignment" << std::endl); IMP_USAGE_CHECK((input.rows==m_to_align.rows) && (input.cols==m_to_align.cols), "em2d::align_rotational: Matrices have different size."); cv::Mat polar1,polar2,corr; // Build maps for resampling PolarResamplingParameters polar_params(input.rows,input.cols); polar_params.set_estimated_number_of_angles(std::min(input.rows,input.cols)); polar_params.create_maps_for_resampling(); do_resample_polar(input,polar1,polar_params); // subject image do_resample_polar(m_to_align,polar2,polar_params); // projection image ResultAlign2D RA= get_translational_alignment(polar1,polar2); algebra::Vector2D shift=RA.first.get_translation(); // column shift[0] is the optimal angle to bring m_to_align to input double angle =shift[0]*polar_params.get_angle_step(); RA.first.set_rotation(angle); RA.first.set_translation(algebra::Vector2D(0.0,0.0)); // Apply the rotation if requested if(apply) { cv::Mat result; get_transformed(m_to_align,result,RA.first); result.copyTo(m_to_align); } IMP_LOG_VERBOSE("Rotational alingment: Transformation= " << RA.first << " cross_correlation = " << RA.second << std::endl); return RA; }