|
- import cv2
- import numpy as np
- import math
- from matplotlib import pyplot as plt
-
- def __clac_intersection(line_a, line_b):
- x1_a, y1_a, x2_a, y2_a = line_a
- x1_b, y1_b, x2_b, y2_b = line_b
- A_a = y2_a - y1_a
- B_a = x1_a - x2_a
- C_a = x2_a * y1_a - x1_a * y2_a
- A_b = y2_b - y1_b
- B_b = x1_b - x2_b
- C_b = x2_b * y1_b - x1_b * y2_b
- m = A_a * B_b - A_b * B_a
- output_x = (C_b * B_a - C_a * B_b) / m
- output_y = (C_a * A_b - C_b * A_a) / m
- return (int(output_x), int(output_y))
-
- img = cv2.imread('10076.jpg')
-
- img_shape = img.shape
- length = img_shape[0]
- height = img_shape[1]
-
- if length < height:
- height = int(800 * length / height)
- length = 800
- img = cv2.resize(img, (length, height))
- else:
- length = int(800 * height / length)
- height = 800
- img = cv2.resize(img, (length, height))
-
- image = img.copy()
-
- # 图片锐化
- kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)
- img = cv2.filter2D(img, -1, kernel=kernel)
- cv2.imshow('sharpening', img)
-
- # 边缘保护滤波
- img = cv2.edgePreservingFilter(img)
- cv2.imshow('edgePreservingFilter', img)
-
- hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
-
- lower_skin = np.array([11,43,46])
- upper_skin = np.array([34,255,255])
-
- mask = cv2.inRange(hsv,lower_skin,upper_skin)
- img = cv2.bitwise_and(img,img,mask=mask)
-
- img_shape = img.shape
- img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
- dst = img_gray.copy()
-
- # 获取图像的长宽
- length = img_shape[0]
- height = img_shape[1]
- midlength = length / 2
- midheight = height / 2
- quarterL = length / 3
- quarterT = height / 3
- sigmaX = 2*(quarterL**2)
- sigmaY = 2*(quarterT**2)
-
- # 设置kernel
- kernel = np.ones((5, 5), np.int16)
- kernel[2][2] = -24
-
- # 设置卷积核
- kernel2 = np.ones((5, 5), np.int16)
- kernel3 = np.ones((3, 3), np.int16)
- dst = cv2.morphologyEx(img_gray, cv2.MORPH_OPEN, kernel2)
-
- # 平滑
- # 高斯
- dst = cv2.blur(dst, (5, 5))
- # dst = cv2.GaussianBlur(dst, (5, 5), 0)
-
- # 锐化
- blur = cv2.Laplacian(dst, cv2.CV_16S, ksize=3)
- dst = cv2.convertScaleAbs(blur)
-
- # 线性滤波,低通滤波
- dst = cv2.filter2D(img_gray, -1, kernel)
-
- # 平滑(双边滤波)
- # 双边滤波
- dst = cv2.bilateralFilter(dst, 9, 100, 100)
-
- # 在二值化前进行膨胀,以增强线段
- # 膨胀导致线段筛选困难
- # dst = cv2.dilate(dst, kernel3)
-
- # 二值化
- ret, dst = cv2.threshold(dst, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
-
- # Hough变换前的高斯赋值
- # 从图像中央到边缘,逐渐降低权重
- '''
- for i in range(length):
- for j in range(height):
- dst[i][j] = dst[i][j] * math.exp((i-midlength)**2/sigmaX +
- (j-midheight)**2/sigmaY)
- '''
-
- '''
- # Hough变换
- lines = cv2.HoughLines(dst, 1, np.pi/180, 250)
-
- houghLinesImage = img.copy()
- 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', houghLinesImage)
- '''
-
- # Hough变换
- thresh_min = min(dst.shape)
- lines = cv2.HoughLinesP(dst, 1, np.pi / 180, 200, minLineLength=int(dst.shape[0] * 0.45), maxLineGap=int(thresh_min * 0.5))
-
- # 过滤斜率
- lines = list(filter(lambda line: True if abs(line[0][0] - line[0][2]) < 280 or abs(line[0][1] - line[0][3]) < 280 else False, lines))
-
- houghLinesImage = img.copy()
- for line in lines:
- x1,y1,x2,y2 = line[0]
- cv2.line(houghLinesImage,(x1,y1),(x2,y2),(0,0,255),2)
- cv2.imshow('houghLinesImage', houghLinesImage)
-
-
- if lines is not None:
- lines_vertical = filter(lambda line: True if abs(line[0][1] - line[0][3]) > length * 0.2 else False, lines)
- lines_horizontal = filter(lambda line: True if abs(line[0][0] - line[0][2]) > height * 0.2 else False, lines)
-
- # lines_vertical = filter(isVerticalLine, lines_vertical)
- # lines_horizontal = filter(isHorizontalLine, lines_horizontal)
-
- lines_vertical = sorted(lines_vertical, key=lambda line: (line[0][0] + line[0][2]) / 2)
- lines_horizontal = sorted(lines_horizontal , key=lambda line: (line[0][1] + line[0][3]) / 2)
-
- if len(lines_vertical) > 2 and len(lines_horizontal) > 2:
- houghLines = [lines_vertical[0][0], lines_horizontal [0][0], lines_vertical[-1][0], lines_horizontal [-1][0]]
-
- houghEdgeImage = image.copy()
- cv2.line(houghEdgeImage,(houghLines[0][0],houghLines[0][1]),(houghLines[0][2],houghLines[0][3]),(255,0,0),2)
- cv2.line(houghEdgeImage,(houghLines[2][0],houghLines[2][1]),(houghLines[2][2],houghLines[2][3]),(0,255,0),2)
- cv2.line(houghEdgeImage,(houghLines[1][0],houghLines[1][1]),(houghLines[1][2],houghLines[1][3]),(0,0,255),2)
- cv2.line(houghEdgeImage,(houghLines[3][0],houghLines[3][1]),(houghLines[3][2],houghLines[3][3]),(255,255,0),2)
- cv2.imshow('houghEdge', houghEdgeImage)
-
- p1 = __clac_intersection((houghLines[0][0],houghLines[0][1], houghLines[0][2],houghLines[0][3]), (houghLines[1][0],houghLines[1][1], houghLines[1][2],houghLines[1][3]))
- p2 = __clac_intersection((houghLines[1][0],houghLines[1][1], houghLines[1][2],houghLines[1][3]), (houghLines[2][0],houghLines[2][1], houghLines[2][2],houghLines[2][3]))
- p3 = __clac_intersection((houghLines[2][0],houghLines[2][1], houghLines[2][2],houghLines[2][3]), (houghLines[3][0],houghLines[3][1], houghLines[3][2],houghLines[3][3]))
- p4 = __clac_intersection((houghLines[3][0],houghLines[3][1], houghLines[3][2],houghLines[3][3]), (houghLines[0][0],houghLines[0][1], houghLines[0][2],houghLines[0][3]))
-
- warpPerspectiveImage = image.copy()
- pts1 = np.float32([p1,p2,p4,p3])
- pts2 = np.float32([[0,0],[800,0],[0,800],[800,800]])
- M = cv2.getPerspectiveTransform(pts1,pts2)
- dst = cv2.warpPerspective(warpPerspectiveImage,M,(800,800))
- cv2.imshow('warpPerspective', dst)
-
-
- # 利用方差进行平行线的判断
- # 近邻生长法
- # Hough变换
- # 首先找到水平的范围,上边界为rho最大,theta最小,下边界为rho最小,theta最大(<90)
- ThetaMIN2 = 180
- ThetaMIN = 180
- ThetaMAX = -1
- ThetaMAX2 = -1
- RhoMAX = -1
- RhoMAX2 = -1
- RhoMIN = 1000
- RhoMIN2 = 1000
- up = 0
- bot = 0
- up2 = 0
- bot2 = 0
-
- '''
- for i in range(int(lines[0].size/2)):
- # 遍历全部点集
- r, t = lines[0][i]
- print(lines[0][i])
- t = t / np.pi*180
- if t < 90:
- # theta < 90,属于水平范围
- if t > ThetaMAX:
- ThetaMAX = t
- up = i
- if r > RhoMAX:
- RhoMAX = r
- bot = i
- else:
- if t > ThetaMAX2:
- ThetaMAX2 = t
- up2 = i
- if t < ThetaMIN2:
- ThetaMIN2 = t
- bot2 = i
-
- result = [up, bot, up2, bot2]
- print(result)
- # Hough变换
- xtheta = []
- yrho = []
- for rho, theta in lines[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 theta < 0.5:
- xtheta.append(theta / np.pi * 180)
- yrho.append(rho)
- cv2.line(img, (x1, y1), (x2, y2), (255, 255, 0), 2)
-
- print(result)
- for i in result:
- rho = lines[0][i][0]
- theta = lines[0][i][1]
- 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))
- cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 10)
- '''
-
- # 计算最有可能的两条best
-
- # 显示
- # plt.subplot(1, 2, 1), plt.imshow(dst, 'gray')
-
- plt.subplot(1, 3, 1), plt.imshow(dst, 'gray')
- plt.title('test')
- plt.xticks([]), plt.yticks([])
-
- plt.subplot(1, 3, 2), plt.imshow(img_gray, 'gray')
- plt.title('ori')
- plt.xticks([]), plt.yticks([])
-
- # plt.subplot(1, 4, 3), plt.scatter(xtheta, yrho, c='b', marker='o')
- # plt.title('Hough')
- # plt.xlabel('X'), plt.ylabel('Y')
-
- plt.subplot(1, 3, 3), plt.imshow(img)
- plt.title('Lines')
- plt.xticks([]), plt.yticks([])
-
- plt.show()
|