PageRenderTime 39ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/ot/newfisheye.cpp

https://github.com/aiwenar/Eyes
C++ | 164 lines | 134 code | 25 blank | 5 comment | 10 complexity | ed0d3c046d1e8affee9f8512ab677625 MD5 | raw file
  1. #include <math.h>
  2. #include <unistd.h>
  3. #include <getopt.h>
  4. #include <iostream>
  5. #include <opencv2/opencv.hpp>
  6. #include <opencv2/contrib/contrib.hpp>
  7. #include <vector>
  8. #include <algorithm>
  9. #define mane main
  10. #define REP(x,n) for(int x=0; x<n; x++)
  11. #define FOR(x,b,e) for(int x=b; x<=e; x++)
  12. #define ST first
  13. #define ND second
  14. #define PB push_back
  15. #define MP make_pair
  16. using namespace std;
  17. using namespace cv;
  18. struct mirror
  19. {
  20. bool processMirror(IplImage * src);
  21. void init_mirrors(IplImage * srcExample),
  22. sampleImage(const IplImage* arr, double idx0, double idx1, CvScalar& res),
  23. fisheye(IplImage*src, double distortion, pair <int, int> center);
  24. double calc_shift(double x1,double x2,double cx,double k);
  25. pair <double, double>
  26. getRadial(double x,double y,double cx,double cy,double k);
  27. CvRect mirrorLsrc,
  28. mirrorRsrc,
  29. mirrorWorkspace;
  30. CvSize mirrorLsize,
  31. mirrorRsize;
  32. IplImage * mirrorL,
  33. * mirrorR,
  34. * prevMirror;
  35. pair <int, int> aspectCorrection;
  36. pair<double, double>
  37. aspect,
  38. scale,
  39. shift;
  40. double mirrorL2Diff;
  41. };
  42. void mirror::sampleImage(const IplImage *arr, double idx0, double idx1, CvScalar &res)
  43. {
  44. if(idx0<0 || idx1<0 || idx0>(cvGetSize(arr).height-1) || idx1>(cvGetSize(arr).width-1))
  45. {
  46. res.val[0]=0;
  47. res.val[1]=0;
  48. res.val[2]=0;
  49. res.val[3]=0;
  50. return;
  51. }
  52. double idx0_fl=floor(idx0);
  53. double idx0_cl=ceil(idx0);
  54. double idx1_fl=floor(idx1);
  55. double idx1_cl=ceil(idx1);
  56. CvScalar s1=cvGet2D(arr,(int)idx0_fl,(int)idx1_fl);
  57. CvScalar s2=cvGet2D(arr,(int)idx0_fl,(int)idx1_cl);
  58. CvScalar s3=cvGet2D(arr,(int)idx0_cl,(int)idx1_cl);
  59. CvScalar s4=cvGet2D(arr,(int)idx0_cl,(int)idx1_fl);
  60. double x = idx0 - idx0_fl;
  61. double y = idx1 - idx1_fl;
  62. res.val[0]= s1.val[0]*(1-x)*(1-y) + s2.val[0]*(1-x)*y + s3.val[0]*x*y + s4.val[0]*x*(1-y);
  63. res.val[1]= s1.val[1]*(1-x)*(1-y) + s2.val[1]*(1-x)*y + s3.val[1]*x*y + s4.val[1]*x*(1-y);
  64. res.val[2]= s1.val[2]*(1-x)*(1-y) + s2.val[2]*(1-x)*y + s3.val[2]*x*y + s4.val[2]*x*(1-y);
  65. res.val[3]= s1.val[3]*(1-x)*(1-y) + s2.val[3]*(1-x)*y + s3.val[3]*x*y + s4.val[3]*x*(1-y);
  66. }
  67. pair <double, double> mirror::getRadial(double x, double y, double cx, double cy, double k)
  68. {
  69. x = (x*scale.ST+shift.ST);
  70. y = (y*scale.ND+shift.ND);
  71. double resX = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
  72. double resY = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
  73. return make_pair(resX, resY);
  74. }
  75. double mirror::calc_shift(double x1, double x2, double cx, double k)
  76. {
  77. double thresh = 1;
  78. double x3 = x1+(x2-x1)*0.5;
  79. double res1 = x1+((x1-cx)*k*((x1-cx)*(x1-cx)));
  80. double res3 = x3+((x3-cx)*k*((x3-cx)*(x3-cx)));
  81. // std::cerr<<"x1: "<<x1<<" - "<<res1<<" x3: "<<x3<<" - "<<res3<<std::endl;
  82. if(res1>-thresh and res1 < thresh)
  83. return x1;
  84. if(res3<0)
  85. {
  86. return calc_shift(x3,x2,cx,k);
  87. }
  88. else
  89. {
  90. return calc_shift(x1,x3,cx,k);
  91. }
  92. }
  93. void mirror::fisheye(IplImage *src, double distortion, pair<int, int> center)
  94. {
  95. IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
  96. double centerX=(double)(center.ST*src->width)/100.0;
  97. double centerY=(double)(center.ND*src->height)/100.0;
  98. int width = src->width;
  99. int height = src->height;
  100. shift.ST = calc_shift(0,centerX-1,centerX,distortion);
  101. double newcenterX = width-centerX;
  102. pair <double, double> shift_2;
  103. shift_2.ST = calc_shift(0,newcenterX-1,newcenterX,distortion);
  104. shift.ND = calc_shift(0,centerY-1,centerY,distortion);
  105. double newcenterY = height-centerY;
  106. shift_2.ND = calc_shift(0,newcenterY-1,newcenterY,distortion);
  107. scale.ST = (width-shift.ST-shift_2.ST)/width;
  108. scale.ND = (height-shift.ND-shift_2.ND)/height;
  109. //std::cerr<<xshift<<" "<<shift.ND<<" "<<xscale<<" "<<yscale<<std::endl;
  110. //std::cerr<<cvGetSize(src).height<<std::endl;
  111. //std::cerr<<cvGetSize(src).width<<std::endl;
  112. for(int j=0;j<cvGetSize(dst).height;j++)
  113. {
  114. for(int i=0;i<cvGetSize(dst).width;i++)
  115. {
  116. CvScalar s;
  117. pair <double, double> xy;
  118. xy = getRadial((double)i,(double)j,centerX,centerY,distortion);
  119. sampleImage(src,xy.ND,xy.ST,s);
  120. cvSet2D(dst,j,i,s);
  121. }
  122. }
  123. cvReleaseImage(&src);
  124. src = cvCloneImage(dst);
  125. }
  126. int mane(int argc, char** argv)
  127. {
  128. mirror mir;
  129. IplImage* src = cvLoadImage( argv[1], 1 );
  130. IplImage* newd;
  131. newd = cvCloneImage(src);
  132. mir.fisheye(newd, 0.00001, make_pair(50, 50));
  133. //cv::blur(cv::Mat(newd), cv::Mat(newd), cvSize(9, 5));
  134. cv::GaussianBlur(cv::Mat(newd), cv::Mat(newd), cvSize(9*1.8 + (1 - int(9*1.8) % 2), 5*1.8 + (1 - int(5*1.8) % 2)), 0, 0);
  135. cv::Mat source;
  136. cv::GaussianBlur(cv::Mat(newd), source, cvSize(50*1.8 + (1 - int(50*1.8) % 2), 30*1.8 + (1 - int(30*1.8) % 2)), 0, 0);
  137. addWeighted(cv::Mat(newd), 0.55, source, 0.45, 0, cv::Mat(newd));
  138. cvSaveImage(argv[2],newd,0);
  139. }