import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage import io
from numpy import fft
from IPython.html import widgets
%matplotlib inline
Hough Transform is a popular technique to detect any shape, if you can represent that shape in mathematical form. It can detect the shape even if it is broken or distorted a little bit. We will see how it works for a line.
cv2.HoughLines()
: HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]]) -> lines
return lines are array of ($\rho$, $\theta$) pairs. lines above origin have negative $\rho$
parameters image should be a binary image (e.g., by thrsholding or canny detection)
parameters rho and theta are precision for detected $\rho$ and $\theta$
parameters threshold are essnetially length of the line in terms of number of points
cv2.HoughLinesP()
is usually easier to use, because it returns starting, ending pionts, instead of $\rho$ and $\theta$
two more parameters:
sudoku = cv2.imread("public-images/sudoku.jpg")[:,:,::-1]
sudoku_gray = cv2.cvtColor(sudoku, cv2.COLOR_RGB2GRAY)
edges = cv2.Canny(sudoku_gray, 50, 150)
plt.imshow(edges, cmap = plt.cm.gray)
<matplotlib.image.AxesImage at 0x7f7ace10bc50>
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength = 450, maxLineGap = 200)
lined_img = sudoku.copy()
print len(lines)
for line in lines[:]:
startx, starty, endx, endy = line[0]
lined_img = cv2.line(lined_img, (startx, starty), (endx, endy),
color = (255, 0, 0), thickness = 2)
plt.imshow(lined_img)
69
<matplotlib.image.AxesImage at 0x7f7ace2d0250>
marbles = cv2.imread("public-images/marbles.jpg")[:,:,::-1]
marbles_gray = cv2.cvtColor(marbles, cv2.COLOR_RGB2GRAY)
marbles_gray = cv2.Canny(marbles_gray, 150, 200)
plt.imshow(marbles_gray, cmap = plt.cm.gray)
<matplotlib.image.AxesImage at 0x7f7ac8eb8dd0>
circles = cv2.HoughCircles(marbles_gray, cv2.HOUGH_GRADIENT, dp = 10, minDist = 50, minRadius = 30,
maxRadius = 60)
circled_img = marbles.copy()
for x, y, r in circles[0]:
circled_img = cv2.circle(circled_img, (x, y), r, color = (255, 0, 0), thickness = 5)
plt.imshow(circled_img)
<matplotlib.image.AxesImage at 0x7f7ac8d7f1d0>
** there is a big problem in the result, as the hough circle depends on the edge detection result**