## 3. 算法原理

1）首先我们创建一个参数空间（又叫做霍夫空间）。参数空间是ρ和θ的二维矩阵，其中θ的范围在0–180之间。

2）使用诸如Canny边缘之类的边缘检测算法检测图像的边缘之后运行该算法。值为255的像素被认为是边缘。

3）接着我们逐像素扫描图像以找到这些边缘像素，并通过使用从0到180的θ值来计算每个像素的ρ。对于同一直线上的像素，θ和rho的值将是相同的。我们在霍夫空间中以1的权重对其投票。

4）最后，投票超过一定阈值的ρ和θ的值被视为直线。

``````def hough(img):
# Create a parameter space
# Here we use a dictionary
H=dict()
# We check for pixels in image which have value more than 0(not black)
co=np.where(img>0)
co=np.array(co).T
for point in co:
for t in range(180):
# Compute rho for theta 0-180
d=int(d)
# Compare with the extreme cases for image
if d<int(np.ceil(np.sqrt(np.square(img.shape[0]) + np.square(img.shape[1])))):
if (d,t) in H:
# Upvote
H[(d,t)] += 1
else:
# Create a new vote
H[(d,t)] = 1
return H``````

## 4. 算法应用

### 4.1 彩色图到HSV空间

``````img = cv2.imread("book.jpeg")
scale_percent = 30 # percent of original size
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
# resize image
img = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)``````

### 4.2 高斯模糊

``````# Apply gaussian blur to he mask
blur = cv2.GaussianBlur(hsv, (9, 9), 3)``````

### 4.3 二值化和腐蚀操作

``````# Define the color range for the ball (in HSV format)
lower_color = np.array([0, 0, 24],np.uint8)
upper_color = np.array([179, 255, 73],np.uint8)
# Define the kernel size for the morphological operations
kernel_size = 7
# Create a mask for the ball color using cv2.inRange()

``````# Apply morphological operations to the mask to fill in gaps
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (kernel_size, kernel_size))

### 4.4 边缘检测

``````#  Use canny edges to get the edges of the image mask

### 4.5 霍夫变换

``````# Get the hough space, sort and select to 20 values
hough_space = dict(sorted(hough(edges).items(), key=lambda item: item[1],reverse=True)[:20])
# Sort the hough space w.r.t rho and theta
sorted_hough_space_unfiltered = dict(sorted(hough_space.items()))
# Get the unique rhoand theta values
unique_=unique(sorted_hough_space_unfiltered)
# Sort according to value and get the top 4 lines
unique_=dict(sorted(unique_.items(), key=lambda item: item[1],reverse=True)[:4])``````

### 4.6 计算角点

``````# Create combinations of lines
line_combinations = list(combinations(unique_.items(), 2))

intersection=[]
filter_int=[]
for (key1, value1), (key2, value2) in line_combinations:
try:
# Solve point of intersection of two lines
except:
print("Singular Matrix")

for x,y in intersection:
if x>0 and y>0:
# Get the valid cartesan co ordinates
cv2.circle(img, (x, y), 5, (0, 0, 0), -1)
cv2.putText(img, '{},{}'.format(x,y), (x-10, y), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1)
filter_int.append([x,y])``````