Skip to content

Instantly share code, notes, and snippets.

@cmastudios
Last active January 12, 2020 06:14
Show Gist options
  • Save cmastudios/968da20146957e69285fc1102c9b1539 to your computer and use it in GitHub Desktop.
Save cmastudios/968da20146957e69285fc1102c9b1539 to your computer and use it in GitHub Desktop.
2020 FRC vision finding pose of high target
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import cv2\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Camera parameters - obtained through calibration"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"cameraMatrix = np.array([\n",
" [308.458, 0, 326.496],\n",
" [ 0, 308.463, 235.230],\n",
" [ 0, 0, 1 ]\n",
"])\n",
"distCoeffs = np.array([-0.0081333, -0.0560598, -0.003446, -0.00018859, 0.148150])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Input image taken of the high target"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f32bf7d3fa0>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"image = cv2.imread(\"hightarget.jpg\", 0)\n",
"plt.imshow(image, cmap=\"gray\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Image filtering"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f32bf76ce80>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"_, thresholded = cv2.threshold(image, 100, 255, cv2.THRESH_BINARY)\n",
"kernel = np.mat(\"1 0 1; 0 1 0; 1 0 1\", dtype=np.uint8)\n",
"morphed = cv2.erode(thresholded, kernel)\n",
"morphed = cv2.dilate(morphed, kernel)\n",
"plt.imshow(morphed, cmap=\"gray\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Contour extraction"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f32bf037af0>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"contours, hierarchy = cv2.findContours(morphed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n",
"demo = np.zeros((480, 640, 3), dtype=np.uint8)\n",
"cv2.drawContours(demo, contours, -1, (255,0,0), 2)\n",
"plt.imshow(demo)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Find the outer shell of the target"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"contour = contours[0]\n",
"hull = cv2.convexHull(contour)\n",
"poly = cv2.approxPolyDP(hull, 5, True)\n",
"len(poly)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f32bf015070>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"demo = np.zeros((480, 640, 3), dtype=np.uint8)\n",
"cv2.drawContours(demo, [poly], -1, (255,0,0), 2)\n",
"plt.imshow(demo)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Order the image points to match object points"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[181., 341.],\n",
" [250., 327.],\n",
" [230., 365.],\n",
" [189., 368.]], dtype=float32)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#what's so cool about a trapezoid? should be able to easily identify TL or TR\n",
"in_pts = np.squeeze(poly)\n",
"min_x = min([x for (x, y) in in_pts])\n",
"max_x = max([x for (x, y) in in_pts])\n",
"min_y = min([y for (x, y) in in_pts])\n",
"from itertools import cycle\n",
"it = cycle(in_pts) # iterate clockwise repeating\n",
"ordered_pts = [0,0,0,0]\n",
"pt_idx = 0\n",
"for i in range(4):\n",
" x, y = in_pt = next(it) # pull next point from trapezoid\n",
" # first check if definitively top left\n",
" if x == min_x and y == min_y:\n",
" pt_idx = 0\n",
" ordered_pts[pt_idx] = in_pt\n",
" break\n",
" # then try definitive top right\n",
" elif x == max_x and y == min_y:\n",
" pt_idx = 1\n",
" ordered_pts[pt_idx] = in_pt\n",
" break\n",
" if i == 3:\n",
" raise RuntimeError(\"Failed\")\n",
"\n",
"tally = 1\n",
"while tally < 4:\n",
" pt_idx += 1\n",
" if pt_idx > 3:\n",
" pt_idx = 0\n",
" in_pt = next(it)\n",
" ordered_pts[pt_idx] = in_pt\n",
" tally += 1\n",
"\n",
"imagePoints = np.array(ordered_pts, dtype=np.float32)\n",
"imagePoints"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Solve\n",
"Object points are inches from the center of the white line to the high target"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 47.37, 98.19, 119.8 ],\n",
" [ 86.63, 98.19, 119.8 ],\n",
" [ 76.8 , 81.19, 119.8 ],\n",
" [ 57.19, 81.19, 119.8 ]], dtype=float32)"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"objectPoints = np.array(np.mat(\"\"\"47.37\t98.19\t119.8;\n",
"86.63\t98.19\t119.8;\n",
"76.8\t81.19\t119.8;\n",
"57.19\t81.19\t119.8\"\"\"), dtype=np.float32)\n",
"objectPoints"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"imagePoints[:, 1] = 480 - imagePoints[:, 1]"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"retval, rvec, tvec = cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-140.17514218],\n",
" [ -52.42771918],\n",
" [ 13.81003314]])"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tvec"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.73903615],\n",
" [0.16432407],\n",
" [0.14831033]])"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rvec"
]
},
{
"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.8.1"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment