当前位置:   article > 正文

OPENCV视频去抖动_openpose 平滑

openpose 平滑
  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. #include <cassert>
  4. #include <cmath>
  5. #include <fstream>
  6. using namespace std;
  7. using namespace cv;
  8. // This video stablisation smooths the global trajectory using a sliding average window
  9. //const int SMOOTHING_RADIUS = 15; // In frames. The larger the more stable the video, but less reactive to sudden panning
  10. const int HORIZONTAL_BORDER_CROP = 20; // In pixels. Crops the border to reduce the black borders from stabilisation being too noticeable.
  11. // 1. Get previous to current frame transformation (dx, dy, da) for all frames
  12. // 2. Accumulate the transformations to get the image trajectory
  13. // 3. Smooth out the trajectory using an averaging window
  14. // 4. Generate new set of previous to current transform, such that the trajectory ends up being the same as the smoothed trajectory
  15. // 5. Apply the new transformation to the video
  16. struct TransformParam
  17. {
  18. TransformParam() {}
  19. TransformParam(double _dx, double _dy, double _da) {
  20. dx = _dx;
  21. dy = _dy;
  22. da = _da;
  23. }
  24. double dx;
  25. double dy;
  26. double da; // angle
  27. };
  28. struct Trajectory
  29. {
  30. Trajectory() {}
  31. Trajectory(double _x, double _y, double _a) {
  32. x = _x;
  33. y = _y;
  34. a = _a;
  35. }
  36. // "+"
  37. friend Trajectory operator+(const Trajectory &c1,const Trajectory &c2){
  38. return Trajectory(c1.x+c2.x,c1.y+c2.y,c1.a+c2.a);
  39. }
  40. //"-"
  41. friend Trajectory operator-(const Trajectory &c1,const Trajectory &c2){
  42. return Trajectory(c1.x-c2.x,c1.y-c2.y,c1.a-c2.a);
  43. }
  44. //"*"
  45. friend Trajectory operator*(const Trajectory &c1,const Trajectory &c2){
  46. return Trajectory(c1.x*c2.x,c1.y*c2.y,c1.a*c2.a);
  47. }
  48. //"/"
  49. friend Trajectory operator/(const Trajectory &c1,const Trajectory &c2){
  50. return Trajectory(c1.x/c2.x,c1.y/c2.y,c1.a/c2.a);
  51. }
  52. //"="
  53. Trajectory operator =(const Trajectory &rx){
  54. x = rx.x;
  55. y = rx.y;
  56. a = rx.a;
  57. return Trajectory(x,y,a);
  58. }
  59. double x;
  60. double y;
  61. double a; // angle
  62. };
  63. //
  64. int main(int argc, char **argv)
  65. {
  66. // For further analysis
  67. ofstream out_transform("prev_to_cur_transformation.txt");
  68. ofstream out_trajectory("trajectory.txt");
  69. ofstream out_smoothed_trajectory("smoothed_trajectory.txt");
  70. ofstream out_new_transform("new_prev_to_cur_transformation.txt");
  71. VideoCapture cap("F:\\OPENCV实验室\\test9.avi");
  72. assert(cap.isOpened());
  73. Mat cur, cur_grey;
  74. Mat prev, prev_grey;
  75. cap >> prev;//get the first frame.ch
  76. cvtColor(prev, prev_grey, COLOR_BGR2GRAY);
  77. // Step 1 - Get previous to current frame transformation (dx, dy, da) for all frames
  78. vector <TransformParam> prev_to_cur_transform; // previous to current
  79. // Accumulated frame to frame transform
  80. double a = 0;
  81. double x = 0;
  82. double y = 0;
  83. // Step 2 - Accumulate the transformations to get the image trajectory
  84. vector <Trajectory> trajectory; // trajectory at all frames
  85. //
  86. // Step 3 - Smooth out the trajectory using an averaging window
  87. vector <Trajectory> smoothed_trajectory; // trajectory at all frames
  88. Trajectory X;//posteriori state estimate
  89. Trajectory X_;//priori estimate
  90. Trajectory P;// posteriori estimate error covariance
  91. Trajectory P_;// priori estimate error covariance
  92. Trajectory K;//gain
  93. Trajectory z;//actual measurement
  94. double pstd = 4e-3;//can be changed
  95. double cstd = 0.25;//can be changed
  96. Trajectory Q(pstd,pstd,pstd);// process noise covariance
  97. Trajectory R(cstd,cstd,cstd);// measurement noise covariance
  98. // Step 4 - Generate new set of previous to current transform, such that the trajectory ends up being the same as the smoothed trajectory
  99. vector <TransformParam> new_prev_to_cur_transform;
  100. //
  101. // Step 5 - Apply the new transformation to the video
  102. //cap.set(CV_CAP_PROP_POS_FRAMES, 0);
  103. Mat T(2,3,CV_64F);
  104. int vert_border = HORIZONTAL_BORDER_CROP * prev.rows / prev.cols; // get the aspect ratio correct
  105. VideoWriter outputVideo;
  106. outputVideo.open("compare.avi" , CV_FOURCC('X','V','I','D'), 24,cvSize(cur.rows, cur.cols*2+10), true);
  107. //
  108. int k=1;
  109. int max_frames = cap.get(CV_CAP_PROP_FRAME_COUNT);
  110. Mat last_T;
  111. Mat prev_grey_,cur_grey_;
  112. while(true) {
  113. cap >> cur;
  114. if(cur.data == NULL) {
  115. break;
  116. }
  117. cvtColor(cur, cur_grey, COLOR_BGR2GRAY);
  118. // vector from prev to cur
  119. vector <Point2f> prev_corner, cur_corner;
  120. vector <Point2f> prev_corner2, cur_corner2;
  121. vector <uchar> status;
  122. vector <float> err;
  123. goodFeaturesToTrack(prev_grey, prev_corner, 200, 0.01, 30);
  124. calcOpticalFlowPyrLK(prev_grey, cur_grey, prev_corner, cur_corner, status, err);
  125. // weed out bad matches
  126. for(size_t i=0; i < status.size(); i++) {
  127. if(status[i]) {
  128. prev_corner2.push_back(prev_corner[i]);
  129. cur_corner2.push_back(cur_corner[i]);
  130. }
  131. }
  132. // translation + rotation only
  133. Mat T = estimateRigidTransform(prev_corner2, cur_corner2, false); // false = rigid transform, no scaling/shearing
  134. // in rare cases no transform is found. We'll just use the last known good transform.
  135. if(T.data == NULL) {
  136. last_T.copyTo(T);
  137. }
  138. T.copyTo(last_T);
  139. // decompose T
  140. double dx = T.at<double>(0,2);
  141. double dy = T.at<double>(1,2);
  142. double da = atan2(T.at<double>(1,0), T.at<double>(0,0));
  143. //
  144. //prev_to_cur_transform.push_back(TransformParam(dx, dy, da));
  145. out_transform << k << " " << dx << " " << dy << " " << da << endl;
  146. //
  147. // Accumulated frame to frame transform
  148. x += dx;
  149. y += dy;
  150. a += da;
  151. //trajectory.push_back(Trajectory(x,y,a));
  152. //
  153. out_trajectory << k << " " << x << " " << y << " " << a << endl;
  154. //
  155. z = Trajectory(x,y,a);
  156. //
  157. if(k==1){
  158. // intial guesses
  159. X = Trajectory(0,0,0); //Initial estimate, set 0
  160. P =Trajectory(1,1,1); //set error variance,set 1
  161. }
  162. else
  163. {
  164. //time update(prediction)
  165. X_ = X; //X_(k) = X(k-1);
  166. P_ = P+Q; //P_(k) = P(k-1)+Q;
  167. // measurement update(correction)
  168. K = P_/( P_+R ); //gain;K(k) = P_(k)/( P_(k)+R );
  169. X = X_+K*(z-X_); //z-X_ is residual,X(k) = X_(k)+K(k)*(z(k)-X_(k));
  170. P = (Trajectory(1,1,1)-K)*P_; //P(k) = (1-K(k))*P_(k);
  171. }
  172. //smoothed_trajectory.push_back(X);
  173. out_smoothed_trajectory << k << " " << X.x << " " << X.y << " " << X.a << endl;
  174. //-
  175. // target - current
  176. double diff_x = X.x - x;//
  177. double diff_y = X.y - y;
  178. double diff_a = X.a - a;
  179. dx = dx + diff_x;
  180. dy = dy + diff_y;
  181. da = da + diff_a;
  182. //new_prev_to_cur_transform.push_back(TransformParam(dx, dy, da));
  183. //
  184. out_new_transform << k << " " << dx << " " << dy << " " << da << endl;
  185. //
  186. T.at<double>(0,0) = cos(da);
  187. T.at<double>(0,1) = -sin(da);
  188. T.at<double>(1,0) = sin(da);
  189. T.at<double>(1,1) = cos(da);
  190. T.at<double>(0,2) = dx;
  191. T.at<double>(1,2) = dy;
  192. Mat cur2;
  193. warpAffine(prev, cur2, T, cur.size());
  194. cur2 = cur2(Range(vert_border, cur2.rows-vert_border), Range(HORIZONTAL_BORDER_CROP, cur2.cols-HORIZONTAL_BORDER_CROP));
  195. // Resize cur2 back to cur size, for better side by side comparison
  196. resize(cur2, cur2, cur.size());
  197. // Now draw the original and stablised side by side for coolness
  198. Mat canvas = Mat::zeros(cur.rows, cur.cols*2+10, cur.type());
  199. prev.copyTo(canvas(Range::all(), Range(0, cur2.cols)));
  200. cur2.copyTo(canvas(Range::all(), Range(cur2.cols+10, cur2.cols*2+10)));
  201. // If too big to fit on the screen, then scale it down by 2, hopefully it'll fit :)
  202. if(canvas.cols > 1920) {
  203. resize(canvas, canvas, Size(canvas.cols/2, canvas.rows/2));
  204. }
  205. //outputVideo<<canvas;
  206. imshow("before and after", canvas);
  207. waitKey(10);
  208. //
  209. prev = cur.clone();//cur.copyTo(prev);
  210. cur_grey.copyTo(prev_grey);
  211. cout << "Frame: " << k << "/" << max_frames << " - good optical flow: " << prev_corner2.size() << endl;
  212. k++;
  213. }
  214. return 0;
  215. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/732527
推荐阅读
相关标签
  

闽ICP备14008679号