Exemplo n.º 1
0
    def getCropSize(self, areaCorners, targetSize):
        leftEdge = linefinder.LineSegment(round(areaCorners[3][0]),
                                          round(areaCorners[3][1]),
                                          round(areaCorners[0][0]),
                                          round(areaCorners[0][1]))
        rightEdge = linefinder.LineSegment(round(areaCorners[2][0]),
                                           round(areaCorners[2][1]),
                                           round(areaCorners[1][0]),
                                           round(areaCorners[1][1]))
        topEdge = linefinder.LineSegment(round(areaCorners[0][0]),
                                         round(areaCorners[0][1]),
                                         round(areaCorners[1][0]),
                                         round(areaCorners[1][1]))
        bottomEdge = linefinder.LineSegment(round(areaCorners[3][0]),
                                            round(areaCorners[3][1]),
                                            round(areaCorners[2][0]),
                                            round(areaCorners[2][1]))
        w = linefinder.distanceBetweenPoints(leftEdge.midpoint(),
                                             rightEdge.midpoint())
        h = linefinder.distanceBetweenPoints(bottomEdge.midpoint(),
                                             topEdge.midpoint())

        if w <= 0 or h <= 0:
            return (0, 0)
        aspect = float(w) / h
        width = targetSize[0]
        height = round(float(width) / aspect)
        if height > targetSize[1]:
            height = targetSize[1]
            width = round(float(height) * aspect)
        return (int(width), int(height))
Exemplo n.º 2
0
def filterBetweenLines(img, textContours, textLines):
    min_area_percent_within_lines = 0.88
    max_distance_percent_from_lines = 0.15
    if len(textLines) == 0:
        return
    validPoints = []
    rows, cols = img.shape
    outerMask = np.zeros((rows, cols), np.uint8)
    for i in range(0, len(textLines)):

        lp = np.array(textLines[i].linePolygon, np.int32)

        outerMask = cv2.fillConvexPoly(outerMask, lp, (255, 255, 255))
    for i in range(0, textContours.size()):
        if textContours.goodIndices[i] == False:
            continue
        percentInsideMask = getContourAreaPercentInsideMask(
            outerMask, textContours.contours, textContours.hierarchy, i)

        if percentInsideMask < min_area_percent_within_lines:
            textContours.goodIndices[i] = False
            continue
        x, y, w, h = cv2.boundingRect(textContours.contours[i])
        xmiddle = int(x + (w / 2))
        topMiddle = (xmiddle, y)
        botMiddle = (xmiddle, y + h)

        for j in range(0, len(textLines)):
            closetTopPoint = textLines[j].topLine.closestPointOnSegmentTo(
                topMiddle)
            closetBottomPoint = textLines[
                j].bottomLine.closestPointOnSegmentTo(botMiddle)
            absTopDistance = linefinder.distanceBetweenPoints(
                closetTopPoint, topMiddle)
            absBottomDistance = linefinder.distanceBetweenPoints(
                closetBottomPoint, botMiddle)
            maxDistance = textLines[
                j].lineHeight * max_distance_percent_from_lines
            if absTopDistance < maxDistance and absBottomDistance < maxDistance:
                a = 0
            else:
                textContours.goodIndices[j] = False
    return textContours
