import cv2
import numpy as np

image=cv2.imread('10076.jpg')
image = cv2.resize(image, (800, 800))

grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('grayImage', grayImage)

edgeImage = grayImage

# 直方图均衡
edgeImage = cv2.equalizeHist(edgeImage)
cv2.imshow('equalizeHist', edgeImage)

'''
# 自适应直方图均衡
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
edgeImage = clahe.apply(edgeImage)
cv2.imshow('createCLAHE', edgeImage)
'''

# 二值化
h, w = edgeImage.shape[:2]
m = np.reshape(edgeImage, [1, w*h])
mean = m.sum()/(w*h)
# binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)
ret, binary = cv2.threshold(edgeImage, mean, 255, cv2.THRESH_BINARY)
image_binary = 255 - binary
cv2.imshow('image_binary', image_binary)

'''
# 双边滤波
edgeImage = cv2.bilateralFilter(edgeImage,9,75,75)
cv2.imshow('bilateralFilter', edgeImage)
'''

'''
# 中位模糊
edgeImage = cv2.medianBlur(edgeImage,5)
cv2.imshow('medianBlur', edgeImage)
'''

# 高斯模糊
edgeImage = cv2.GaussianBlur(grayImage, (3, 3), 1)
cv2.imshow('GaussianBlur', edgeImage)

'''
# 平均
edgeImage = cv2.blur(edgeImage,(5,5))
cv2.imshow('blur', edgeImage)
'''

# 边缘检测
canny = cv2.Canny(edgeImage, 20, 80)
cv2.imshow('Canny', canny)

kernel = np.ones((5,5),np.uint8)
dilate = cv2.dilate(canny,kernel,iterations = 1) 
cv2.imshow('dilate', dilate)

'''
# 轮廓检测
ret, thresh = cv2.threshold(edgeImage, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

def cnt_area(cnt):
  area = cv2.contourArea(cnt)
  return area
contours.sort(key = cnt_area, reverse=True)
print(len(contours))
for i in range(0, 1):
    cnt = contours[i]
    img = image.copy()
    cv2.drawContours(img, [cnt], 0, (0,255,0), 3)
    cv2.imshow('drawContours_' + str(i), img)
cv2.drawContours(image, contours, -1, (0,255,0), 1)
cv2.imshow('drawContours', image)
'''

laplacian = cv2.Laplacian(edgeImage,cv2.CV_8U)
# laplacian = cv2.Laplacian(edgeImage,cv2.CV_64F)
cv2.imshow('laplacian', laplacian)

# 二值化
h, w = laplacian.shape[:2]
m = np.reshape(laplacian, [1, w*h])
mean = m.sum()/(w*h)
# binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)
ret, laplacian_binary = cv2.threshold(laplacian, mean, 255, cv2.THRESH_BINARY)
cv2.imshow('laplacian_binary', laplacian_binary)

sobelx = edgeImage
for i in range(0, 6): # 3,6,8有奇效(3: HoughLinesP检测竖线, 6: HoughLines检测竖线, 8:检测横线)
    sobelx = cv2.Sobel(sobelx,cv2.CV_8U,1,0,ksize=5)
    # sobelx = cv2.Sobel(edgeImage,cv2.CV_64F,1,0,ksize=5)
cv2.imshow('sobelx', sobelx)

sobely = edgeImage
for i in range(0, 6): # 3,6,8有奇效(3: HoughLinesP检测横线, 6: HoughLines检测横线, 8:检测竖线)
    sobely = cv2.Sobel(sobely,cv2.CV_8U,0,1,ksize=5)
    # sobely = cv2.Sobel(edgeImage,cv2.CV_64F,0,1,ksize=5)
cv2.imshow('sobely', sobely)

binary_1 = cv2.bitwise_and(dilate, laplacian_binary)
cv2.imshow('binary_1', binary_1)

sobelx_binary = cv2.bitwise_and(sobelx, binary_1)
cv2.imshow('sobelx_binary', sobelx_binary)

