00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <time.h>
00015
00016 #include "outlet_pose_estimation/detail/planar.h"
00017 #include <highgui.h>
00018 #include <stdio.h>
00019
00020 #include <limits>
00021
00022 void gen_3x3_matrix(CvMat* in, CvMat* out)
00023 {
00024 for(int r = 0; r < 2; r++)
00025 {
00026 for(int c = 0; c < 3; c++)
00027 {
00028 float value = cvmGet(in, r, c);
00029 cvmSet(out, r, c, value);
00030 }
00031 }
00032
00033 cvmSet(out, 2, 0, 0.0f);
00034 cvmSet(out, 2, 1, 0.0f);
00035 cvmSet(out, 2, 2, 1.0f);
00036 }
00037
00038 CvPoint2D32f apply_mat(CvMat* mat, CvPoint2D32f vec)
00039 {
00040 CvPoint2D32f res = cvPoint2D32f(cvmGet(mat, 0, 0)*vec.x + cvmGet(mat, 0, 1)*vec.y,
00041 cvmGet(mat, 1, 0)*vec.x + cvmGet(mat, 1, 1)*vec.y);
00042 return(res);
00043 }
00044
00045 CvRect calc_mapped_rectangle(CvMat* mat, CvRect roi)
00046 {
00047 CvPoint2D32f p[4];
00048 p[0] = cvPoint2D32f(roi.x, roi.y);
00049 p[1] = cvPoint2D32f(roi.x + roi.width, roi.y);
00050 p[2] = cvPoint2D32f(roi.x + roi.width, roi.y + roi.height);
00051 p[3] = cvPoint2D32f(roi.x, roi.y + roi.height);
00052
00053 CvPoint2D32f r[4];
00054 for(int i = 0; i < 4; i++)
00055 {
00056 r[i] = apply_mat(mat, p[i]);
00057 }
00058
00059 float xmin = FLT_MAX, xmax = -FLT_MAX, ymin = FLT_MAX, ymax = -FLT_MAX;
00060 for(int i = 0; i < 4; i++)
00061 {
00062 xmin = MIN(xmin, r[i].x);
00063 xmax = MAX(xmax, r[i].x);
00064 ymin = MIN(ymin, r[i].y);
00065 ymax = MAX(ymax, r[i].y);
00066 }
00067
00068 return(cvRect(xmin, ymin, xmax - xmin, ymax - ymin));
00069 }
00070
00071 void copy_cols(CvMat* src, CvMat* dst, int start_col, int end_col)
00072 {
00073 for(int r = 0; r < src->rows; r++)
00074 {
00075 for(int c = start_col; c < end_col; c++)
00076 {
00077 float val = cvmGet(src, r, c);
00078 cvmSet(dst, r, c, val);
00079 }
00080 }
00081 }
00082
00083
00084 CvSize gen_random_homog_transform(CvRect roi, CvMat* mat)
00085 {
00086 CvMat* rt = cvCreateMat(2, 2, CV_32FC1);
00087 CvMat* rp = cvCreateMat(2, 2, CV_32FC1);
00088 CvMat* rpi = cvCreateMat(2, 2, CV_32FC1);
00089 CvMat* s = cvCreateMat(2, 2, CV_32FC1);
00090 CvMat* final = cvCreateMat(2, 2, CV_32FC1);
00091
00092 CvMat* temp = cvCreateMat(2, 3, CV_32FC1);
00093
00094 float phi = (float(rand())/RAND_MAX*2 - 1)*60;
00095 cv2DRotationMatrix(cvPoint2D32f(0, 0), phi, 1, temp);
00096 copy_cols(temp, rp, 0, 2);
00097
00098 cv2DRotationMatrix(cvPoint2D32f(0, 0), -phi, 1, temp);
00099 copy_cols(temp, rpi, 0, 2);
00100
00101 const float max_angle = 30;
00102 float theta = (float(rand())/RAND_MAX*2 - 1)*max_angle;
00103 cv2DRotationMatrix(cvPoint2D32f(0, 0), theta, 1, temp);
00104 copy_cols(temp, rt, 0, 2);
00105
00106 const float smin = 0.8f;
00107 const float smax = 1.3f;
00108 float l1 = float(rand())/RAND_MAX*(smax - smin) + smin;
00109 float l2 = float(rand())/RAND_MAX*(smax - smin) + smin;
00110 cvmSet(s, 0, 0, l1);
00111 cvmSet(s, 0, 1, 0.0f);
00112 cvmSet(s, 1, 0, 0.0f);
00113 cvmSet(s, 1, 1, l2);
00114
00115 cvMatMul(rt, rpi, final);
00116 cvMatMul(final, s, final);
00117 cvMatMul(final, rp, final);
00118
00119 CvRect bound = calc_mapped_rectangle(final, roi);
00120
00121 for(int r = 0; r < 2; r++)
00122 {
00123 for(int c = 0; c < 2; c++)
00124 {
00125 float value = cvmGet(final, r, c);
00126 cvmSet(mat, r, c, value);
00127 }
00128 }
00129
00130 int length = MAX(bound.width, bound.height);
00131 bound.x -= (length - bound.width)/2;
00132 bound.y -= (length - bound.height)/2;
00133
00134 cvmSet(mat, 0, 2, -bound.x);
00135 cvmSet(mat, 1, 2, -bound.y);
00136
00137 cvReleaseMat(&rt);
00138 cvReleaseMat(&rp);
00139 cvReleaseMat(&s);
00140 cvReleaseMat(&rpi);
00141 cvReleaseMat(&temp);
00142 cvReleaseMat(&final);
00143
00144
00145 return cvSize(length, length);
00146 }
00147
00148 void gen_random_homog_patches(IplImage* src, int count, IplImage** dst)
00149 {
00150 srand(clock());
00151
00152 CvRect roi = cvGetImageROI(src);
00153 cvResetImageROI(src);
00154
00155 CvMat* transform = cvCreateMat(2, 3, CV_32FC1);
00156 for(int i = 0; i < count; i++)
00157 {
00158 CvSize size = gen_random_homog_transform(roi, transform);
00159 dst[i] = cvCreateImage(size, IPL_DEPTH_8U, 1);
00160 cvWarpAffine(src, dst[i], transform);
00161 cvEqualizeHist(dst[i], dst[i]);
00162 }
00163 cvSetImageROI(src, roi);
00164
00165 cvReleaseMat(&transform);
00166 }
00167
00168 void save_image_array(const char* folder, const char* filename, int count, IplImage** images)
00169 {
00170 for(int i = 0; i < count; i++)
00171 {
00172 char buf[1024];
00173 sprintf(buf, "%s/%s_%d.jpg", folder, filename, i);
00174 cvSaveImage(buf, images[i]);
00175 }
00176 }
00177
00178 void release_image_array(int count, IplImage** images)
00179 {
00180 for(int i = 0; i < count; i++)
00181 {
00182 cvReleaseImage(&images[i]);
00183 }
00184 }
00185 void test_homog_transform(IplImage* src)
00186 {
00187 const int count = 30;
00188 IplImage* images[count];
00189 gen_random_homog_patches(src, count, images);
00190 save_image_array("../../patches", "", count, images);
00191 release_image_array(count, images);
00192 }
00193
00194 namespace cv{
00195
00196
00197
00198
00199
00200
00201
00202
00203 void findPlanarObjectPose(const Mat& object_points, const Mat& image_points, const Point3f& normal,
00204 const Mat& intrinsic_matrix, const Mat& distortion_coeffs, std::vector<Point3f>& object_points_crf)
00205 {
00206 vector<Point2f> _rays;
00207 undistortPoints(image_points, _rays, intrinsic_matrix, distortion_coeffs);
00208
00209
00210 vector<Point3f> rays;
00211 for(size_t i = 0; i < _rays.size(); i++)
00212 {
00213 double proj = rays[i].dot(normal);
00214 if(fabs(proj) > std::numeric_limits<double>::epsilon())
00215 {
00216 rays.push_back(Point3f(_rays[i].x, _rays[i].y, 1.0f));
00217 }
00218 }
00219
00220 Point3f pm(0.0f, 0.0f, 0.0f);
00221 for(size_t i = 0; i < rays.size(); i++)
00222 {
00223 pm = pm + rays[i]*(1.0/rays[i].dot(normal));
00224 }
00225
00226 pm = -pm*(1.0/rays.size());
00227
00228 double dev = 0.0;
00229 for(size_t i = 0; i < rays.size(); i++)
00230 {
00231 Point3f pdev = rays[i]*(1.0/rays[i].dot(normal)) - pm;
00232 dev += pdev.dot(pdev);
00233 }
00234
00235 double C = -1.0/sqrt(dev);
00236
00237 object_points_crf.resize(rays.size());
00238 for(size_t i = 0; i < rays.size(); i++)
00239 {
00240 object_points_crf[i] = -rays[i]*(C/rays[i].dot(normal));
00241 }
00242 }
00243
00244 };