All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.tsystems.mms.tic.testframework.layout.matching.GraphBasedTemplateMatcher Maven / Gradle / Ivy

/*
 * Testerra
 *
 * (C) 2020, René Habermann, T-Systems Multimedia Solutions GmbH, Deutsche Telekom AG
 *
 * Deutsche Telekom AG and all other contributors /
 * copyright owners license this file to you under the Apache
 * License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */
package eu.tsystems.mms.tic.testframework.layout.matching;

import eu.tsystems.mms.tic.testframework.common.PropertyManager;
import eu.tsystems.mms.tic.testframework.constants.TesterraProperties;
import eu.tsystems.mms.tic.testframework.layout.DefaultParameter;
import eu.tsystems.mms.tic.testframework.layout.core.LayoutElement;
import eu.tsystems.mms.tic.testframework.layout.core.ValuedPoint2D;
import eu.tsystems.mms.tic.testframework.layout.matching.graph.DistanceGraph;
import eu.tsystems.mms.tic.testframework.layout.matching.matchers.TemplateMatchingAlgorithm;
import org.opencv.core.Mat;

import java.util.LinkedList;
import java.util.List;

/**
 * User: rnhb
 * Date: 11.06.14
 */
public class GraphBasedTemplateMatcher extends TemplateMatcher {

    private double minimalDistanceBetweenMatches = PropertyManager.getIntProperty(
            TesterraProperties.LAYOUTCHECK_MIN_MATCH_DISTANCE,
            DefaultParameter.LAYOUTCHECK_MIN_MATCH_DISTANCE);

    private final TemplateMatchingAlgorithm templateMatchingAlgorithm;

    public GraphBasedTemplateMatcher(TemplateMatchingAlgorithm templateMatchingAlgorithm) {
        this.templateMatchingAlgorithm = templateMatchingAlgorithm;
    }

    /**
     * After detecting all template elements, find all matches for them and construct a distance graph from that.
     *
     * @param imageToMatch   Image to match in.
     * @param layoutElements Template Elements.
     * @return DistanceGraph
     */
    @Override
    public DistanceGraph matchTemplates(Mat imageToMatch, List layoutElements) {
        DistanceGraph distanceGraph = generateInitialDistanceGraph(layoutElements);
        for (LayoutElement layoutElement : layoutElements) {
            List matchingPoints = templateMatchingAlgorithm.findMatchingPoints(layoutElement, imageToMatch);
            List isolatedPoints = cleanGroupedPoints(matchingPoints);
            for (ValuedPoint2D isolatedPoint : isolatedPoints) {
                distanceGraph.createMatchNode(layoutElement, isolatedPoint);
            }
        }
        distanceGraph.combineMatchNodes();
        distanceGraph.connectMatchNodes();
        distanceGraph.checkForParameterWarnings();
        if (referenceImageIsSubImage) {
            distanceGraph.incorporateSubImageDisplacement();
        }
        distanceGraph.printFullReport();
        return distanceGraph;
    }

    /**
     * Sometimes matches are found on the same object at different pixels, for example two matches 1 pixel apart from each other,
     * because both scored very high. We need to detect such cases and regard it as a single match.
     *
     * @param matchedPoints Points where a match is found.
     * @return List of locations of actually matched object.
     */
    private List cleanGroupedPoints(List matchedPoints) {
        if (matchedPoints.size() == 1) {
            return matchedPoints;
        }

        List isolatedPoints = new LinkedList<>();
        while (!matchedPoints.isEmpty()) {
            float x = 0;
            float y = 0;
            float value = 0;
            float count = 0;
            List pointsInArea = getPointsInArea(matchedPoints, minimalDistanceBetweenMatches);
            for (ValuedPoint2D point : pointsInArea) {
                matchedPoints.remove(point);
                x += point.x;
                y += point.y;
                value += point.value;
                count++;
            }
            isolatedPoints.add(new ValuedPoint2D(Math.round(x / count), Math.round(y / count), value / count));
        }
        return isolatedPoints;
    }

    /**
     * Returns all Points in an area defined by 'MINIMAL_DISTANCE_BETWEEN_MATCHES', so we can summarize them into one point.
     *
     * @param allPoints List of all points where this method should look for areas of near points.
     * @return The first area that is found.
     */
    private List getPointsInArea(List allPoints, double maximalDistance) {
        ValuedPoint2D basePoint;
        if (allPoints.isEmpty())
            return new LinkedList<>();
        else basePoint = allPoints.get(0);

        List pointsInArea = new LinkedList<>();
        pointsInArea.add(basePoint);
        for (ValuedPoint2D point : allPoints) {
            if (point != basePoint) {
                boolean pointIsNear = false;
                for (ValuedPoint2D potentialNearPoint : pointsInArea) {
                    if (point.getEuclideanDistance(potentialNearPoint) < maximalDistance) {
                        pointIsNear = true;
                        break;
                    }
                }
                if (pointIsNear) {
                    pointsInArea.add(point);
                }
            }
        }
        return pointsInArea;
    }


    /**
     * Generates a Distance Graph with all template nodes in it.
     *
     * @param layoutElements Templates
     * @return DistanceGraph
     */
    private DistanceGraph generateInitialDistanceGraph(List layoutElements) {
        DistanceGraph distanceGraph = new DistanceGraph();
        for (LayoutElement layoutElement : layoutElements) {
            distanceGraph.createTemplateNode(layoutElement);
        }
        return distanceGraph;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy