summaryrefslogtreecommitdiff
path: root/tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde
diff options
context:
space:
mode:
Diffstat (limited to 'tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde')
-rw-r--r--tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde110
1 files changed, 110 insertions, 0 deletions
diff --git a/tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde b/tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde
new file mode 100644
index 000000000..48a2c56a0
--- /dev/null
+++ b/tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde
@@ -0,0 +1,110 @@
+class MotionField {
+ Camera camera;
+ int block_size;
+ PointCloud point_cloud;
+ ArrayList<PVector> last_positions;
+ ArrayList<PVector> current_positions;
+ ArrayList<PVector> motion_field;
+
+ MotionField(Camera camera, PointCloud point_cloud, int block_size) {
+ this.camera = camera;
+ this.point_cloud = point_cloud;
+ this.block_size = block_size;
+ this.last_positions = new ArrayList<PVector>();
+ this.current_positions = new ArrayList<PVector>();
+ this.motion_field = new ArrayList<PVector>();
+ for (int i = 0; i < point_cloud.points.size(); i++) {
+ PVector pos = point_cloud.points.get(i);
+ PVector proj_pos = getProjectedPos(pos);
+ last_positions.add(proj_pos);
+ current_positions.add(proj_pos);
+ }
+ }
+
+ PVector getProjectedPos(PVector pos) {
+ float[] cam_mat = camera.getCameraMat();
+ PVector trans_pos =
+ PVector.sub(pos, camera.pos); // translate based on camera's position
+ PVector rot_pos =
+ MatxVec3(cam_mat, trans_pos); // rotate based on camera angle
+ PVector proj_pos = new PVector(0, 0, 0);
+ proj_pos.x =
+ height / 2.0f * rot_pos.x / (rot_pos.z) / tan(camera.fov / 2.0f);
+ proj_pos.y =
+ height / 2.0f * rot_pos.y / (rot_pos.z) / tan(camera.fov / 2.0f);
+ proj_pos.z = trans_pos.z;
+
+ return proj_pos;
+ }
+
+ void run() {
+ last_positions = current_positions;
+ // take care
+ current_positions = new ArrayList<PVector>();
+ for (int i = 0; i < point_cloud.points.size(); i++) {
+ PVector pos = point_cloud.points.get(i);
+ PVector proj_pos = getProjectedPos(pos);
+ current_positions.add(proj_pos);
+ }
+ }
+
+ ArrayList<PVector> getMotionField() {
+ ArrayList<PVector> depth = new ArrayList<PVector>();
+ IntList pixel_idx = new IntList();
+ for (int i = 0; i < width * height; i++)
+ depth.add(new PVector(Float.POSITIVE_INFINITY, -1));
+ for (int i = 0; i < current_positions.size(); i++) {
+ PVector pos = current_positions.get(i);
+ int row = int(pos.y + height / 2);
+ int col = int(pos.x + width / 2);
+ int idx = row * width + col;
+ if (row >= 0 && row < height && col >= 0 && col < width) {
+ PVector depth_info = depth.get(idx);
+ if (depth_info.y == -1) {
+ depth.set(idx, new PVector(pos.z, pixel_idx.size()));
+ pixel_idx.append(i);
+ } else if (pos.z < depth_info.x) {
+ depth.set(idx, new PVector(pos.z, depth_info.y));
+ pixel_idx.set(int(depth_info.y), i);
+ }
+ }
+ }
+ motion_field = new ArrayList<PVector>();
+ int r_num = height / block_size, c_num = width / block_size;
+ for (int i = 0; i < r_num * c_num; i++)
+ motion_field.add(new PVector(0, 0, 0));
+ for (int i = 0; i < pixel_idx.size(); i++) {
+ PVector cur_pos = current_positions.get(pixel_idx.get(i));
+ PVector last_pos = last_positions.get(pixel_idx.get(i));
+ int row = int(cur_pos.y + height / 2);
+ int col = int(cur_pos.x + width / 2);
+ int idx = row / block_size * c_num + col / block_size;
+ PVector mv = PVector.sub(last_pos, cur_pos);
+ PVector acc_mv = motion_field.get(idx);
+ motion_field.set(
+ idx, new PVector(acc_mv.x + mv.x, acc_mv.y + mv.y, acc_mv.z + 1));
+ }
+ for (int i = 0; i < r_num * c_num; i++) {
+ PVector mv = motion_field.get(i);
+ if (mv.z > 0) {
+ motion_field.set(i, new PVector(mv.x / mv.z, mv.y / mv.z, 0));
+ }
+ }
+ return motion_field;
+ }
+
+ void showMotionField() {
+ ortho(-width, 0, -height, 0);
+ camera(0, 0, 0, 0, 0, 1, 0, 1, 0);
+ getMotionField();
+ int r_num = height / block_size, c_num = width / block_size;
+ for (int i = 0; i < r_num; i++)
+ for (int j = 0; j < c_num; j++) {
+ PVector mv = motion_field.get(i * c_num + j);
+ float ox = j * block_size + 0.5f * block_size;
+ float oy = i * block_size + 0.5f * block_size;
+ stroke(255, 0, 0);
+ line(ox, oy, ox + mv.x, oy + mv.y);
+ }
+ }
+}