137 lines
4.2 KiB
Plaintext
137 lines
4.2 KiB
Plaintext
|
{
|
||
|
"cells": [
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"import numpy as np\n",
|
||
|
"import imageio\n",
|
||
|
"import math"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 2,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"def rgb2gray(rgb):\n",
|
||
|
" return np.dot(rgb[..., :3], [0.299, 0.587, 0.114]).astype(np.uint8)\n",
|
||
|
"\n",
|
||
|
"\n",
|
||
|
"def hough_line(img, angle_step=1, lines_are_white=True, value_threshold=5):\n",
|
||
|
" \"\"\"\n",
|
||
|
" Hough transform for lines\n",
|
||
|
"\n",
|
||
|
" Input:\n",
|
||
|
" img - 2D binary image with nonzeros representing edges\n",
|
||
|
" angle_step - Spacing between angles to use every n-th angle\n",
|
||
|
" between -90 and 90 degrees. Default step is 1.\n",
|
||
|
" lines_are_white - boolean indicating whether lines to be detected are white\n",
|
||
|
" value_threshold - Pixel values above or below the value_threshold are edges\n",
|
||
|
"\n",
|
||
|
" Returns:\n",
|
||
|
" accumulator - 2D array of the hough transform accumulator\n",
|
||
|
" theta - array of angles used in computation, in radians.\n",
|
||
|
" rhos - array of rho values. Max size is 2 times the diagonal\n",
|
||
|
" distance of the input image.\n",
|
||
|
" \"\"\"\n",
|
||
|
" # Rho and Theta ranges\n",
|
||
|
" thetas = np.deg2rad(np.arange(-90.0, 90.0, angle_step))\n",
|
||
|
" width, height = img.shape\n",
|
||
|
" diag_len = int(round(math.sqrt(width * width + height * height)))\n",
|
||
|
" rhos = np.linspace(-diag_len, diag_len, diag_len * 2)\n",
|
||
|
"\n",
|
||
|
" # Cache some resuable values\n",
|
||
|
" cos_t = np.cos(thetas)\n",
|
||
|
" sin_t = np.sin(thetas)\n",
|
||
|
" num_thetas = len(thetas)\n",
|
||
|
"\n",
|
||
|
" # Hough accumulator array of theta vs rho\n",
|
||
|
" accumulator = np.zeros((2 * diag_len, num_thetas), dtype=np.uint8)\n",
|
||
|
" # (row, col) indexes to edges\n",
|
||
|
" are_edges = img > value_threshold if lines_are_white else img < value_threshold\n",
|
||
|
" y_idxs, x_idxs = np.nonzero(are_edges)\n",
|
||
|
"\n",
|
||
|
" # Vote in the hough accumulator\n",
|
||
|
" for i in range(len(x_idxs)):\n",
|
||
|
" x = x_idxs[i]\n",
|
||
|
" y = y_idxs[i]\n",
|
||
|
"\n",
|
||
|
" for t_idx in range(num_thetas):\n",
|
||
|
" # Calculate rho. diag_len is added for a positive index\n",
|
||
|
" rho = diag_len + int(round(x * cos_t[t_idx] + y * sin_t[t_idx]))\n",
|
||
|
" accumulator[rho, t_idx] += 1\n",
|
||
|
"\n",
|
||
|
" return accumulator, thetas, rhos"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 3,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"def show_hough_line(img, accumulator, thetas, rhos, save_path=None):\n",
|
||
|
" import matplotlib.pyplot as plt\n",
|
||
|
"\n",
|
||
|
" fig, ax = plt.subplots(1, 2, figsize=(10, 10))\n",
|
||
|
"\n",
|
||
|
" ax[0].imshow(img, cmap=plt.cm.gray)\n",
|
||
|
" ax[0].set_title('Input image')\n",
|
||
|
" ax[0].axis('image')\n",
|
||
|
"\n",
|
||
|
" ax[1].imshow(\n",
|
||
|
" accumulator, cmap='jet',\n",
|
||
|
" extent=[np.rad2deg(thetas[-1]), np.rad2deg(thetas[0]), rhos[-1], rhos[0]])\n",
|
||
|
" ax[1].set_aspect('equal', adjustable='box')\n",
|
||
|
" ax[1].set_title('Hough transform')\n",
|
||
|
" ax[1].set_xlabel('Angles (degrees)')\n",
|
||
|
" ax[1].set_ylabel('Distance (pixels)')\n",
|
||
|
" ax[1].axis('image')\n",
|
||
|
"\n",
|
||
|
" # plt.axis('off')\n",
|
||
|
" if save_path is not None:\n",
|
||
|
" plt.savefig(save_path, bbox_inches='tight')\n",
|
||
|
" plt.show()"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 4,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"imgpath = '../images/bangdiem.png'\n",
|
||
|
"img = imageio.imread(imgpath)\n",
|
||
|
"if img.ndim == 3:\n",
|
||
|
" img = rgb2gray(img)\n",
|
||
|
"accumulator, thetas, rhos = hough_line(img)"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"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.7.2"
|
||
|
}
|
||
|
},
|
||
|
"nbformat": 4,
|
||
|
"nbformat_minor": 2
|
||
|
}
|