SimpleRectangleFinder.cpp

00001 /*
00002  * SimpleRectangleFinder.cpp
00003  *
00004  *  Created on: Feb 20, 2010
00005  *      Author: uscr
00006  */
00007 
00008 #include "SimpleRectangleFinder.h"
00009 #include <cstdio>
00010 #include <cmath>
00011 
00012 
00013 SimpleRectangleFinder::SimpleRectangleFinder(IplImage * imgRef) {
00014         edges = cvCloneImage(imgRef);
00015         storage = cvCreateMemStorage(0);
00016         approxStorage = cvCreateMemStorage(0);
00017 
00018         contours = 0;
00019         polyPoints = 0;
00020 
00021         //Grab the Camera Calibration Data:
00022         cameraMat = (CvMat*)cvLoad(CV_CALIB_IFILE);
00023         distortMat = (CvMat*)cvLoad(CV_CALIB_DFILE);
00024         mapx = cvCreateImage( cvGetSize( imgRef ), IPL_DEPTH_32F, 1 );
00025         mapy = cvCreateImage( cvGetSize( imgRef ), IPL_DEPTH_32F, 1 );
00026         ideal = cvCreateImage( cvGetSize( imgRef ), IPL_DEPTH_8U, 1 );
00027         cvInitUndistortMap( cameraMat, distortMat, mapx, mapy );
00028 
00029 
00030         for (int i = 0; i < 4; i++) {
00031                 rectDeformCorn.push_back(cvPoint2D32f(0,0));
00032                 rectFlatCorn.push_back(cvPoint2D32f(0,0));
00033         }
00034 
00035 }
00036 
00037 SimpleRectangleFinder::~SimpleRectangleFinder() {
00038         cvReleaseImage (&edges);
00039         cvReleaseImage (&mapx);
00040         cvReleaseImage (&mapy);
00041         cvReleaseImage (&ideal);
00042         cvReleaseMat (&distortMat);
00043         cvReleaseMat (&cameraMat);
00044 
00045 }
00046 
00047 void SimpleRectangleFinder::search(IplImage * subj, int width, int & centerx, int & centery) {
00048 
00049         contours = 0;
00050         polyPoints = 0;
00051         storage = cvCreateMemStorage(0);
00052         approxStorage = cvCreateMemStorage(0);
00053         int area;
00054 
00055         //rather than f'ing around with the stupid cvUndistortPoints method which
00056         // does NOT want to work, let's just do a complete image undistort first
00057         // and ignore have distortion taken care of apriori
00058         //cvRemap(subj, ideal, mapx, mapy);
00059 
00060         //Get lines from the image, clean up the lines, and then find the
00061         // countours from the lines
00062         cvCanny(subj, edges, CANNY_THRESH, CANNY_THRESH, 3);
00063         cvDilate(edges, edges, 0, 1);
00064         cvFindContours(edges, storage, &contours, sizeof(CvContour),
00065                         CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cvPoint(0, 0));
00066 
00067         for (CvSeq* curCont = contours; curCont != NULL; curCont = curCont->h_next) {
00068                 polyPoints = cvApproxPoly(curCont, sizeof(CvContour), approxStorage,
00069                                 CV_POLY_APPROX_DP, cvContourPerimeter(curCont) * POLY_APPROX_ACCURACY, 0);
00070 
00071                 if (polyPoints->total == 4) {
00072                         area = (int) abs(cvContourArea(polyPoints));
00073 
00074                         if (area > AREA_THRESH) {
00075 
00076                                 //Okay, so we think this is the one and we are going to go for it.
00077                                 // Next we need to convert the observed screen coordinates to
00078                                 // ideal screen coordinates.
00079                                 for (int i = 0; i < 4; i++) {
00080                                         rectDeformCorn[i].x = ((CvPoint *) cvGetSeqElem(polyPoints, i))->x;
00081                                         rectDeformCorn[i].y = ((CvPoint *) cvGetSeqElem(polyPoints, i))->y;
00082                                 }
00083 
00084                                 //Compute the center by finding the intersection of the lines
00085                                 // created by the vertices idealized above
00086                                 center[0] = ((rectDeformCorn[0].x*rectDeformCorn[2].y - rectDeformCorn[2].x*rectDeformCorn[0].y)*
00087                                                         (rectDeformCorn[1].x - rectDeformCorn[3].x) -
00088                                                         (rectDeformCorn[1].x*rectDeformCorn[3].y - rectDeformCorn[3].x*rectDeformCorn[1].y)*
00089                                                         (rectDeformCorn[0].x - rectDeformCorn[2].x));
00090                                 center[0] /=    ((rectDeformCorn[0].x - rectDeformCorn[2].x)*
00091                                                                 (rectDeformCorn[1].y - rectDeformCorn[3].y) -
00092                                                                 (rectDeformCorn[1].x - rectDeformCorn[3].x)*
00093                                                                 (rectDeformCorn[0].y - rectDeformCorn[2].y));
00094                                 center[1] = ((rectDeformCorn[0].x*rectDeformCorn[2].y - rectDeformCorn[2].x*rectDeformCorn[0].y)*
00095                                                         (rectDeformCorn[1].y - rectDeformCorn[3].y) -
00096                                                         (rectDeformCorn[1].x*rectDeformCorn[3].y - rectDeformCorn[3].x*rectDeformCorn[1].y)*
00097                                                         (rectDeformCorn[0].y - rectDeformCorn[2].y));
00098                                 center[1] /=    ((rectDeformCorn[0].x - rectDeformCorn[2].x)*
00099                                                                 (rectDeformCorn[1].y - rectDeformCorn[3].y) -
00100                                                                 (rectDeformCorn[1].x - rectDeformCorn[3].x)*
00101                                                                 (rectDeformCorn[0].y - rectDeformCorn[2].y));
00102 
00103                                 centerx = center[0];
00104                                 centery = center[1];
00105 
00106                                 //Ok so this is the square placed at the center of where we are
00107                                 rectFlatCorn[1].x = rectFlatCorn[2].x = center[0] + width/2.0;
00108                                 rectFlatCorn[1].y = rectFlatCorn[0].y = center[1] + width/2.0;
00109                             rectFlatCorn[3].x = rectFlatCorn[0].x = center[0] - width/2.0;
00110                             rectFlatCorn[2].y = rectFlatCorn[3].y = center[1] - width/2.0;
00111 
00112                             //find the perspective transformation:
00113                             CvMat * mapMatrix = cvCreateMat(3, 3, CV_32FC1);
00114                             cvGetPerspectiveTransform (&rectFlatCorn[0], &rectDeformCorn[0], mapMatrix);
00115 
00116                             double angle1 = asin(cvmGet(mapMatrix, 1, 0));
00117                             double angle2 = acos(cvmGet(mapMatrix, 0, 0) / cos(angle1));
00118                             double angle3 = acos(cvmGet(mapMatrix, 1, 1) / cos(angle1));
00119 
00120                             printf("-----------------------------\n");
00121                             printf ("[\t%f\t%f\t%f\t]\n", cvmGet(mapMatrix, 0, 0), cvmGet(mapMatrix, 0, 1), cvmGet(mapMatrix, 0, 2));
00122                             printf ("[\t%f\t%f\t%f\t]\n", cvmGet(mapMatrix, 1, 0), cvmGet(mapMatrix, 1, 1), cvmGet(mapMatrix, 1, 2));
00123                             printf ("[\t%f\t%f\t%f\t]\n", cvmGet(mapMatrix, 2, 0), cvmGet(mapMatrix, 2, 1), cvmGet(mapMatrix, 2, 2));
00124                             //printf ("angle1 = %f\n", angle1);
00125                             //printf ("angle2 = %f\n", angle2);
00126                             //printf ("angle3 = %f\n", angle3);
00127 
00128                             cvReleaseMat(&mapMatrix);
00129                         }
00130                 }
00131         }
00132 
00133         cvReleaseMemStorage(&approxStorage);
00134         cvReleaseMemStorage(&storage);
00135 }
Generated on Sun May 8 08:41:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3