def getReferenceVector(points): points = sortRectPoints(points) lowestPointVal = points[0][1] lowestPointIndex = 0 for i in range(len(points)): if (points[i][1] > lowestPointVal): lowestPointVal = points[i][1] lowestPointIndex = i points = np.concatenate( (points[lowestPointIndex:], points[:lowestPointIndex])) # vector a a = [points[1][0] - points[0][0], points[0][1] - points[1][1]] width = getLength(a) # vector b b = [points[2][0] - points[1][0], points[1][1] - points[2][1]] height = getLength(b) # vector d d = [points[3][0] - points[0][0], points[0][1] - points[3][1]] d = norm(d) angle = np.degrees(getAngle(horizontal, d)) if (width > height): angle = 270 + angle return [np.cos(np.radians(angle)), np.sin(np.radians(angle))]
def __init__(self, pathToObjPts): self.objPts = json.loads(open(pathToObjPts, 'r').readline())['points'] self.polarPts = np.zeros((len(self.objPts), 2), dtype=np.float32) for i in range(len(self.objPts)): vector = [self.objPts[i][0], self.objPts[i][1]] length = getLength(vector) angle = getAngle([1, 0], norm(vector), False) self.polarPts[i][0] = length self.polarPts[i][1] = angle
def sortImgPts(imgpts, x, midpt): numOfPoints = len(imgpts) pts = {} for i in range(numOfPoints): vector = norm([imgpts[i][0][0] - midpt[0], midpt[1] - imgpts[i][0][1]]) angle = getAngle(x, vector, False) pts[angle] = imgpts[i] pts = collections.OrderedDict(sorted(pts.items())) sortedPts = np.zeros((numOfPoints, 1, 2), dtype=np.int32) j = 0 for i in pts: sortedPts[j] = pts[i] j += 1 return sortedPts
def __init__(self, contours, frameCenter, useConvexHull, numOfCorners): # Save the contours that comprise the group self.contours = contours # Combine the points from the contours self.vertices = ContourGroup.combinePoints(contours) # Find the convex hull of the contour group self.useConvexHull = useConvexHull self.convexHull = cv.convexHull(self.vertices) # Apply k-means if there are duplicates criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0) if useConvexHull: if (len(self.convexHull) > numOfCorners) and (numOfCorners is not 0): self.convexHull = cv.kmeans( self.convexHull.astype(dtype=np.float32), numOfCorners, None, criteria, 10, cv.KMEANS_RANDOM_CENTERS)[2] self.convexHull = self.convexHull.reshape( (numOfCorners, 1, 2)).astype(dtype=np.int32) else: if (len(self.vertices) > numOfCorners) and (numOfCorners is not 0): self.vertices = cv.kmeans( self.vertices.astype(dtype=np.float32), numOfCorners, None, criteria, 10, cv.KMEANS_RANDOM_CENTERS)[2] self.vertices = self.vertices.reshape( (numOfCorners, 1, 2)).astype(dtype=np.int32) # Find the area of the contour self.area = ContourGroup.combineArea(contours) # Obtain the straight bounding box self.boundingBoxPoints, self.boundingBoxArea, self.boundingBoxAspectRatio = getBoundingBoxPoints( self.vertices) x, y, self.boundingBoxWidth, self.boundingBoxHeight = cv.boundingRect( self.vertices) self.boundingBoxUpperLeftPoint = (x, y) self.boundingBoxLowerRightPoint = (x + self.boundingBoxWidth, y + self.boundingBoxHeight) self.boundingBoxPoints = [ self.boundingBoxUpperLeftPoint, [x + self.boundingBoxWidth, y], self.boundingBoxLowerRightPoint, [x, y + self.boundingBoxHeight] ] # Find the rotated rect and it's area rect = cv.minAreaRect(self.vertices) _, (width, height), _ = rect if (width < height): self.tshort = width self.tlong = height else: self.tshort = height self.tlong = width box = np.int0(cv.boxPoints(rect)) self.rotatedRect = [box] self.rotatedRectArea = cv.contourArea(box) # Get the center of the group self.midpoint = tuple( np.average(self.vertices, axis=0).ravel().astype(int)) # Find the direction vector using the rotated rect and create a Line instance of it self.directionVector = getReferenceVector(box) self.rotation = getAngle(horizontal, self.directionVector) self.referenceVector = Line(self.directionVector, self.midpoint) self.contourLine = Line( self.directionVector, [self.midpoint[0], frameCenter[1] * 2 - self.midpoint[1]]) # Finally, sort the image points self.vertices = sortImgPts(self.vertices, self.directionVector, self.midpoint) # Get the distance to the center of the frame self.distanceToCenter = np.linalg.norm( np.array([ self.midpoint[0] - frameCenter[0], frameCenter[1] - self.midpoint[1] ]))
def __init__(self, contourPoints, frameCenter, useConvexHull, numOfCorners): # First process the contour points self.points = contourPoints # Find the area of the contour self.area = cv.contourArea(self.points) # Obtain the straight bounding box self.boundingBoxPoints, self.boundingBoxArea, self.boundingBoxAspectRatio = getBoundingBoxPoints( self.points) x, y, self.boundingBoxWidth, self.boundingBoxHeight = cv.boundingRect( self.points) self.boundingBoxArea = self.boundingBoxHeight * self.boundingBoxWidth self.boundingBoxAspectRatio = self.boundingBoxWidth / self.boundingBoxHeight self.boundingBoxUpperLeftPoint = (x, y) self.boundingBoxLowerRightPoint = (x + self.boundingBoxWidth, y + self.boundingBoxHeight) # Find the rotated rect and it's area rect = cv.minAreaRect(self.points) _, (width, height), _ = rect if (width < height): self.tshort = width self.tlong = height else: self.tshort = height self.tlong = width box = np.int0(cv.boxPoints(rect)) self.rotatedRect = [box] self.rotatedRectArea = cv.contourArea(box) # Compute the verticies of the contour self.vertices = cv.approxPolyDP( self.points, 0.015 * cv.arcLength(self.points, True), True) # Apply k-means if there are duplicates criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0) if (len(self.vertices) > numOfCorners) and (numOfCorners is not 0): self.vertices = cv.kmeans(self.vertices.astype(dtype=np.float32), numOfCorners, None, criteria, 10, cv.KMEANS_RANDOM_CENTERS)[2] self.vertices = self.vertices.reshape( (numOfCorners, 1, 2)).astype(dtype=np.int32) # Find the convex hull of the contour self.useConvexHull = useConvexHull self.convexHull = cv.convexHull(self.vertices) # Find the midpoint of the contour self.midpoint = getMidPoint(self.points) # Find the direction vector using the rotated rect and create a Line instance of it self.directionVector = getReferenceVector(box) self.rotation = getAngle(horizontal, self.directionVector, True) self.referenceVector = Line(self.directionVector, self.midpoint) self.contourLine = Line( self.directionVector, [self.midpoint[0], frameCenter[1] * 2 - self.midpoint[1]]) # Finally, sort the vertices if self.useConvexHull: self.vertices = sortImgPts(self.convexHull, self.directionVector, self.midpoint).astype(dtype=np.int32) else: self.vertices = sortImgPts(self.vertices, self.directionVector, self.midpoint).astype(dtype=np.int32) # Get the distance to the center of the frame (used for sorting) self.distanceToCenter = np.linalg.norm( np.array([ self.midpoint[0] - frameCenter[0], frameCenter[1] - self.midpoint[1] ]))