| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 | 
							- # -*- coding:utf-8 -*-
 
- import os, sys, time
 
- import inspect
 
- import cv2 as cv
 
- import numpy as np
 
- from ssat_sdk.utils import LoggingUtil
 
- from image_util import *
 
- class LineUtil():
 
-     '''
 
-     BGR图片传入,获取直线
 
-     '''
 
-     def getLines(self, img, lineMinLen = 20, lineMaxLen = 1000, ableArea=None, threshold1=50, threshold2=100, apertureSize=5, lineThreshold = 200):
 
-         targetMat = np.array(img)
 
-         if (ableArea <> None):
 
-             targetMat = cutMat(img, ableArea)
 
-         grayMat = cv.cvtColor(targetMat, cv.COLOR_BGR2GRAY)
 
-         # cv.imshow("gray", grayMat)
 
-         lines, imageGray = self.getGrayLines(grayMat, lineMinLen,lineMaxLen,ableArea,threshold1,threshold2,apertureSize,lineThreshold)
 
-         return lines, imageGray
 
-     def getGrayLines(self, imgGray, lineMinLen = 20, lineMaxLen = 1000, ableArea=None, threshold1=50, threshold2=100, apertureSize=5, lineThreshold = 200):
 
-         edges = cv.Canny(imgGray, threshold1, threshold2, apertureSize=apertureSize)
 
-         # cv.imshow("edges",edges)
 
-         lines = cv.HoughLinesP(edges, 2, np.pi / 180, lineThreshold)
 
-         retLines = []
 
-         if lines is None:
 
-             return None, None
 
-         for line in lines:
 
-             x1, y1, x2, y2 = line[0]
 
-             # print "line:", x1, y1, x2, y2
 
-             # "line rgb:",PreImageJudge.getImgAverageRGB(targetMat, (x1, y1, x2+1, y2+1)), \
 
-             # "icon rgb:",PreImageJudge.getAverageRGB(icon)
 
-             lineLen = self.caculateLinLen(line[0])
 
-             if lineLen > lineMinLen and lineLen < lineMaxLen:
 
-                 # print "retLine:", line[0]
 
-                 cv.line(imgGray, (x1, y1), (x2, y2), 255, 2)
 
-                 retLines.append(line[0])
 
-         # cv.imshow("getLines", imgGray)
 
-         # cv.waitKey(0)
 
-         # cv.destroyAllWindows()
 
-         return retLines, imgGray
 
-     '''
 
-     :param lines:
 
-     '''
 
-     def combineLineList(self, lines, maxDistanse=5):
 
-         retLines = []
 
-         for findex in range(0, lines.__len__() - 1):
 
-             if (lines[findex] is None):
 
-                 continue
 
-             tmpLine = lines[findex]
 
-             for sindex in range(1, lines.__len__()):
 
-                 if (lines[sindex] is None):
 
-                     continue
 
-                 secondLine = lines[sindex]
 
-                 isCombined,tmpLine = self.combine2Line(tmpLine,secondLine, maxDistanse)
 
-                 if (isCombined):
 
-                     lines[sindex] = None
 
-             retLines.append(tmpLine)
 
-         return retLines
 
-     '''
 
-     判断两条线段是否在同一个线段上,是否可以组合成一条线段。
 
-     :param line1:[x1, y1, x2, y2],第一条线段,基础线段。
 
-     :param line2:[x1, y1, x2, y2],第二条线段,拿来对比合并的线段。
 
-     :return 1: bool,是否合并了两条线段。True代表已合并,False代表未合并。
 
-     :return 2:[x1, y1, x2, y2],最终得到的线段,True是已合并的线段,False则返回line1
 
-     '''
 
-     def combine2Line(self, line1, line2, maxDistance):
 
-         # print "combine2Line,line1,line2:",line1, line2
 
-         line1 = self.toOriginLine(line1)
 
-         line2 = self.toOriginLine(line2)
 
-         # 1 判断是不是同是竖线或者横线。纵向方向不同,返回False
 
-         direct1 = self.lineDirect(line1)
 
-         direct2 = self.lineDirect(line2)
 
