int Mosaic::balanceRotations() { // Normalize to the mean angle of rotation (Smiley face) double sineAngle = 0.0; for (int i = 0; i < frames_size; i++) sineAngle += frames[i]->trs[0][1]; sineAngle /= frames_size; // Calculate the cosineAngle (1 - sineAngle*sineAngle) = cosineAngle*cosineAngle double cosineAngle = sqrt(1.0 - sineAngle*sineAngle); double m[3][3] = { { cosineAngle, -sineAngle, 0 }, { sineAngle, cosineAngle, 0}, { 0, 0, 1}}; double tmp[3][3]; for (int i = 0; i < frames_size; i++) { memcpy(tmp, frames[i]->trs, sizeof(tmp)); mult33d(frames[i]->trs, m, tmp); } return MOSAIC_RET_OK; }
// Get current transformation int Align::getLastTRS(double trs[3][3]) { if (frame_number < 1) { trs[0][0] = 1.0; trs[0][1] = 0.0; trs[0][2] = 0.0; trs[1][0] = 0.0; trs[1][1] = 1.0; trs[1][2] = 0.0; trs[2][0] = 0.0; trs[2][1] = 0.0; trs[2][2] = 1.0; return ALIGN_RET_ERROR; } // Note that the logic here handles the case, where a frame is not used for // mosaicing but is captured and used in the preview-rendering. // For these frames, we don't set Hcurr to identity in AddFrame() and the // logic here appends their transformation to Hprev to render them with the // correct transformation. For the frames we do use for mosaicing, we already // append their Hcurr to Hprev in AddFrame() and then set Hcurr to identity. double Hinv33[3][3]; double Hprev33[3][3]; double Hcurr33[3][3]; Matrix33::convert9to33(Hcurr33, Hcurr); normProjMat33d(Hcurr33); inv33d(Hcurr33, Hinv33); Matrix33::convert9to33(Hprev33, Hprev); mult33d(trs, Hprev33, Hinv33); normProjMat33d(trs); return ALIGN_RET_OK; }
int Align::addFrame(ImageType imageGray_) { int ret_code = ALIGN_RET_OK; // Obtain a vector of pointers to rows in image and pass in to dbreg ImageType *m_rows = ImageUtils::imageTypeToRowPointers(imageGray_, width, height); if (frame_number == 0) { reg.AddFrame(m_rows, Hcurr, true); // Force this to be a reference frame int num_corner_ref = reg.GetNrRefCorners(); if (num_corner_ref < MIN_NR_REF_CORNERS) { return ALIGN_RET_LOW_TEXTURE; } } else { reg.AddFrame(m_rows, Hcurr, false); } // Average translation per frame = // [Translation from Frame0 to Frame(n-1)] / [(n-1)] average_tx_per_frame = (num_frames_captured < 2) ? 0.0 : Hprev[2] / (num_frames_captured - 1); // Increment the captured frame counter if we already have a reference frame num_frames_captured++; if (frame_number != 0) { int num_inliers = reg.GetNrInliers(); if(num_inliers < MIN_NR_INLIERS) { ret_code = ALIGN_RET_FEW_INLIERS; Hcurr[0] = 1.0; Hcurr[1] = 0.0; // Set this as the average per frame translation taking into acccount // the separation of the current frame from the reference frame... Hcurr[2] = -average_tx_per_frame * (num_frames_captured - reference_frame_index); Hcurr[3] = 0.0; Hcurr[4] = 1.0; Hcurr[5] = 0.0; Hcurr[6] = 0.0; Hcurr[7] = 0.0; Hcurr[8] = 1.0; } if(fabs(Hcurr[2])<thresh_still && fabs(Hcurr[5])<thresh_still) // Still camera { return ALIGN_RET_ERROR; } // compute the homography: double Hinv33[3][3]; double Hprev33[3][3]; double Hcurr33[3][3]; // Invert and multiple with previous transformation Matrix33::convert9to33(Hcurr33, Hcurr); Matrix33::convert9to33(Hprev33, Hprev); normProjMat33d(Hcurr33); inv33d(Hcurr33, Hinv33); mult33d(Hcurr33, Hprev33, Hinv33); normProjMat33d(Hcurr33); Matrix9::convert33to9(Hprev, Hcurr33); // Since we have already factored the current transformation // into Hprev, we can reset the Hcurr to identity db_Identity3x3(Hcurr); // Update the reference frame to be the current frame reg.UpdateReference(m_rows,quarter_res,false); // Update the reference frame index reference_frame_index = num_frames_captured; } frame_number++; return ret_code; }