sobely_binary = cv2.bitwise_and(sobely, binary_1)
cv2.imshow('sobely_binary', sobely_binary)

lineXImage = sobelx_binary
lineYImage = sobely_binary

'''
# 侵蚀
kernel = np.ones((5,5),np.uint8)
edgeImage = cv2.erode(edgeImage,kernel,iterations = 1)
cv2.imshow('erode', edgeImage)
'''

'''
# 扩张
kernel = np.ones((5,5),np.uint8)
edgeImage = cv2.dilate(edgeImage,kernel,iterations = 1) 
cv2.imshow('dilate', edgeImage)
'''

'''
# 开运算
kernel = np.ones((5,5),np.uint8)
edgeImage = cv2.morphologyEx(edgeImage, cv2.MORPH_OPEN, kernel)
cv2.imshow('morphologyEx', edgeImage)
'''

'''
# 闭运算
kernel = np.ones((5,5),np.uint8)
morphologyEx = cv2.morphologyEx(edgeImage, cv2.MORPH_CLOSE, kernel)
cv2.imshow('morphologyEx', morphologyEx)
'''

'''
# 形态学梯度
kernel = np.ones((5,5),np.uint8)
edgeImage = cv2.morphologyEx(edgeImage, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('morphologyEx', edgeImage)
'''

'''
# 顶帽
kernel = np.ones((5,5),np.uint8)
edgeImage = cv2.morphologyEx(edgeImage, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('morphologyEx', edgeImage)
'''

'''
# 黑帽
kernel = np.ones((5,5),np.uint8)
edgeImage = cv2.morphologyEx(edgeImage, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('morphologyEx', edgeImage)
'''

'''
# 锐化
cv2.imshow('edgeImage + edgeImage', edgeImage + edgeImage)
'''

def findLine(edgeImage, title):
    houghLinesImage = image.copy()
    lines = cv2.HoughLines(edgeImage,1,np.pi/180,200)
    print(len(lines))
    for line in lines:
        rho,theta = line[0]
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 1000*(-b))
        y1 = int(y0 + 1000*(a))
        x2 = int(x0 - 1000*(-b))
        y2 = int(y0 - 1000*(a))
        if (x2-x1) == 0 :
            xielv = (y2-y1)/0.00000001
        else:
            xielv = (y2-y1)/(x2-x1)
        '''
        if (xielv > -0.08 and xielv < 0.08)  or xielv > 8.0 or xielv < -8.0 :
            print(xielv)
        '''
        cv2.line(houghLinesImage,(x1,y1),(x2,y2),(0,0,255),2)
    cv2.imshow('houghLinesImage' + title, houghLinesImage)

    houghLinesPImage = image.copy()
    thresh_min = min(edgeImage.shape)
    lines = cv2.HoughLinesP(edgeImage, 1.2, np.pi / 180, 160, minLineLength=int(edgeImage.shape[0] * 0.7),maxLineGap=int(thresh_min * 0.5))
    print(len(lines))
    for line in lines:
        x1,y1,x2,y2 = line[0]
        xielv = (y2-y1)/(x2-x1)
        '''
        if (xielv > -0.08 and xielv < 0.08)  or xielv > 8.0 or xielv < -8.0 :
            print(xielv)
        '''
        cv2.line(houghLinesPImage,(x1,y1),(x2,y2),(255,0,0),2)
    cv2.imshow('HoughLinesP' + title, houghLinesPImage)

findLine(lineXImage, 'X')
findLine(lineYImage, 'Y')

'''
circles = cv2.HoughCircles(edgeImage,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # 绘制外圆
    cv2.circle(image,(i[0],i[1]),i[2],(0,255,0),2)
    # 绘制圆心
    cv2.circle(image,(i[0],i[1]),2,(0,0,255),3)
'''

'''
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1, pts2)
image = cv2.warpPerspective(image, M, (600, 600))
cv2.imshow('show', image)
'''

cv2.waitKey(0)
cv2.destroyAllWindows()