-         if (direct1 <> direct2):
 
-             return False, line1
 
-         # 2 判断两条线段所在直线的平行距离。平行距离太远返回False
 
-         maxDistance = maxDistance
 
-         paralDistance = self.getParalDistance(line1, line2, direct1)
 
-         if (paralDistance > maxDistance):
 
-             return False, line1
 
-         # 3 判断两条线段纵向距离。在纵向上相离,相交,包含,相离太远返回False
 
-         maxInterval = maxDistance
 
-         status, interval, lineNear, lineFar = self.getLengthwaysDistance(line1, line2, direct1)
 
-         if ((status == 1) and (interval > maxInterval)) or (status == -1):
 
-             return False, line1
 
-         # 4 合并相离不远、相交和包含的线段
 
-         point1 = lineNear[0],lineNear[1]
 
-         point2 = self.getMaxPoint([lineNear[2], lineNear[3]],[lineFar[0], lineFar[1]],[lineFar[2], lineFar[3]])
 
-         retLine = [-1,-1,-1,-1]
 
-         if direct1 == 1:
 
-             retLine[0] = point1[0]
 
-             retLine[2] = point2[0]
 
-             retLine[1] = (point1[1] + point2[1])/2
 
-             retLine[3] = (point1[1] + point2[1])/2
 
-         else:
 
-             retLine[1] = point1[1]
 
-             retLine[3] = point2[1]
 
-             retLine[0] = (point1[0] + point2[0])/2
 
-             retLine[2] = (point1[0] + point2[0])/2
 
-         return True, retLine
 
-     '''
 
-     例如:[1002 ,134,1002 , 43] 调整为[1002,43,1002,134]
 
-     '''
 
-     def toOriginLine(self, line):
 
-         retLine = line
 
-         if (line[0] + line[1]) > (line[2]+line[3]):
 
-             retLine = [line[2] , line[3], line[0],line[1]]
 
-         return retLine
 
-     def getMaxPoint(self, *pointList):
 
-         # print "getMaxPoint:",pointList
 
-         maxPoint = [-1,-1]
 
-         for point in pointList:
 
-             if (maxPoint[0] + maxPoint[1]) < (point[0] + point[1]):
 
-                 maxPoint[0] = point[0]
 
-                 maxPoint[1] = point[1]
 
-         return maxPoint
 
-     def getMinPoint(self, *pointList):
 
-         # print "getMinPoint:",pointList
 
-         minPoint = [10000,10000]
 
-         for point in pointList:
 
-             if (minPoint[0] + minPoint[1]) > (point[0] + point[1]):
 
-                 minPoint[0] = point[0]
 
-                 minPoint[1] = point[1]
 
-         return minPoint
 
-     '''
 
-     找到所有线段中的最小坐标点和最大坐标点
 
-     '''
 
-     def getLineMMPoint(self, lineList):
 
-         minPoint = [10000,10000]
 
-         maxPoint = [-1,-1]
 
-         for line in lineList:
 
-             minPoint = self.getMinPoint(minPoint, (line[0],line[1]), (line[2],line[3]))
 
-             maxPoint = self.getMaxPoint(maxPoint, (line[0],line[1]), (line[2],line[3]))
 
-         return minPoint,maxPoint
 
-     '''
 
-     查看line是水平线段,还是竖直线段,或者其他斜线
 
-     :param line1:[x1, y1, x2, y2],线段1
 
-     :param line2:[x1, y1, x2, y2],线段2
 
-     :param direct:1 代表水平,2代表竖直
 
-     :return int:1 代表相离,2 代表相交,3 代表包含, -1 代表识别异常
 
-     :return int:相离的距离,-1或者相离实际距离
 
-     :return line1: 接近原点的线段
 
-     :return line2: 远离原点的线段
 
-     '''
 
-     def getLengthwaysDistance(self, line1, line2, direct):
 
-         status = -1
 
-         distance = -1
 
-         tallLine = line1
 
-         shortLine = line2
 
-         lineLen1 = self.caculateLinLen(line1)
 
-         lineLen2 = self.caculateLinLen(line2)
 
