x
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -166,4 +166,5 @@ cython_debug/
|
||||
#.idea/
|
||||
.DS_Store
|
||||
output/svg
|
||||
*.mp4
|
||||
*.mp4
|
||||
output
|
||||
7
cali.py
7
cali.py
@ -9,9 +9,6 @@ from itertools import chain
|
||||
from typing import Optional, Sequence, TypedDict, cast
|
||||
import awkward as ak
|
||||
|
||||
from matplotlib.pyplot import stem
|
||||
from numpy import ndarray
|
||||
|
||||
|
||||
class ArucoDictionary(Enum):
|
||||
Dict_4X4_50 = aruco.DICT_4X4_50
|
||||
@ -37,10 +34,10 @@ class ArucoDictionary(Enum):
|
||||
Dict_ArUco_ORIGINAL = aruco.DICT_ARUCO_ORIGINAL
|
||||
|
||||
|
||||
IMAGE_FOLDER = Path("dumped/batch_two/b")
|
||||
IMAGE_FOLDER = Path("dumped/batch_three/c")
|
||||
OUTPUT_FOLDER = Path("output")
|
||||
DICTIONARY = ArucoDictionary.Dict_4X4_50
|
||||
CALIBRATION_PARQUET: Optional[Path] = OUTPUT_FOLDER / "af_03.parquet"
|
||||
CALIBRATION_PARQUET: Optional[Path] = OUTPUT_FOLDER / "c-af_03.parquet"
|
||||
|
||||
|
||||
class CameraParams(TypedDict):
|
||||
|
||||
157
compute_3d_maybe.ipynb
Normal file
157
compute_3d_maybe.ipynb
Normal file
@ -0,0 +1,157 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import awkward as ak\n",
|
||||
"from awkward import Array as AwakwardArray, Record as AwkwardRecord\n",
|
||||
"from typing import cast\n",
|
||||
"import numpy as np"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre>[{prediction: None, trackings: [], frame_num: 0, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 1, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 2, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 3, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 4, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 5, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 6, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 7, ...},\n",
|
||||
" {prediction: None, trackings: [], frame_num: 8, ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" ...,\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...},\n",
|
||||
" {prediction: {Akeypoints: [[...]], ...}, trackings: [{...}], ...}]\n",
|
||||
"-------------------------------------------------------------------\n",
|
||||
"type: 808 * {\n",
|
||||
" prediction: ?{\n",
|
||||
" Akeypoints: var * var * var * float64,\n",
|
||||
" bboxes: var * var * float64,\n",
|
||||
" scores: var * var * var * float64,\n",
|
||||
" frame_number: int64,\n",
|
||||
" reference_frame_size: {\n",
|
||||
" "0": int64,\n",
|
||||
" "1": int64\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" trackings: var * {\n",
|
||||
" id: int64,\n",
|
||||
" bounding_boxes: var * var * float64\n",
|
||||
" },\n",
|
||||
" frame_num: int64,\n",
|
||||
" reference_frame_size: {\n",
|
||||
" height: int64,\n",
|
||||
" width: int64\n",
|
||||
" }\n",
|
||||
"}</pre>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<Array [{prediction: None, ...}, ..., {...}] type='808 * {prediction: ?{Ake...'>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"a_ak = ak.from_parquet(\"pose/a.parquet\")\n",
|
||||
"b_ak = ak.from_parquet(\"pose/b.parquet\")\n",
|
||||
"# display(a_ak)\n",
|
||||
"display(b_ak)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre>{Akeypoints: [[[893, 417], [898, 408], [...], ..., [782, 596], [785, 599]]],\n",
|
||||
" bboxes: [[756, 341, 940, 597]],\n",
|
||||
" scores: [[[0.907], [0.896], [0.916], [0.341], ..., [0.811], [0.835], [0.802]]],\n",
|
||||
" frame_number: 5,\n",
|
||||
" reference_frame_size: {'0': 1080, '1': 1920}}\n",
|
||||
"--------------------------------------------------------------------------------\n",
|
||||
"type: {\n",
|
||||
" Akeypoints: var * var * var * float64,\n",
|
||||
" bboxes: var * var * float64,\n",
|
||||
" scores: var * var * var * float64,\n",
|
||||
" frame_number: int64,\n",
|
||||
" reference_frame_size: {\n",
|
||||
" "0": int64,\n",
|
||||
" "1": int64\n",
|
||||
" }\n",
|
||||
"}</pre>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<Record {Akeypoints: [[...]], bboxes: ..., ...} type='{Akeypoints: var * va...'>"
|
||||
]
|
||||
},
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"a_ak[\"prediction\"][5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"unique_tracking_ids_a = np.unique(ak.to_numpy(ak.flatten(cast(AwakwardArray, a_ak[\"trackings\"][\"id\"]))))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
58
dump_and_play.sh
Executable file
58
dump_and_play.sh
Executable file
@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z $1 ]; then
|
||||
echo "Usage: $0 <port>"
|
||||
exit 1
|
||||
else
|
||||
echo "dumping video from port $1"
|
||||
fi
|
||||
|
||||
TARGET_PORT=$1;
|
||||
|
||||
if ! [[ $TARGET_PORT =~ ^[0-9]+$ ]] ; then
|
||||
echo "error: expect a number, got $TARGET_PORT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# See also majestic.yaml
|
||||
# Get the current date and time in the format YYYYMMDD-HHMMSS
|
||||
DATE=$(date +"%Y%m%d-%H%M%S")
|
||||
|
||||
# use mts as MPEG transport stream
|
||||
FILENAME="output/video-${DATE}-${TARGET_PORT}.mts"
|
||||
# SINK="autovideosink"
|
||||
SINK="glimagesink"
|
||||
|
||||
|
||||
# Run the GStreamer pipeline with the dynamic filename
|
||||
# gst-launch-1.0 -e udpsrc port=$TARGET_PORT \
|
||||
# ! 'application/x-rtp,encoding-name=H265,payload=96' \
|
||||
# ! rtph265depay \
|
||||
# ! h265parse \
|
||||
# ! tee name=t \
|
||||
# t. ! queue ! $DECODER ! videoconvert ! $SINK \
|
||||
# t. ! queue ! mp4mux ! filesink location=$FILENAME
|
||||
|
||||
|
||||
# DECODER="nvh265dec"
|
||||
# DECODER="vulkanh265dec"
|
||||
# DECODER="avdec_h265"
|
||||
DECODER="vtdec_hw"
|
||||
# DECODER="vtdec"
|
||||
# gst-launch-1.0 -e udpsrc port=$TARGET_PORT auto-multicast=true multicast-group=224.0.0.123 \
|
||||
# ! 'application/x-rtp,encoding-name=H265,payload=96' \
|
||||
# ! rtph265depay \
|
||||
# ! tee name=t \
|
||||
# ! h265parse \
|
||||
# t. ! queue ! $DECODER ! videoconvert ! $SINK \
|
||||
# t. ! queue ! mpegtsmux ! filesink location=$FILENAME
|
||||
|
||||
# hvc1
|
||||
# hev1
|
||||
gst-launch-1.0 -e udpsrc port=$TARGET_PORT auto-multicast=true multicast-group=224.0.0.123 \
|
||||
! 'application/x-rtp,encoding-name=H265,payload=96' \
|
||||
! rtph265depay \
|
||||
! tee name=t \
|
||||
t. ! queue ! h265parse ! "video/x-h265,stream-format=hvc1" ! $DECODER ! videoconvert ! $SINK \
|
||||
t. ! queue ! h265parse ! mpegtsmux ! filesink location=$FILENAME
|
||||
|
||||
@ -10,9 +10,14 @@ import numpy as np
|
||||
|
||||
NDArray = np.ndarray
|
||||
CALIBRATION_PARQUET = Path("output") / "usbcam_cal.parquet"
|
||||
DICTIONARY: Final[int] = aruco.DICT_4X4_50
|
||||
# 7x7
|
||||
DICTIONARY: Final[int] = aruco.DICT_7X7_1000
|
||||
# 400mm
|
||||
MARKER_LENGTH: Final[float] = 0.4
|
||||
RED = (0, 0, 255)
|
||||
GREEN = (0, 255, 0)
|
||||
BLUE = (255, 0, 0)
|
||||
YELLOW = (0, 255, 255)
|
||||
|
||||
|
||||
def gen():
|
||||
@ -47,23 +52,18 @@ def main():
|
||||
# logger.info("markers={}, ids={}", np.array(markers).shape, np.array(ids).shape)
|
||||
for m, i in zip(markers, ids):
|
||||
center = np.mean(m, axis=0).astype(int)
|
||||
GREY = (128, 128, 128)
|
||||
logger.info("id={}, center={}", i, center)
|
||||
cv2.circle(frame, tuple(center), 5, GREY, -1)
|
||||
cv2.circle(frame, tuple(center), 5, RED, -1)
|
||||
cv2.putText(
|
||||
frame,
|
||||
str(i),
|
||||
tuple(center),
|
||||
cv2.FONT_HERSHEY_SIMPLEX,
|
||||
1,
|
||||
GREY,
|
||||
RED,
|
||||
2,
|
||||
)
|
||||
# BGR
|
||||
RED = (0, 0, 255)
|
||||
GREEN = (0, 255, 0)
|
||||
BLUE = (255, 0, 0)
|
||||
YELLOW = (0, 255, 255)
|
||||
color_map = [RED, GREEN, BLUE, YELLOW]
|
||||
for color, corners in zip(color_map, m):
|
||||
corners = corners.astype(int)
|
||||
|
||||
179
get_ext.ipynb
179
get_ext.ipynb
@ -2,7 +2,7 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -22,7 +22,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -33,80 +33,15 @@
|
||||
"MARKER_LENGTH: Final[float] = 0.4\n",
|
||||
"\n",
|
||||
"A_CALIBRATION_PARQUET = Path(\"output\") / \"a-ae_08.parquet\"\n",
|
||||
"B_CALIBRATION_PARQUET = Path(\"output\") / \"b-af_03.parquet\""
|
||||
"B_CALIBRATION_PARQUET = Path(\"output\") / \"b-ae_09.parquet\"\n",
|
||||
"C_CALIBRATION_PARQUET = Path(\"output\") / \"c-af_03.parquet\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'ops_map'"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{16: array([[0.152, 0.025, 0. ],\n",
|
||||
" [0.249, 0.025, 0. ],\n",
|
||||
" [0.249, 0.122, 0. ],\n",
|
||||
" [0.152, 0.122, 0. ]]),\n",
|
||||
" 17: array([[0.025, 0.152, 0. ],\n",
|
||||
" [0.122, 0.152, 0. ],\n",
|
||||
" [0.122, 0.249, 0. ],\n",
|
||||
" [0.025, 0.249, 0. ]]),\n",
|
||||
" 18: array([[0.27900001, 0.152 , 0. ],\n",
|
||||
" [0.37599999, 0.152 , 0. ],\n",
|
||||
" [0.37599999, 0.249 , 0. ],\n",
|
||||
" [0.27900001, 0.249 , 0. ]]),\n",
|
||||
" 19: array([[0.152 , 0.27900001, 0. ],\n",
|
||||
" [0.249 , 0.27900001, 0. ],\n",
|
||||
" [0.249 , 0.37599999, 0. ],\n",
|
||||
" [0.152 , 0.37599999, 0. ]]),\n",
|
||||
" 20: array([[1.51999995e-01, 1.70838222e-17, 3.86000000e-01],\n",
|
||||
" [2.48999998e-01, 2.89628965e-17, 3.86000000e-01],\n",
|
||||
" [2.48999998e-01, 2.30233595e-17, 2.88999999e-01],\n",
|
||||
" [1.51999995e-01, 1.11442852e-17, 2.88999999e-01]]),\n",
|
||||
" 21: array([[ 2.50000004e-02, -6.24569833e-18, 2.59000005e-01],\n",
|
||||
" [ 1.22000001e-01, 5.63337574e-18, 2.59000005e-01],\n",
|
||||
" [ 1.22000001e-01, -3.06161408e-19, 1.62000002e-01],\n",
|
||||
" [ 2.50000004e-02, -1.21852355e-17, 1.62000002e-01]]),\n",
|
||||
" 22: array([[2.79000014e-01, 2.48603320e-17, 2.59000005e-01],\n",
|
||||
" [3.75999987e-01, 3.67394027e-17, 2.59000005e-01],\n",
|
||||
" [3.75999987e-01, 3.07998655e-17, 1.62000002e-01],\n",
|
||||
" [2.79000014e-01, 1.89207949e-17, 1.62000002e-01]]),\n",
|
||||
" 23: array([[ 1.51999995e-01, 1.53080704e-18, 1.31999986e-01],\n",
|
||||
" [ 2.48999998e-01, 1.34098813e-17, 1.31999986e-01],\n",
|
||||
" [ 2.48999998e-01, 7.47034601e-18, 3.50000129e-02],\n",
|
||||
" [ 1.51999995e-01, -4.40872829e-18, 3.50000129e-02]]),\n",
|
||||
" 24: array([[1.53080852e-18, 2.49000005e-01, 3.86000000e-01],\n",
|
||||
" [1.53080852e-18, 1.52000002e-01, 3.86000000e-01],\n",
|
||||
" [7.47034556e-18, 1.52000002e-01, 2.88999999e-01],\n",
|
||||
" [7.47034556e-18, 2.49000005e-01, 2.88999999e-01]]),\n",
|
||||
" 25: array([[9.30731537e-18, 3.76000000e-01, 2.59000005e-01],\n",
|
||||
" [9.30731537e-18, 2.78999999e-01, 2.59000005e-01],\n",
|
||||
" [1.52468525e-17, 2.78999999e-01, 1.62000002e-01],\n",
|
||||
" [1.52468525e-17, 3.76000000e-01, 1.62000002e-01]]),\n",
|
||||
" 26: array([[9.30731537e-18, 1.21999986e-01, 2.59000005e-01],\n",
|
||||
" [9.30731537e-18, 2.50000129e-02, 2.59000005e-01],\n",
|
||||
" [1.52468525e-17, 2.50000129e-02, 1.62000002e-01],\n",
|
||||
" [1.52468525e-17, 1.21999986e-01, 1.62000002e-01]]),\n",
|
||||
" 27: array([[1.70838237e-17, 2.49000005e-01, 1.31999986e-01],\n",
|
||||
" [1.70838237e-17, 1.52000002e-01, 1.31999986e-01],\n",
|
||||
" [2.30233590e-17, 1.52000002e-01, 3.50000129e-02],\n",
|
||||
" [2.30233590e-17, 2.49000005e-01, 3.50000129e-02]])}"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aruco_dict = aruco.getPredefinedDictionary(DICTIONARY)\n",
|
||||
"def read_camera_calibration(path: Path) -> tuple[MatLike, MatLike]:\n",
|
||||
@ -115,8 +50,6 @@
|
||||
" distortion_coefficients = cast(MatLike, ak.to_numpy(cal[\"distortion_coefficients\"]))\n",
|
||||
" return camera_matrix, distortion_coefficients\n",
|
||||
"\n",
|
||||
"a_mtx, a_dist = read_camera_calibration(A_CALIBRATION_PARQUET)\n",
|
||||
"b_camera_matrix, b_distortion_coefficients = read_camera_calibration(B_CALIBRATION_PARQUET)\n",
|
||||
"ops = ak.from_parquet(OBJECT_POINTS_PARQUET)\n",
|
||||
"detector = aruco.ArucoDetector(\n",
|
||||
" dictionary=aruco_dict, detectorParams=aruco.DetectorParameters()\n",
|
||||
@ -125,12 +58,12 @@
|
||||
"total_ids = cast(NDArray, ak.to_numpy(ops[\"ids\"])).flatten()\n",
|
||||
"total_corners = cast(NDArray, ak.to_numpy(ops[\"corners\"])).reshape(-1, 4, 3)\n",
|
||||
"ops_map: dict[int, NDArray] = dict(zip(total_ids, total_corners))\n",
|
||||
"display(\"ops_map\", ops_map)"
|
||||
"# display(\"ops_map\", ops_map)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 41,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -227,26 +160,35 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"A_IMG = Path(\"dumped/batch_two/op/video-20241219-142434-op-a.png\")\n",
|
||||
"B_IMG = Path(\"dumped/batch_two/op/video-20241219-142439-op-b.png\")\n",
|
||||
"A_IMG = Path(\"dumped/batch_three/video-20241224-154256-a.png\")\n",
|
||||
"B_IMG = Path(\"dumped/batch_three/video-20241224-154302-b.png\")\n",
|
||||
"C_IMG = Path(\"dumped/batch_three/video-20241224-154252-c.png\")\n",
|
||||
"C_PRIME_IMG = Path(\"dumped/batch_three/video-20241224-153926-c-prime.png\")\n",
|
||||
"\n",
|
||||
"a_img = cv2.imread(str(A_IMG))\n",
|
||||
"b_img = cv2.imread(str(B_IMG))"
|
||||
"b_img = cv2.imread(str(B_IMG))\n",
|
||||
"c_img = cv2.imread(str(C_IMG))\n",
|
||||
"c_prime_img = cv2.imread(str(C_PRIME_IMG))\n",
|
||||
"\n",
|
||||
"a_mtx, a_dist = read_camera_calibration(A_CALIBRATION_PARQUET)\n",
|
||||
"b_mtx, b_dist = read_camera_calibration(B_CALIBRATION_PARQUET)\n",
|
||||
"c_mtx, c_dist = read_camera_calibration(C_CALIBRATION_PARQUET)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 43,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/cj/0zmvpygn7m72m42lh6x_hcgw0000gn/T/ipykernel_28395/542219436.py:22: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
|
||||
"/var/folders/cj/0zmvpygn7m72m42lh6x_hcgw0000gn/T/ipykernel_79393/542219436.py:22: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
|
||||
" id = int(id)\n"
|
||||
]
|
||||
}
|
||||
@ -258,26 +200,45 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 44,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/cj/0zmvpygn7m72m42lh6x_hcgw0000gn/T/ipykernel_28395/542219436.py:22: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
|
||||
"/var/folders/cj/0zmvpygn7m72m42lh6x_hcgw0000gn/T/ipykernel_79393/542219436.py:22: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
|
||||
" id = int(id)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"b_result_img, b_rvec, b_tvec = process(b_img, b_camera_matrix, b_distortion_coefficients)\n",
|
||||
"b_result_img, b_rvec, b_tvec = process(b_img, b_mtx, b_dist)\n",
|
||||
"# plt.imshow(cv2.cvtColor(b_result_img, cv2.COLOR_BGR2RGB))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 45,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/cj/0zmvpygn7m72m42lh6x_hcgw0000gn/T/ipykernel_79393/542219436.py:22: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
|
||||
" id = int(id)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"c_result_img, c_rvec, c_tvec = process(c_img, c_mtx, c_dist)\n",
|
||||
"c_prime_result_img, c_prime_rvec, c_prime_tvec = process(c_prime_img, c_mtx, c_dist)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 46,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -292,10 +253,12 @@
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre>[{name: 'a', rvec: [[-1.04], ..., [-2.95]], tvec: [...], ...},\n",
|
||||
" {name: 'b', rvec: [[0.948], ..., [2.97]], tvec: [...], ...}]\n",
|
||||
"--------------------------------------------------------------\n",
|
||||
"type: 2 * {\n",
|
||||
"<pre>[{name: 'a-ae_08', rvec: [[-0.602], ..., [-3.05]], tvec: [...], ...},\n",
|
||||
" {name: 'b-ae_09', rvec: [[0.572], ..., [3.02]], tvec: [...], ...},\n",
|
||||
" {name: 'c-af_03', rvec: [[-1.98], ..., [-2.4]], tvec: [...], ...},\n",
|
||||
" {name: 'c-prime-af_03', rvec: [[-1.99], ...], tvec: [...], ...}]\n",
|
||||
"---------------------------------------------------------------------\n",
|
||||
"type: 4 * {\n",
|
||||
" name: string,\n",
|
||||
" rvec: var * var * float64,\n",
|
||||
" tvec: var * var * float64,\n",
|
||||
@ -304,7 +267,7 @@
|
||||
"}</pre>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<Array [{name: 'a', rvec: [...], ...}, ...] type='2 * {name: string, rvec: ...'>"
|
||||
"<Array [{name: 'a-ae_08', rvec: ..., ...}, ...] type='4 * {name: string, rv...'>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@ -313,16 +276,16 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<pyarrow._parquet.FileMetaData object at 0x17f93f830>\n",
|
||||
"<pyarrow._parquet.FileMetaData object at 0x311da8900>\n",
|
||||
" created_by: parquet-cpp-arrow version 14.0.1\n",
|
||||
" num_columns: 5\n",
|
||||
" num_rows: 2\n",
|
||||
" num_rows: 4\n",
|
||||
" num_row_groups: 1\n",
|
||||
" format_version: 2.6\n",
|
||||
" serialized_size: 0"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"execution_count": 46,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -331,19 +294,33 @@
|
||||
"params = AwkwardArray(\n",
|
||||
" [\n",
|
||||
" {\n",
|
||||
" \"name\": \"a\",\n",
|
||||
" \"name\": \"a-ae_08\",\n",
|
||||
" \"rvec\": a_rvec,\n",
|
||||
" \"tvec\": a_tvec,\n",
|
||||
" \"camera_matrix\": a_mtx,\n",
|
||||
" \"distortion_coefficients\": a_dist,\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"name\": \"b\",\n",
|
||||
" \"name\": \"b-ae_09\",\n",
|
||||
" \"rvec\": b_rvec,\n",
|
||||
" \"tvec\": b_tvec,\n",
|
||||
" \"camera_matrix\": b_camera_matrix,\n",
|
||||
" \"distortion_coefficients\": b_distortion_coefficients,\n",
|
||||
" \"camera_matrix\": b_mtx,\n",
|
||||
" \"distortion_coefficients\": b_dist,\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"name\": \"c-af_03\",\n",
|
||||
" \"rvec\": c_rvec,\n",
|
||||
" \"tvec\": c_tvec,\n",
|
||||
" \"camera_matrix\": c_mtx,\n",
|
||||
" \"distortion_coefficients\": c_dist\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"name\": \"c-prime-af_03\",\n",
|
||||
" \"rvec\": c_prime_rvec,\n",
|
||||
" \"tvec\": c_prime_tvec,\n",
|
||||
" \"camera_matrix\": c_mtx,\n",
|
||||
" \"distortion_coefficients\": c_dist\n",
|
||||
" }\n",
|
||||
" ]\n",
|
||||
")\n",
|
||||
"display(\"params\", params)\n",
|
||||
@ -352,7 +329,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": 47,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -361,14 +338,16 @@
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"execution_count": 47,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"cv2.imwrite(\"output/a_result_img.png\", a_result_img)\n",
|
||||
"cv2.imwrite(\"output/b_result_img.png\", b_result_img)"
|
||||
"cv2.imwrite(\"output/b_result_img.png\", b_result_img)\n",
|
||||
"cv2.imwrite(\"output/c_result_img.png\", c_result_img)\n",
|
||||
"cv2.imwrite(\"output/c_prime_result_img.png\", c_prime_result_img)"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
BIN
output/b-af_03.parquet
LFS
BIN
output/b-af_03.parquet
LFS
Binary file not shown.
BIN
output/params.parquet
LFS
BIN
output/params.parquet
LFS
Binary file not shown.
BIN
pose/a.parquet
LFS
Normal file
BIN
pose/a.parquet
LFS
Normal file
Binary file not shown.
BIN
pose/b.parquet
LFS
Normal file
BIN
pose/b.parquet
LFS
Normal file
Binary file not shown.
132
run_capture.py
Normal file
132
run_capture.py
Normal file
@ -0,0 +1,132 @@
|
||||
from datetime import datetime
|
||||
from os import PathLike
|
||||
from pathlib import Path
|
||||
import signal
|
||||
from subprocess import Popen, TimeoutExpired
|
||||
from typing import Any, Literal
|
||||
from loguru import logger
|
||||
import click
|
||||
import loguru
|
||||
|
||||
# pacman -S python-loguru
|
||||
# pacman -S python-click
|
||||
|
||||
Mode = Literal["preview", "save", "save_preview"]
|
||||
MODE_LIST: list[Mode] = ["preview", "save", "save_preview"]
|
||||
MULTICAST_ADDR = "224.0.0.123"
|
||||
|
||||
|
||||
class DumpCommand:
|
||||
port: int
|
||||
output_path: str
|
||||
|
||||
def __init__(self, port: int, output_path: PathLike | str):
|
||||
self.port = port
|
||||
self.output_path = str(output_path)
|
||||
|
||||
def save_and_decode_nv_pipeline(self):
|
||||
# note that capabilties SHOULD NOT have spaces in between
|
||||
# `gst-launch-1.0` could tolerate that, but not the API itself
|
||||
return f"""gst-launch-1.0 -e udpsrc port={self.port} \
|
||||
! 'application/x-rtp,encoding-name=H265,payload=96' \
|
||||
! rtph265depay \
|
||||
! h265parse \
|
||||
! tee name=t \
|
||||
t. ! queue ! nvh265dec ! videoconvert ! autovideosink \
|
||||
t. ! queue ! mp4mux ! filesink location={self.output_path}
|
||||
"""
|
||||
|
||||
def save_and_decode_nv_pipeline_multicast(self):
|
||||
return f"""gst-launch-1.0 -e udpsrc port={self.port} \
|
||||
auto-multicast=true \
|
||||
multicast-group={MULTICAST_ADDR} \
|
||||
! 'application/x-rtp,encoding-name=H265,payload=96' \
|
||||
! rtph265depay \
|
||||
! h265parse \
|
||||
! tee name=t \
|
||||
t. ! queue ! vtdec_hw ! videoconvert ! autovideosink \
|
||||
t. ! queue ! mp4mux ! filesink location={self.output_path}
|
||||
"""
|
||||
# `vtdec_hw` for macos
|
||||
# `nvh265dec` for nv
|
||||
|
||||
def save_pipeline(self):
|
||||
return f"""gst-launch-1.0 -e udpsrc port={self.port} \
|
||||
! 'application/x-rtp, encoding-name=H265, payload=96' \
|
||||
! rtph265depay \
|
||||
! queue ! h265parse ! mp4mux ! filesink location={self.output_path}
|
||||
"""
|
||||
|
||||
def decode_cv_only(self):
|
||||
return f"""gst-launch-1.0 -e udpsrc port={self.port} \
|
||||
! 'application/x-rtp,encoding-name=H265,payload=96' \
|
||||
! rtph265depay \
|
||||
! h265parse \
|
||||
! nvh265dec \
|
||||
! videoconvert \
|
||||
! autovideosink
|
||||
"""
|
||||
|
||||
def get_pipeline_from_mode(self, mode: Mode):
|
||||
if mode == "save":
|
||||
return self.save_pipeline()
|
||||
elif mode == "save_preview":
|
||||
return self.save_and_decode_nv_pipeline_multicast()
|
||||
elif mode == "preview":
|
||||
return self.decode_cv_only()
|
||||
raise ValueError(f"Unknown mode: {mode}")
|
||||
|
||||
|
||||
def test_filename(
|
||||
port: int,
|
||||
output_dir: PathLike | str,
|
||||
date: datetime,
|
||||
prefix="video_",
|
||||
suffix=".mp4",
|
||||
):
|
||||
date_str = date.strftime("%Y-%m-%d_%H-%M-%S")
|
||||
assert suffix.startswith("."), "suffix should start with a dot"
|
||||
file_name = f"{prefix}{date_str}_{port}{suffix}"
|
||||
return Path(output_dir) / file_name
|
||||
|
||||
|
||||
# nmap -sS --open -p 22 192.168.2.0/24
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("-o", "--output", type=click.Path(exists=True), default="output")
|
||||
@click.option("-m", "--mode", type=click.Choice(MODE_LIST), default="save_preview")
|
||||
def main(output: str, mode: Mode):
|
||||
ports = [5601, 5602, 5603, 5604, 5605, 5606]
|
||||
output_dir = Path(output)
|
||||
now = datetime.now()
|
||||
commands = [
|
||||
DumpCommand(port, test_filename(port, output_dir, now)) for port in ports
|
||||
]
|
||||
ps: list[Popen] = []
|
||||
run_flag: bool = True
|
||||
|
||||
def handle_sigint(signum: int, frame: Any):
|
||||
nonlocal run_flag
|
||||
run_flag = False
|
||||
logger.info("Received SIGINT, stopping all processes")
|
||||
|
||||
for command in commands:
|
||||
p = Popen(command.get_pipeline_from_mode(mode), shell=True)
|
||||
ps.append(p)
|
||||
|
||||
signal.signal(signal.SIGINT, handle_sigint)
|
||||
while run_flag:
|
||||
pass
|
||||
|
||||
for p in ps:
|
||||
p.send_signal(signal.SIGINT)
|
||||
for p in ps:
|
||||
try:
|
||||
p.wait(3)
|
||||
except TimeoutExpired:
|
||||
logger.warning("Command `{}` timeout", p.args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main() # pylint: disable=no-value-for-parameter
|
||||
Reference in New Issue
Block a user