## 计算机几何学方式（检测线段和圆）

#直线检测
#使用霍夫直线变换做直线检测，前提条件：边缘检测已经完成
import cv2
import numpy as np
# %matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from math import atan, pi

#标准霍夫线变换
def line_detection(img, length=1000):
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
gray = cv2.GaussianBlur(gray,(3,3),0)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)  #apertureSize参数默认其实就是3
#     plt.imshow(edges)
#     plt.title('edges')
#     plt.show()
lines = cv2.HoughLines(edges, 1, np.pi/180, 80)
xstart, ystart, xend, yend = None, None, None, None
if lines is None:
print 'cannot detect any line'
return xstart, ystart, xend, yend
else:
print 'line_detection', lines.shape[0]
for line in lines:
rho, theta = line[0]  #line[0]存储的是点到直线的极径和极角，其中极角是弧度表示的。
a = np.cos(theta)   #theta是弧度
b = np.sin(theta)
x0 = a * rho    #代表x = r * cos（theta）
y0 = b * rho    #代表y = r * sin（theta）
x1 = int(x0 + length * (-b)) #计算直线起点横坐标
y1 = int(y0 + length * a)    #计算起始起点纵坐标
x2 = int(x0 - length * (-b)) #计算直线终点横坐标
y2 = int(y0 - length * a)    #计算直线终点纵坐标    注：这里的数值1000给出了画出的线段长度范围大小，数值越小，画出的线段越短，数值越大，画出的线段越长
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)    #点的坐标必须是元组，不能是列表。
if not xstart:
xstart, ystart, xend, yend = x1, y1, x2, y2
#         xstart, ystart, xend, yend = x1, y1, x2, y2
#     plt.imshow(img)
#     plt.title('img-lines')
#     plt.show()
return xstart, ystart, xend, yend

#统计概率霍夫线变换
def line_detect_possible_demo(img):
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
ray = cv2.GaussianBlur(gray,(3,3),0)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)  # apertureSize参数默认其实就是3
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 60, minLineLength=60, maxLineGap=5)
#     print 'line_detect_possible_demo', len(lines)
xstart, ystart, xend, yend = None, None, None, None
if lines is None:
print 'cannot detect any line'
return xstart, ystart, xend, yend
else:
print 'line_detection', lines.shape[0]
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
if not xstart:
xstart, ystart, xend, yend = x1, y1, x2, y2
#         xstart, ystart, xend, yend = x1, y1, x2, y2
#     plt.imshow(img)
#     plt.title('line_detect_possible_demo')
#     plt.show()
#     print 'coordinate :', xstart, ystart, xend, yend
return xstart, ystart, xend, yend

#计算角度
def calculate_reading(xstart, ystart, xend, yend, angle_min, angle_max, meas_range):
# the coordinate of the two points in the line: xstart, ystart, xend, yend
# angle_min: the start point value, 6点钟位置为零，从零出发，顺时针的相对角度
# angle_max: the end point value, 6点钟位置为零，从零出发，逆时针的相对角度
# meas_range: measure range
if not xstart or not ystart or not xend or not yend:

whole_angle = 360 - (angle_min + angle_max)
#     print 'coordinate is: ', xstart, ystart, xend, yend
if xstart == xend:
valid_angle = 90 + (90 - angle_min)
else:
angle = atan(float(ystart - yend) / (xstart - xend)) * 180 / pi
#         print 'angle with horizontal line is: ', angle
if angle < 0:
angle = 180 + angle
#         print 'after angle with horizontal line is: ', angle
valid_angle = angle + (90 - angle_min)
#     print 'valid_angle / whole_angle * meas_range', valid_angle, whole_angle, meas_range
reading = float(valid_angle) / whole_angle * meas_range

if isinstance(img_file, str):
else:
img = img_file
# print(img.shape)
# plt.imshow(img)
# plt.title('input_image')
# plt.show()

if is_poss:
xstart, ystart, xend, yend = line_detect_possible_demo(img)
else:
xstart, ystart, xend, yend = line_detection(img)

if is_plot:
plt.imshow(img)
plt.title('last show')
plt.show()


## 计算机视觉-目标检测的方法

### SSD

TensorFlow 版本在 Github 上有实现版本，具体的实践记录在此，理论学习记录。