Exemplo n.º 3
0
    def initialize(self, textArea, linePolygon, width, height):
        if len(textArea) > 0:
            if (len(self.textArea) > 0):
                self.textArea = []
            if (len(self.linePolygon) > 0):
                self.linePolygon = []

        for i in range(0, len(textArea)):
            self.textArea.append(textArea[i])
        self.topLine = linefinder.LineSegment(linePolygon[0][0],
                                              linePolygon[0][1],
                                              linePolygon[1][0],
                                              linePolygon[1][1])
        self.bottomLine = linefinder.LineSegment(linePolygon[3][0],
                                                 linePolygon[3][1],
                                                 linePolygon[2][0],
                                                 linePolygon[2][1])
        if linePolygon[0][0] != 0:
            linePolygon[0] = (0, self.topLine.getPointAt(linePolygon[0][0]))
        if linePolygon[1][0] != width:
            linePolygon[1] = (width,
                              self.topLine.getPointAt(linePolygon[1][0]))
        if linePolygon[2][0] != width:
            linePolygon[2] = (width,
                              self.bottomLine.getPointAt(linePolygon[2][0]))
        if linePolygon[3][0] != 0:
            linePolygon[3] = (0, self.bottomLine.getPointAt(linePolygon[3][0]))

        for i in range(0, len(linePolygon)):
            self.linePolygon.append(linePolygon[i])
        self.charBoxTop = linefinder.LineSegment(textArea[0][0],
                                                 textArea[0][1],
                                                 textArea[1][0],
                                                 textArea[1][1])
        self.charBoxBottom = linefinder.LineSegment(textArea[3][0],
                                                    textArea[3][1],
                                                    textArea[2][0],
                                                    textArea[2][1])
        self.charBoxLeft = linefinder.LineSegment(textArea[3][0],
                                                  textArea[3][1],
                                                  textArea[0][0],
                                                  textArea[0][1])
        self.charBoxRight = linefinder.LineSegment(textArea[2][0],
                                                   textArea[2][1],
                                                   textArea[1][0],
                                                   textArea[1][1])
        x = float(linePolygon[1][0]) / 2
        midpoint = (int(x), int(self.bottomLine.getPointAt(x)))
        acrossFromMidpoint = self.topLine.closestPointOnSegmentTo(midpoint)

        self.lineHeight = linefinder.distanceBetweenPoints(
            midpoint, acrossFromMidpoint)
        self.lineHeight = self.lineHeight - 1
        self.angle = (self.topLine.angle + self.bottomLine.angle) / 2
