From 0a836b1bd7d4d9b0096176f89f285c8ee9021ac1 Mon Sep 17 00:00:00 2001 From: Melfely Date: Wed, 16 Sep 2026 18:06:28 -0500 Subject: [PATCH] changes --- .gitattributes | 1 + model.dat | 2 +- presentation/main.typ | 35 +++++++ project/Cargo.lock | 229 ++++++++++++++++++++++++++++++++++++++++++ project/Cargo.toml | 8 ++ project/src/main.rs | 33 ++++++ project1.md | 100 ++++++++++++++++++ project1.odt | 3 + 8 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 presentation/main.typ create mode 100644 project/Cargo.lock create mode 100644 project/Cargo.toml create mode 100644 project/src/main.rs create mode 100644 project1.md create mode 100644 project1.odt diff --git a/.gitattributes b/.gitattributes index 61f8875..6a2662b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ *.doc filter=lfs diff=lfs merge=lfs -text *.bmp filter=lfs diff=lfs merge=lfs -text +*.odt filter=lfs diff=lfs merge=lfs -text diff --git a/model.dat b/model.dat index 47d5a64..1dd617d 100755 --- a/model.dat +++ b/model.dat @@ -24,4 +24,4 @@ 10 10 4 10 10 6 10 10 8 -10 10 10 \ No newline at end of file +10 10 10 diff --git a/presentation/main.typ b/presentation/main.typ new file mode 100644 index 0000000..e9562b1 --- /dev/null +++ b/presentation/main.typ @@ -0,0 +1,35 @@ +#import "@preview/xwysyy:0.4.0": * + +#show: xwysyy-pre.with( + theme: "midnight", + config-info( + title: [Project 1], + subtitle: [Computer Vision], + author: "Zander Johnson", + date: datetime.today(), + institution: "University of Central Arkansas", + ), +) + +#title-slide() + +#outline-slide() + += Motivation + +== One Minute Setup + +#textbox( + [*Reusable components* + + `textbox`, #red[red highlights], #yellow[yellow highlights], tables, code blocks, and touying animations share one theme.], + + [*Theme control* + + Switch built-in themes with `theme: "sunset"` or pass a custom color dictionary directly.], +) + +#end-slide( + title: [Thank You!], + body: [Questions?], +) diff --git a/project/Cargo.lock b/project/Cargo.lock new file mode 100644 index 0000000..9ea9449 --- /dev/null +++ b/project/Cargo.lock @@ -0,0 +1,229 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" + +[[package]] +name = "glam" +version = "0.30.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9" + +[[package]] +name = "glam" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556f6b2ea90b8d15a74e0e7bb41671c9bdf38cd9f78c284d750b9ce58a2b5be7" + +[[package]] +name = "glam" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f70749695b063ecbf6b62949ccccde2e733ec3ecbbd71d467dca4e5c6c97cca0" + +[[package]] +name = "glam" +version = "0.33.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e762b9b188634fc508d4ec54b62ea3d352c43fd431d18d05d46f559f217f4725" + +[[package]] +name = "matrixmultiply" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f607c237553f086e7043417a51df26b2eb899d3caff94e6a67592ff992fedc7" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "nalgebra" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc43a60c217b0c6ff46e47f26911015ad8d2e5a8be1af668c67e370d99a4346" +dependencies = [ + "approx", + "glam 0.30.10", + "glam 0.31.1", + "glam 0.32.1", + "glam 0.33.7", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973e7178a678cfd059ccec50887658d482ce16b0aa9da3888ddeab5cd5eb4889" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "project" +version = "0.1.0" +dependencies = [ + "anyhow", + "nalgebra", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "safe_arch" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42c6efa15875e6ecb39ca61fb0b0c1a40b84fac5a5ffe71eef7d1000c8eb3f5f" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "simba" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a7200d82ff1c7b4235efd12f11e2537a402c91cf83a5cb97ce80eef787fde7" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "wide", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "wide" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf05ca94c9fba0c51316899caa1d1e74a064fc310a5efa7375e614343d415be" +dependencies = [ + "bytemuck", + "safe_arch", +] diff --git a/project/Cargo.toml b/project/Cargo.toml new file mode 100644 index 0000000..d200a7f --- /dev/null +++ b/project/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "project" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow = "1.0.104" +nalgebra = "0.35.0" diff --git a/project/src/main.rs b/project/src/main.rs new file mode 100644 index 0000000..a137c58 --- /dev/null +++ b/project/src/main.rs @@ -0,0 +1,33 @@ +use anyhow::Result as AnyResult; +use std::{fs::File, io::Read}; + +use nalgebra as ng; + +fn get_data(file_path: &str) -> AnyResult> { + let mut file = File::open(file_path)?; + + let mut buf = "".to_string(); + file.read_to_string(&mut buf)?; + + Ok(buf + .split_whitespace() + .filter_map(|f| f.parse::().ok()) + .collect()) +} + +fn main() -> AnyResult<()> { + let observe_data = get_data("../observe.dat")?; + let observe_mat = ng::MatrixXx2::from_vec_generic( + ng::Dyn(observe_data.len() / 2), + ng::Const::<2>, + observe_data, + ); + println!("Observe: {:?}", observe_mat); + + let model_data = get_data("../model.dat")?; + let model_mat = + ng::MatrixXx3::from_vec_generic(ng::Dyn(model_data.len() / 3), ng::Const::<3>, model_data); + println!("Observe: {:?}", model_mat); + + Ok(()) +} diff --git a/project1.md b/project1.md new file mode 100644 index 0000000..a99b1ea --- /dev/null +++ b/project1.md @@ -0,0 +1,100 @@ +**ENGR4350 Computer Vision** + +**Project 1. Linear Approach to Camera Calibration** + +**Due Data: September 20, 2026** + +**Objective:** To use a linear approach to calibrate a camera and to use +the camera parameters to predict the 2D image-domain location of a set +of 3D points or a 3D moving object. + +Procedure: + +1. Study the lecture note by showing the use of projection matrix that + maps objects from 3-D to 2-D, the definition of intrinsic and + extrinsic parameters of a camera, and the linear approach to + geometric camera calibration. +2. Given an image *test_image.bmp* captured by a camera which is posed + toward a 3D chess board, we manually selected 27 points whose 2-D + image coordinates are saved in the file *observe.dat*, and whose 3-D + coordinates in a world coordinate are stored in the file + *model.dat*. Please use the linear approach to calibrate the camera + system by computing the projection matrix (M) from which you are + required to compute the intrinsic and extrinsic parameters, + including , u0, v0, α, β, and the rotation matrix (R), and the + shift vector (t). +3. In order to verify the correctness of the camera calibration, please + use the projection matrix to map the three set of 3D points, whose + 3-D coordinates are {x,y,0\|x,y=0,...,10}, {x,10,z\|x,z=0,...,10}, + {10,y,z\|y,z=0,...,10}, respectively, into the 2-D image space. + Discuss your results. +4. Create a video file that shows a 3D object moving in the 3D scene + along a specific pre-defined path. For example, a 3D cube (1x1x1) + can be displayed by nine lines connecting seven vertexes (see the + example below). Each line can be drawn with around 100 samples. (You + can see a video example from Slide 13 of the Lecture 8 handout in + the slideshow mode.) + +**Report Requirements:** + +1. Briefly discuss the basics of geometric camera modeling. +2. Briefly discuss the linear approach to camera calibration. +3. Show the simulation results by figures (Part 3). +4. Include some sample frames of the video (Part 4) in the report. +5. The Python source code should be included as the appendix of the + report with detailed comments. A separate Python file should also be + provided for testing. +6. Zip all files (DOC, AVI, M-file) into one package and upload it to + Blackboard by the due date. + +**Useful Python functions:** + +You need to import the required libraries: + +> import torch\ +> import numpy as np\ +> import matplotlib.pyplot as plt\ +> from PIL import Image\ +> import time + +> import cv2\ +> import os + +- Inner product: torch.dot(t1,t2), Cross product : torch.cross(t1,t2). + +> v0 = (s \*\* 2) \* torch.dot(a2, a3)\ +> \ +> cross_a1_a3 = torch.cross(a1, a3) + +> + +- Singular value decomposition (SVD) : + +> \# \-\-- Solve for the projection matrix M \-\--\ +> \# The solution to Qm=0 is the last column of V from the SVD of Q\ +> \# In PyTorch, torch.linalg.svd returns U, S, Vh (V transpose)\ +> U, S, Vh = torch.linalg.svd(Q)\ +> \ +> \# The solution is the last row of Vh, which corresponds to the +> smallest singular value\ +> m = Vh\[-1, :\]\ +> \ +> \# Reshape the 12x1 vector m into the 3x4 projection matrix M\ +> M = m.reshape(3, 4) + +- Norm of a vector: torch.linalg.norm(vector). + +> torch.linalg.norm(cross_a1_a3) + +> + +- Inverse of a matrix: torch.linalg.inv(M) + +> torch.linalg.inv(M) + +> + +- Reshape of a vector to a matrix: + +> \# Reshape the 12x1 vector m into the 3x4 projection matrix M\ +> M = m.reshape(3, 4) diff --git a/project1.odt b/project1.odt new file mode 100644 index 0000000..23c3cf5 --- /dev/null +++ b/project1.odt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ef93fb84eb41134fc4ee8bfbacfa20fd6a94847c35ca5b8b5018df1fb5eb299 +size 41461