cute object we go

This commit is contained in:
2024-12-18 15:40:51 +08:00
parent bfac2c3b60
commit a207c90cb9
3 changed files with 177 additions and 58 deletions

View File

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 142,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@ -118,7 +118,7 @@
},
{
"cell_type": "code",
"execution_count": 143,
"execution_count": 2,
"metadata": {},
"outputs": [
{
@ -155,7 +155,7 @@
},
{
"cell_type": "code",
"execution_count": 144,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
@ -284,7 +284,7 @@
},
{
"cell_type": "code",
"execution_count": 145,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
@ -314,7 +314,7 @@
},
{
"cell_type": "code",
"execution_count": 146,
"execution_count": 15,
"metadata": {},
"outputs": [
{
@ -331,10 +331,10 @@
"mode": "markers+lines+text",
"name": "16",
"text": [
"0",
"1",
"2",
"3"
"16:0",
"16:1",
"16:2",
"16:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -364,10 +364,10 @@
"mode": "markers+lines+text",
"name": "17",
"text": [
"0",
"1",
"2",
"3"
"17:0",
"17:1",
"17:2",
"17:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -397,10 +397,10 @@
"mode": "markers+lines+text",
"name": "18",
"text": [
"0",
"1",
"2",
"3"
"18:0",
"18:1",
"18:2",
"18:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -430,10 +430,10 @@
"mode": "markers+lines+text",
"name": "19",
"text": [
"0",
"1",
"2",
"3"
"19:0",
"19:1",
"19:2",
"19:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -483,10 +483,10 @@
"mode": "markers+lines+text",
"name": "20",
"text": [
"0",
"1",
"2",
"3"
"20:0",
"20:1",
"20:2",
"20:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -516,10 +516,10 @@
"mode": "markers+lines+text",
"name": "21",
"text": [
"0",
"1",
"2",
"3"
"21:0",
"21:1",
"21:2",
"21:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -549,10 +549,10 @@
"mode": "markers+lines+text",
"name": "22",
"text": [
"0",
"1",
"2",
"3"
"22:0",
"22:1",
"22:2",
"22:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -582,10 +582,10 @@
"mode": "markers+lines+text",
"name": "23",
"text": [
"0",
"1",
"2",
"3"
"23:0",
"23:1",
"23:2",
"23:3"
],
"textposition": "middle center",
"type": "scatter3d",
@ -635,10 +635,10 @@
"mode": "markers+lines+text",
"name": "24",
"text": [
"0",
"1",
"2",
"3"
"24:0",
"24:1",
"24:2",
"24:3"
],
"type": "scatter3d",
"x": [
@ -667,10 +667,10 @@
"mode": "markers+lines+text",
"name": "25",
"text": [
"0",
"1",
"2",
"3"
"25:0",
"25:1",
"25:2",
"25:3"
],
"type": "scatter3d",
"x": [
@ -699,10 +699,10 @@
"mode": "markers+lines+text",
"name": "26",
"text": [
"0",
"1",
"2",
"3"
"26:0",
"26:1",
"26:2",
"26:3"
],
"type": "scatter3d",
"x": [
@ -731,10 +731,10 @@
"mode": "markers+lines+text",
"name": "27",
"text": [
"0",
"1",
"2",
"3"
"27:0",
"27:1",
"27:2",
"27:3"
],
"type": "scatter3d",
"x": [
@ -1625,15 +1625,15 @@
],
"source": [
"fig = go.Figure()\n",
"t_corners = plane_a.transformed_corners\n",
"for i, corners in enumerate(t_corners):\n",
"t_corners_a = plane_a.transformed_corners\n",
"for i, corners in enumerate(t_corners_a):\n",
" fig.add_trace(\n",
" go.Scatter3d(\n",
" x=corners[:, 0],\n",
" y=corners[:, 1],\n",
" z=corners[:, 2],\n",
" mode=\"markers+lines+text\",\n",
" text=list(range(4)),\n",
" text=list(map(lambda x: f\"{plane_a.ids[i]}:{x}\", range(4))),\n",
" textposition=\"middle center\",\n",
" name=str(plane_a.ids[i]),\n",
" marker=dict(size=1),\n",
@ -1660,7 +1660,7 @@
" y=corners[:, 1],\n",
" z=corners[:, 2],\n",
" mode=\"markers+lines+text\",\n",
" text=list(range(4)),\n",
" text=list(map(lambda x: f\"{plane_b.ids[i]}:{x}\", range(4))),\n",
" textposition=\"middle center\",\n",
" name=str(plane_b.ids[i]),\n",
" marker=dict(size=1),\n",
@ -1685,7 +1685,7 @@
" y=corners[:, 1],\n",
" z=corners[:, 2],\n",
" mode=\"markers+lines+text\",\n",
" text=list(range(4)),\n",
" text=list(map(lambda x: f\"{plane_c.ids[i]}:{x}\", range(4))),\n",
" name=str(plane_c.ids[i]),\n",
" marker=dict(size=1),\n",
" )\n",
@ -1719,6 +1719,59 @@
")\n",
"fig.show()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre>[{name: &#x27;a&#x27;, ids: [16, 17, 18, 19], corners: [[...], ...]},\n",
" {name: &#x27;b&#x27;, ids: [20, 21, 22, 23], corners: [[...], ...]},\n",
" {name: &#x27;c&#x27;, ids: [24, 25, 26, 27], corners: [[...], ...]}]\n",
"-----------------------------------------------------------\n",
"type: 3 * {\n",
" name: string,\n",
" ids: var * int64,\n",
" corners: var * var * var * float64\n",
"}</pre>"
],
"text/plain": [
"<Array [{name: 'a', ids: [...], ...}, ...] type='3 * {name: string, ids: va...'>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import awkward as ak\n",
"from awkward import Record as AwkwardRecord, Array as AwkwardArray\n",
"\n",
"coords = AwkwardArray(\n",
" [\n",
" {\n",
" \"name\": \"a\",\n",
" \"ids\": plane_a.ids,\n",
" \"corners\": t_corners_a,\n",
" },\n",
" {\n",
" \"name\": \"b\",\n",
" \"ids\": plane_b.ids,\n",
" \"corners\": t_corners_b,\n",
" },\n",
" {\n",
" \"name\": \"c\",\n",
" \"ids\": plane_c.ids,\n",
" \"corners\": t_corners_c,\n",
" },\n",
" ]\n",
")\n",
"display(coords)\n",
"_ = ak.to_parquet(coords, \"output/object_points.parquet\")"
]
}
],
"metadata": {

63
find_cute_object.py Normal file
View File

@ -0,0 +1,63 @@
import cv2
from cv2 import aruco
from datetime import datetime
from loguru import logger
from pathlib import Path
from typing import cast, Final
import awkward as ak
from cv2.typing import MatLike
import numpy as np
NDArray = np.ndarray
CALIBRATION_PARQUET = Path("output") / "usbcam_cal.parquet"
OBJECT_POINTS_PARQUET = Path("output") / "object_points.parquet"
DICTIONARY: Final[int] = aruco.DICT_4X4_50
# 400mm
MARKER_LENGTH: Final[float] = 0.4
def gen():
API = cv2.CAP_AVFOUNDATION
cap = cv2.VideoCapture(0, API)
while True:
ret, frame = cap.read()
if not ret:
logger.warning("Failed to grab frame")
break
yield frame
def main():
aruco_dict = aruco.getPredefinedDictionary(DICTIONARY)
cal = ak.from_parquet(CALIBRATION_PARQUET)[0]
camera_matrix = cast(MatLike, ak.to_numpy(cal["camera_matrix"]))
distortion_coefficients = cast(MatLike, ak.to_numpy(cal["distortion_coefficients"]))
ops = ak.from_parquet(OBJECT_POINTS_PARQUET)
board = aruco.CharucoBoard(
size=(3, 3), squareLength=0.127, markerLength=0.097, dictionary=aruco_dict
)
detector = aruco.CharucoDetector(board)
for frame in gen():
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# pylint: disable-next=unpacking-non-sequence
diamond_corners, diamond_ids, markers, marker_ids = detector.detectDiamonds(
grey
)
# `markers` is [N, 1, 4, 2]
# `ids` is [N, 1]
if diamond_ids is not None:
aruco.drawDetectedDiamonds(frame, diamond_corners, diamond_ids)
cv2.imshow("frame", frame)
if (k := cv2.waitKey(1)) == ord("q"):
logger.info("Exiting")
break
elif k == ord("s"):
now = datetime.now().strftime("%Y%m%d%H%M%S")
file_name = f"aruco_{now}.png"
logger.info("Saving to {}", file_name)
cv2.imwrite(file_name, frame)
if __name__ == "__main__":
main()

BIN
output/object_points.parquet LFS Normal file

Binary file not shown.