Exemplo n.º 4
0
    def highContrastDetection(self, newCrop, newLines):
        smallPlateCorners = []

        morph_size = 3
        closureElement = cv2.getStructuringElement(2, (2 * morph_size + 1, 2 * morph_size + 1), (morph_size, morph_size))
        newCrop = cv2.morphologyEx(newCrop, cv2.MORPH_CLOSE, closureElement)
        newCrop = cv2.morphologyEx(newCrop, cv2.MORPH_OPEN, closureElement)
        thresholded_crop = cv2.threshold(newCrop, 80, 255, cv2.THRESH_OTSU)
        _, contours, _ = cv2.findContours(thresholded_crop, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        rows, cols = newCrop.shape
        min_area = 0.05 * cols * rows
        for i in range(0, len(contours)):
            if(cv2.contourArea(contours) < min_area):
                continue
            smoothPoints = cv2.approxPolyDP(contours[i], 1, True)
            rrect = cv2.minAreaRect(smoothPoints)
            box = cv2.boxPoints(rrect)
            sorted_polygon_points = linefinder.sortPolygonPoints([box],(rows, cols))
            polygon_width = (linefinder.distanceBetweenPoints(sorted_polygon_points[0],
                                                             sorted_polygon_points[1]) +
                             linefinder.distanceBetweenPoints(sorted_polygon_points[3],
                                                              sorted_polygon_points[2])
                             ) / 2
            polygon_height = (linefinder.distanceBetweenPoints(sorted_polygon_points[1],
                                                              sorted_polygon_points[1]) +
                             linefinder.distanceBetweenPoints(sorted_polygon_points[3],
                                                              sorted_polygon_points[0])
                             ) / 2
            x_offset = cols * 0.1
            y_offset = rows * 0.1
            a = x_offset
            b = y_offset
            c = cols - x_offset
            d = rows - y_offset
            isoutside = False
            for ptidx in range(len(sorted_polygon_points)):
                x = sorted_polygon_points[ptidx][0]
                y = sorted_polygon_points[ptidx][0]
                if not ((x > c and x < a) and (y > d and y < b)):
                    isoutside = True
            if isoutside:
                continue
            max_closeness_to_edge_percent = 0.2
            if rrect.center[0] < (cols * max_closeness_to_edge_percent) or rrect.center[0] > (cols - (cols * max_closeness_to_edge_percent)) or rrect.center[1] < (rows * max_closeness_to_edge_percent) or rrect.center[1] > (rows - (rows * max_closeness_to_edge_percent)):
                continue
            aspect_ratio = float(polygon_width) / polygon_height
            ideal_aspect_ratio = 304.8 / 152.4
            ratio = ideal_aspect_ratio / aspect_ratio
            if ratio > 2 or ratio < 0.5:
                continue
            x, y, w, h = rrect.boundingRect()
            for linenum in range(0, len(newLines)):
                for r in range(0, len(newLines[linenum].textArea)):
                    a,b = newLines[linenum].textArea[r]
                    if not (( a > x and a < x+w) and (b > y and b < y + h)):
                        isoutside = True
            if isoutside:
                continue
            for ridx in range(0, 4):
                smallPlateCorners.append(sorted_polygon_points[ridx])

        return smallPlateCorners
Exemplo n.º 5
0
    def scoreVerticals(self, v1, v2):
        scoreKeeper = ScoreKeeper()
        left = LineSegment()
        right = LineSegment()
        charHeightToPlateWidthRatio = 304.8 / 70
        idealPixelWidth = self.tlc.charHeight * (charHeightToPlateWidthRatio *
                                                 1.03)
        confidenceDiff = 0
        missingSegmentPenalty = 0

        if v1 == -1 and v2 == -1:
            left = self.tlc.centerVerticalLine.getParalleLine(
                -1 * idealPixelWidth / 2.0)
            right = self.tlc.centerVerticalLine.getParalleLine(
                idealPixelWidth / 2.0)
            missingSegmentPenalty = 2
            confidenceDiff += 2

        elif v1 != -1 and v2 != -1:
            left = self.plateLines.verticalLines[v1].line
            right = self.plateLines.verticalLines[v2].line
            confidenceDiff += (1.0 -
                               self.plateLines.verticalLines[v1].confidence)
            confidenceDiff += (1.0 -
                               self.plateLines.verticalLines[v2].confidence)

        elif v1 == -1 and v2 != -1:
            right = self.plateLines.verticalLines[v2].line
            left = right.getParalleLine(idealPixelWidth)
            missingSegmentPenalty += 1
            confidenceDiff += (1.0 -
                               self.plateLines.verticalLines[v2].confidence)
        elif v1 != -1 and v2 == -1:
            left = self.plateLines.verticalLines[v1].line
            right = left.getParalleLine(-1 * idealPixelWidth)
            missingSegmentPenalty += 1
            confidenceDiff += (1.0 -
                               self.plateLines.verticalLines[v1].confidence)
        scoreKeeper.setScore("SCORING_LINE_CONFIDENCE_WEIGHT", confidenceDiff,
                             18.0)
        scoreKeeper.setScore("SCORING_MISSING_SEGMENT_PENALTY_VERTICAL",
                             missingSegmentPenalty, 10)
        if self.tlc.isLeftOfText(left) < 1 or self.tlc.isLeftOfText(
                right) > -1:
            return None
        perpendicularCharAngle = self.tlc.charAngle - 90
        charanglediff = abs(perpendicularCharAngle -
                            left.angle) + abs(perpendicularCharAngle -
                                              right.angle)
        scoreKeeper.setScore("SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT",
                             charanglediff, 1.1)
        leftMidLinePoint = left.closestPointOnSegmentTo(
            self.tlc.centerVerticalLine.midpoint())
        rightMidLinePoint = right.closestPointOnSegmentTo(
            self.tlc.centerHorizontalLine.midpoint())
        actual_width = distanceBetweenPoints(leftMidLinePoint,
                                             rightMidLinePoint)
        if actual_width < (idealPixelWidth / 4):
            return None
        plateDistance = abs(idealPixelWidth - actual_width)
        plateDistance = plateDistance / float(self.inputImage.shape[1])
        scoreKeeper.setScore("SCORING_DISTANCE_WEIGHT_VERTICAL", plateDistance,
                             4.0)
        score = scoreKeeper.getTotal()

        if score < self.bestVerticalScore:

            self.bestVerticalScore = score
            self.bestLeft = LineSegment(left.p1[0], left.p1[1], left.p2[0],
                                        left.p2[1])
            self.bestRight = LineSegment(right.p1[0], right.p1[1], right.p2[0],
                                         right.p2[1])
Exemplo n.º 6
0
    def scoreHorizontals(self, h1, h2):

        scoreKeeper = ScoreKeeper()
        top = LineSegment()
        bottom = LineSegment()

        extra_vertical_pixels = 3
        charHeightToPlateHeightRatio = 152.4 / 70
        idealPixelHeight = self.tlc.charHeight * charHeightToPlateHeightRatio

        missingSegmengtPenalty = 0
        if h1 == -1 and h2 == -1:
            top = self.tlc.centerHorizontalLine.getParalleLine(
                idealPixelHeight / 2)
            bottom = self.tlc.centerHorizontalLine.getParalleLine(
                -1 * idealPixelHeight / 2)
            missingSegmengtPenalty = 2
        elif h1 != -1 and h2 != -1:
            top = self.plateLines.horizontalLines[h1].line
            bottom = self.plateLines.horizontalLines[h2].line
        elif h1 == -1 and h2 != -1:
            bottom = self.plateLines.horizontalLines[h2].line
            top = bottom.getParalleLine(idealPixelHeight +
                                        extra_vertical_pixels)
            missingSegmengtPenalty += 1
        elif h1 != -1 and h2 == -1:
            top = self.plateLines.horizontalLines[h1].line
            bottom = top.getParalleLine(-1 * idealPixelHeight -
                                        extra_vertical_pixels)
            missingSegmengtPenalty += 1
        scoreKeeper.setScore("SCORING_MISSING_SEGMENT_PENALTY_HORIZONTAL",
                             missingSegmengtPenalty, 1)

        if self.tlc.isAboveText(top) < 1 or self.tlc.isAboveText(bottom) > -1:
            return None

        topPoint = top.midpoint()
        botPoint = bottom.closestPointOnSegmentTo(topPoint)
        plateHeightPx = distanceBetweenPoints(topPoint, botPoint)
        heightRatio = self.tlc.charHeight / float(plateHeightPx)
        idealHeightRatio = (70.0 / 152.4)

        heightRatioDiff = abs(heightRatio - idealHeightRatio)

        scoreKeeper.setScore("SCORING_PLATEHEIGHT_WEIGHT", heightRatioDiff,
                             2.2)

        charAreaMidPoint = self.tlc.centerHorizontalLine.midpoint()
        topLineSpot = top.closestPointOnSegmentTo(charAreaMidPoint)
        botLineSpot = bottom.closestPointOnSegmentTo(charAreaMidPoint)
        topDistanceFromMiddle = distanceBetweenPoints(topLineSpot,
                                                      charAreaMidPoint)
        bottomDistanceFromMiddle = distanceBetweenPoints(
            botLineSpot, charAreaMidPoint)
        idealDistanceFromMiddle = idealPixelHeight / 2.0

        middleScore = abs(topDistanceFromMiddle - idealDistanceFromMiddle
                          ) / float(idealDistanceFromMiddle)
        middleScore += abs(bottomDistanceFromMiddle -
                           idealDistanceFromMiddle) / idealDistanceFromMiddle

        scoreKeeper.setScore("SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT",
                             middleScore, 2.0)
        charanglediff = abs(self.tlc.charAngle -
                            top.angle) + abs(self.tlc.charAngle - bottom.angle)

        scoreKeeper.setScore("SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT",
                             charanglediff, 1.1)
        score = scoreKeeper.getTotal()

        if score < self.bestHorizontalScore:

            self.bestHorizontalScore = score
            self.bestTop = LineSegment(top.p1[0], top.p1[1], top.p2[0],
                                       top.p2[1])
            self.bestBottom = LineSegment(bottom.p1[0], bottom.p1[1],
                                          bottom.p2[0], bottom.p2[1])