cute object we go
This commit is contained in:
169
boom.ipynb
169
boom.ipynb
@ -2,7 +2,7 @@
|
|||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 142,
|
"execution_count": 1,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -118,7 +118,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 143,
|
"execution_count": 2,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -155,7 +155,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 144,
|
"execution_count": 3,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -284,7 +284,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 145,
|
"execution_count": 4,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -314,7 +314,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 146,
|
"execution_count": 15,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -331,10 +331,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "16",
|
"name": "16",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"16:0",
|
||||||
"1",
|
"16:1",
|
||||||
"2",
|
"16:2",
|
||||||
"3"
|
"16:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -364,10 +364,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "17",
|
"name": "17",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"17:0",
|
||||||
"1",
|
"17:1",
|
||||||
"2",
|
"17:2",
|
||||||
"3"
|
"17:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -397,10 +397,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "18",
|
"name": "18",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"18:0",
|
||||||
"1",
|
"18:1",
|
||||||
"2",
|
"18:2",
|
||||||
"3"
|
"18:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -430,10 +430,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "19",
|
"name": "19",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"19:0",
|
||||||
"1",
|
"19:1",
|
||||||
"2",
|
"19:2",
|
||||||
"3"
|
"19:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -483,10 +483,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "20",
|
"name": "20",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"20:0",
|
||||||
"1",
|
"20:1",
|
||||||
"2",
|
"20:2",
|
||||||
"3"
|
"20:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -516,10 +516,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "21",
|
"name": "21",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"21:0",
|
||||||
"1",
|
"21:1",
|
||||||
"2",
|
"21:2",
|
||||||
"3"
|
"21:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -549,10 +549,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "22",
|
"name": "22",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"22:0",
|
||||||
"1",
|
"22:1",
|
||||||
"2",
|
"22:2",
|
||||||
"3"
|
"22:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -582,10 +582,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "23",
|
"name": "23",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"23:0",
|
||||||
"1",
|
"23:1",
|
||||||
"2",
|
"23:2",
|
||||||
"3"
|
"23:3"
|
||||||
],
|
],
|
||||||
"textposition": "middle center",
|
"textposition": "middle center",
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
@ -635,10 +635,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "24",
|
"name": "24",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"24:0",
|
||||||
"1",
|
"24:1",
|
||||||
"2",
|
"24:2",
|
||||||
"3"
|
"24:3"
|
||||||
],
|
],
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
"x": [
|
"x": [
|
||||||
@ -667,10 +667,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "25",
|
"name": "25",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"25:0",
|
||||||
"1",
|
"25:1",
|
||||||
"2",
|
"25:2",
|
||||||
"3"
|
"25:3"
|
||||||
],
|
],
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
"x": [
|
"x": [
|
||||||
@ -699,10 +699,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "26",
|
"name": "26",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"26:0",
|
||||||
"1",
|
"26:1",
|
||||||
"2",
|
"26:2",
|
||||||
"3"
|
"26:3"
|
||||||
],
|
],
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
"x": [
|
"x": [
|
||||||
@ -731,10 +731,10 @@
|
|||||||
"mode": "markers+lines+text",
|
"mode": "markers+lines+text",
|
||||||
"name": "27",
|
"name": "27",
|
||||||
"text": [
|
"text": [
|
||||||
"0",
|
"27:0",
|
||||||
"1",
|
"27:1",
|
||||||
"2",
|
"27:2",
|
||||||
"3"
|
"27:3"
|
||||||
],
|
],
|
||||||
"type": "scatter3d",
|
"type": "scatter3d",
|
||||||
"x": [
|
"x": [
|
||||||
@ -1625,15 +1625,15 @@
|
|||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"fig = go.Figure()\n",
|
"fig = go.Figure()\n",
|
||||||
"t_corners = plane_a.transformed_corners\n",
|
"t_corners_a = plane_a.transformed_corners\n",
|
||||||
"for i, corners in enumerate(t_corners):\n",
|
"for i, corners in enumerate(t_corners_a):\n",
|
||||||
" fig.add_trace(\n",
|
" fig.add_trace(\n",
|
||||||
" go.Scatter3d(\n",
|
" go.Scatter3d(\n",
|
||||||
" x=corners[:, 0],\n",
|
" x=corners[:, 0],\n",
|
||||||
" y=corners[:, 1],\n",
|
" y=corners[:, 1],\n",
|
||||||
" z=corners[:, 2],\n",
|
" z=corners[:, 2],\n",
|
||||||
" mode=\"markers+lines+text\",\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",
|
" textposition=\"middle center\",\n",
|
||||||
" name=str(plane_a.ids[i]),\n",
|
" name=str(plane_a.ids[i]),\n",
|
||||||
" marker=dict(size=1),\n",
|
" marker=dict(size=1),\n",
|
||||||
@ -1660,7 +1660,7 @@
|
|||||||
" y=corners[:, 1],\n",
|
" y=corners[:, 1],\n",
|
||||||
" z=corners[:, 2],\n",
|
" z=corners[:, 2],\n",
|
||||||
" mode=\"markers+lines+text\",\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",
|
" textposition=\"middle center\",\n",
|
||||||
" name=str(plane_b.ids[i]),\n",
|
" name=str(plane_b.ids[i]),\n",
|
||||||
" marker=dict(size=1),\n",
|
" marker=dict(size=1),\n",
|
||||||
@ -1685,7 +1685,7 @@
|
|||||||
" y=corners[:, 1],\n",
|
" y=corners[:, 1],\n",
|
||||||
" z=corners[:, 2],\n",
|
" z=corners[:, 2],\n",
|
||||||
" mode=\"markers+lines+text\",\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",
|
" name=str(plane_c.ids[i]),\n",
|
||||||
" marker=dict(size=1),\n",
|
" marker=dict(size=1),\n",
|
||||||
" )\n",
|
" )\n",
|
||||||
@ -1719,6 +1719,59 @@
|
|||||||
")\n",
|
")\n",
|
||||||
"fig.show()"
|
"fig.show()"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 16,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/html": [
|
||||||
|
"<pre>[{name: 'a', ids: [16, 17, 18, 19], corners: [[...], ...]},\n",
|
||||||
|
" {name: 'b', ids: [20, 21, 22, 23], corners: [[...], ...]},\n",
|
||||||
|
" {name: 'c', 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": {
|
"metadata": {
|
||||||
|
|||||||
63
find_cute_object.py
Normal file
63
find_cute_object.py
Normal 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
BIN
output/object_points.parquet
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user