-         if (lineLen1 > lineLen2):
 
-             tallLine = line1
 
-             shortLine = line2
 
-         else:
 
-             tallLine = line2
 
-             shortLine = line1
 
-         if (direct == 1):
 
-             if (tallLine[1] < shortLine[1]) and (tallLine[3] < shortLine[1]):
 
-                 status = 1
 
-                 distance = shortLine[1] - tallLine[3]
 
-                 return status, distance, tallLine, shortLine
 
-             if (tallLine[1] < shortLine[1]) and (tallLine[3] >= shortLine[1]) and (tallLine[3] < shortLine[3]):
 
-                 status = 2
 
-                 distance = -1
 
-                 return status, distance, tallLine, shortLine
 
-             if (tallLine[1] <= shortLine[1]) and (tallLine[3] >= shortLine[3]):
 
-                 status = 3
 
-                 distance = -1
 
-                 return status, distance, tallLine, shortLine
 
-             if (tallLine[1] > shortLine[1]) and (tallLine[1] <= shortLine[3]) and (tallLine[3] > shortLine[3]):
 
-                 status = 2
 
-                 distance = -1
 
-                 return status, distance, shortLine, tallLine
 
-             if (tallLine[1] > shortLine[3]) and (tallLine[3] > shortLine[3]):
 
-                 status = 1
 
-                 distance = tallLine[1] - shortLine[3]
 
-                 return status, distance, shortLine, tallLine
 
-         if (direct == 2):
 
-             if (tallLine[0] < shortLine[0]) and (tallLine[2] < shortLine[0]):
 
-                 status = 1
 
-                 distance = shortLine[0] - tallLine[2]
 
-                 return status, distance, tallLine, shortLine
 
-             if (tallLine[0] < shortLine[0]) and (tallLine[2] >= shortLine[0]) and (tallLine[2] < shortLine[2]):
 
-                 status = 2
 
-                 distance = -1
 
-                 return status, distance, tallLine, shortLine
 
-             if (tallLine[0] <= shortLine[0]) and (tallLine[2] >= shortLine[2]):
 
-                 status = 3
 
-                 distance = -1
 
-                 return status, distance, tallLine, shortLine
 
-             if (tallLine[0] > shortLine[0]) and (tallLine[0] <= shortLine[2]) and (tallLine[2] > shortLine[2]):
 
-                 status = 2
 
-                 distance = -1
 
-                 return status, distance, shortLine, tallLine
 
-             if (tallLine[0] > shortLine[2]) and (tallLine[2] > shortLine[2]):
 
-                 status = 1
 
-                 distance = tallLine[0] - shortLine[2]
 
-                 return status, distance, shortLine, tallLine
 
-         return status, distance, shortLine, tallLine
 
-     '''
 
-     查看line是水平线段,还是竖直线段,或者其他斜线
 
-     :param line1:[x1, y1, x2, y2],线段1
 
-     :param line2:[x1, y1, x2, y2],线段2
 
-     :param direct:1 代表水平,2代表竖直
 
-     :return int:1 代表水平,2代表竖直,0代表其他斜线
 
-     '''
 
-     def getParalDistance(self, line1, line2, direct):
 
-         if direct == 1:
 
-             return abs(line1[1] - line2[1])
 
-         if direct == 2:
 
-             return abs(line1[0] - line2[0])
 
-     '''
 
-     查看line是水平线段,还是竖直线段,或者其他斜线
 
-     :param line:[x1, y1, x2, y2],线段
 
-     :return bool:1 代表水平,2代表竖直,0代表其他斜线
 
-     '''
 
-     def lineDirect(self, line):
 
-         if (line[0] == line[2]):
 
-             return 2
 
-         elif (line[1] == line[3]):
 
-             return 1
 
-         else:
 
-             return 0
 
-     def caculateLinLen(self, line):
 
-         dx = abs(line[0] - line[2])
 
-         dy = abs(line[1] - line[3])
 
-         # print "caculateLinLen:",dx,dy
 
-         lineLen = np.sqrt(np.square(dx) + np.square(dy))
 
-         return lineLen
 
 
  |