Note that there are some explanatory texts on larger screens.

plurals
  1. POCamera motion compensation
    text
    copied!<p>I am using openCV to implementing camera motion compensation for an application. I know I need to calculate the optical flow and then find the fundamental matrix between two frames to transform the image.</p> <p>Here is what I have done so far:</p> <pre><code>void VideoStabilization::stabilize(Image *image) { if (image-&gt;getWidth() != width || image-&gt;getHeight() != height) reset(image-&gt;getWidth(), image-&gt;getHeight()); IplImage *currImage = toCVImage(image); IplImage *currImageGray = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); cvCvtColor(currImage, currImageGray, CV_BGRA2GRAY); if (baseImage) { CvPoint2D32f currFeatures[MAX_CORNERS]; char featuresFound[MAX_CORNERS]; opticalFlow(currImageGray, currFeatures, featuresFound); IplImage *result = transformImage(currImage, currFeatures, featuresFound); if (result) { updateImage(image, result); cvReleaseImage(&amp;result); } } cvReleaseImage(&amp;currImage); if (baseImage) cvReleaseImage(&amp;baseImage); baseImage = currImageGray; updateGoodFeatures(); } void VideoStabilization::updateGoodFeatures() { const double QUALITY_LEVEL = 0.05; const double MIN_DISTANCE = 5.0; baseFeaturesCount = MAX_CORNERS; cvGoodFeaturesToTrack(baseImage, eigImage, tempImage, baseFeatures, &amp;baseFeaturesCount, QUALITY_LEVEL, MIN_DISTANCE); cvFindCornerSubPix(baseImage, baseFeatures, baseFeaturesCount, cvSize(10, 10), cvSize(-1,-1), TERM_CRITERIA); } void VideoStabilization::opticalFlow(IplImage *currImage, CvPoint2D32f *currFeatures, char *featuresFound) { const unsigned int WIN_SIZE = 15; const unsigned int PYR_LEVEL = 5; cvCalcOpticalFlowPyrLK(baseImage, currImage, NULL, NULL, baseFeatures, currFeatures, baseFeaturesCount, cvSize(WIN_SIZE, WIN_SIZE), PYR_LEVEL, featuresFound, NULL, TERM_CRITERIA, 0); } IplImage *VideoStabilization::transformImage(IplImage *image, CvPoint2D32f *features, char *featuresFound) const { unsigned int featuresFoundCount = 0; for (unsigned int i = 0; i &lt; MAX_CORNERS; ++i) { if (featuresFound[i]) ++featuresFoundCount; } if (featuresFoundCount &lt; 8) { std::cout &lt;&lt; "Not enough features found." &lt;&lt; std::endl; return NULL; } CvMat *points1 = cvCreateMat(2, featuresFoundCount, CV_32F); CvMat *points2 = cvCreateMat(2, featuresFoundCount, CV_32F); CvMat *fundamentalMatrix = cvCreateMat(3, 3, CV_32F); unsigned int pos = 0; for (unsigned int i = 0; i &lt; featuresFoundCount; ++i) { while (!featuresFound[pos]) ++pos; cvSetReal2D(points1, 0, i, baseFeatures[pos].x); cvSetReal2D(points1, 1, i, baseFeatures[pos].y); cvSetReal2D(points2, 0, i, features[pos].x); cvSetReal2D(points2, 1, i, features[pos].y); ++pos; } int fmCount = cvFindFundamentalMat(points1, points2, fundamentalMatrix, CV_FM_RANSAC, 1.0, 0.99); if (fmCount &lt; 1) { std::cout &lt;&lt; "Fundamental matrix not found." &lt;&lt; std::endl; return NULL; } std::cout &lt;&lt; fundamentalMatrix-&gt;data.fl[0] &lt;&lt; " " &lt;&lt; fundamentalMatrix-&gt;data.fl[1] &lt;&lt; " " &lt;&lt; fundamentalMatrix-&gt;data.fl[2] &lt;&lt; "\n"; std::cout &lt;&lt; fundamentalMatrix-&gt;data.fl[3] &lt;&lt; " " &lt;&lt; fundamentalMatrix-&gt;data.fl[4] &lt;&lt; " " &lt;&lt; fundamentalMatrix-&gt;data.fl[5] &lt;&lt; "\n"; std::cout &lt;&lt; fundamentalMatrix-&gt;data.fl[6] &lt;&lt; " " &lt;&lt; fundamentalMatrix-&gt;data.fl[7] &lt;&lt; " " &lt;&lt; fundamentalMatrix-&gt;data.fl[8] &lt;&lt; "\n"; cvReleaseMat(&amp;points1); cvReleaseMat(&amp;points2); IplImage *result = transformImage(image, *fundamentalMatrix); cvReleaseMat(&amp;fundamentalMatrix); return result; } </code></pre> <p>MAX_CORNERS is 100 and it usually find around 70-90 features.</p> <p>With this code, I get a weird fundamental matrix, like:</p> <pre><code>-0.000190809 -0.00114947 1.2487 0.00127824 6.57727e-05 0.326055 -1.22443 -0.338243 1 </code></pre> <p>Since I just hold the camera with my hand and try not to shake it (and there werent any objects moving), I expected the matrix to be close to identity. What am I doing wrong?</p> <p>Also, I'm not sure what to use to transform the image. cvWarpAffine need a 2x3 matrix, should I discard the last row or use another function?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload