Search in sources :

Example 1 with ScoreElement

use of org.vitrivr.cineast.core.data.score.ScoreElement in project cineast by vitrivr.

the class SpatialDistance method getSimilar.

/**
 * Returns similar <i>objects</i> to the feature data contained in the given segment container.
 */
@Override
public List<ScoreElement> getSimilar(SegmentContainer sc, ReadableQueryConfig qc) {
    final QueryConfig mqc = QueryConfig.clone(qc);
    if (sc instanceof ParameterisedLocationQueryTermContainer) {
        if (((ParameterisedLocationQueryTermContainer) sc).getParameter().isPresent()) {
            final String param = ((ParameterisedLocationQueryTermContainer) sc).getParameter().get();
            mqc.setCorrespondenceFunctionIfEmpty(CorrespondenceFunction.hyperbolic(parseAndEvaluateHalfSimilarityDistance(param)));
        }
    }
    return this.extractFeature(sc).map(ReadableFloatVector::toArray).map(array -> this.getSimilar(array, new ReadableQueryConfig(mqc))).orElse(Collections.emptyList());
}
Also used : ParameterisedLocationQueryTermContainer(org.vitrivr.cineast.core.data.query.containers.ParameterisedLocationQueryTermContainer) MetadataFeatureModule(org.vitrivr.cineast.core.features.abstracts.MetadataFeatureModule) CorrespondenceFunction(org.vitrivr.cineast.core.data.CorrespondenceFunction) ReadableFloatVector(org.vitrivr.cineast.core.data.ReadableFloatVector) QueryConfig(org.vitrivr.cineast.core.config.QueryConfig) ScoreElement(org.vitrivr.cineast.core.data.score.ScoreElement) MediaObjectMetadataDescriptor(org.vitrivr.cineast.core.data.entities.MediaObjectMetadataDescriptor) ReadableQueryConfig(org.vitrivr.cineast.core.config.ReadableQueryConfig) DoubleEvaluator(com.fathzer.soft.javaluator.DoubleEvaluator) LinkedHashMap(java.util.LinkedHashMap) GpsData(org.vitrivr.cineast.core.data.GpsData) List(java.util.List) Logger(org.apache.logging.log4j.Logger) ImmutableList(com.google.common.collect.ImmutableList) SegmentContainer(org.vitrivr.cineast.core.data.segments.SegmentContainer) Optional(java.util.Optional) Distance(org.vitrivr.cineast.core.config.ReadableQueryConfig.Distance) Path(java.nio.file.Path) Collections(java.util.Collections) LogManager(org.apache.logging.log4j.LogManager) Location(org.vitrivr.cineast.core.data.Location) ReadableQueryConfig(org.vitrivr.cineast.core.config.ReadableQueryConfig) QueryConfig(org.vitrivr.cineast.core.config.QueryConfig) ReadableQueryConfig(org.vitrivr.cineast.core.config.ReadableQueryConfig) ParameterisedLocationQueryTermContainer(org.vitrivr.cineast.core.data.query.containers.ParameterisedLocationQueryTermContainer) ReadableFloatVector(org.vitrivr.cineast.core.data.ReadableFloatVector)

Example 2 with ScoreElement

use of org.vitrivr.cineast.core.data.score.ScoreElement in project cineast by vitrivr.

the class MFCCShingle method postprocessQuery.

/**
 * This method represents the last step that's executed when processing a query. A list of partial-results (DistanceElements) returned by the lookup stage is processed based on some internal method and finally converted to a list of ScoreElements. The filtered list of ScoreElements is returned by the feature module during retrieval.
 *
 * @param partialResults List of partial results returned by the lookup stage.
 * @param qc             A ReadableQueryConfig object that contains query-related configuration parameters.
 * @return List of final results. Is supposed to be de-duplicated and the number of items should not exceed the number of items per module.
 */
@Override
protected List<ScoreElement> postprocessQuery(List<SegmentDistanceElement> partialResults, ReadableQueryConfig qc) {
    /* Prepare helper data-structures. */
    final List<ScoreElement> results = new ArrayList<>();
    final TObjectIntHashMap<String> scoreMap = new TObjectIntHashMap<>();
    /* Set QueryConfig and extract correspondence function. */
    qc = this.setQueryConfig(qc);
    final CorrespondenceFunction correspondence = qc.getCorrespondenceFunction().orElse(this.correspondence);
    for (DistanceElement hit : partialResults) {
        if (hit.getDistance() < this.distanceThreshold) {
            scoreMap.adjustOrPutValue(hit.getId(), 1, scoreMap.get(hit.getId()) / 2);
        }
    }
    /* Prepare final result-set. */
    scoreMap.forEachEntry((key, value) -> results.add(new SegmentScoreElement(key, 1.0 - 1.0 / value)));
    ScoreElement.filterMaximumScores(results.stream());
    return results;
}
Also used : SegmentScoreElement(org.vitrivr.cineast.core.data.score.SegmentScoreElement) TObjectIntHashMap(gnu.trove.map.hash.TObjectIntHashMap) ScoreElement(org.vitrivr.cineast.core.data.score.ScoreElement) SegmentScoreElement(org.vitrivr.cineast.core.data.score.SegmentScoreElement) ArrayList(java.util.ArrayList) CorrespondenceFunction(org.vitrivr.cineast.core.data.CorrespondenceFunction) SegmentDistanceElement(org.vitrivr.cineast.core.data.distance.SegmentDistanceElement) DistanceElement(org.vitrivr.cineast.core.data.distance.DistanceElement)

Example 3 with ScoreElement

use of org.vitrivr.cineast.core.data.score.ScoreElement in project cineast by vitrivr.

the class ContinuousQueryDispatcher method addRetrievalResult.

private void addRetrievalResult(TObjectDoubleMap<String> scoreByObjectId, TObjectDoubleMap<String> scoreBySegmentId, RetrievalTask task, List<ScoreElement> scoreElements) {
    if (scoreElements == null) {
        LOGGER.warn("Retrieval task {} returned 'null' results.", task);
        return;
    }
    for (RetrievalResultListener listener : resultListeners) {
        listener.notify(scoreElements, task);
    }
    double retrieverWeight = this.retrieverWeights.get(task.getRetriever());
    for (ScoreElement element : scoreElements) {
        TObjectDoubleMap<String> scoreById;
        if (element instanceof ObjectScoreElement) {
            scoreById = scoreByObjectId;
        } else if (element instanceof SegmentScoreElement) {
            scoreById = scoreBySegmentId;
        } else if (element instanceof BooleanSegmentScoreElement) {
            // TODO: Cleanup?
            scoreById = scoreBySegmentId;
        } else {
            LOGGER.error("Unknown subclass {} of ScoreElement in ContinuousQueryDispatcher.addRetrievalResult.", element.getClass().getSimpleName());
            continue;
        }
        this.addScoreElement(scoreById, element, retrieverWeight);
    }
}
Also used : SegmentScoreElement(org.vitrivr.cineast.core.data.score.SegmentScoreElement) BooleanSegmentScoreElement(org.vitrivr.cineast.core.data.score.BooleanSegmentScoreElement) ScoreElement(org.vitrivr.cineast.core.data.score.ScoreElement) ObjectScoreElement(org.vitrivr.cineast.core.data.score.ObjectScoreElement) SegmentScoreElement(org.vitrivr.cineast.core.data.score.SegmentScoreElement) BooleanSegmentScoreElement(org.vitrivr.cineast.core.data.score.BooleanSegmentScoreElement) RetrievalResultListener(org.vitrivr.cineast.standalone.listener.RetrievalResultListener) BooleanSegmentScoreElement(org.vitrivr.cineast.core.data.score.BooleanSegmentScoreElement) ObjectScoreElement(org.vitrivr.cineast.core.data.score.ObjectScoreElement)

Example 4 with ScoreElement

use of org.vitrivr.cineast.core.data.score.ScoreElement in project cineast by vitrivr.

the class RetrievalResultCSVExporter method notify.

@Override
public void notify(List<ScoreElement> resultList, RetrievalTask task) {
    ReadableQueryConfig qc = task.getConfig();
    String queryIdString;
    if (qc == null || qc.getQueryId() == null) {
        LOGGER.error("could not determine query id, using 'null'");
        queryIdString = "null";
    } else {
        queryIdString = qc.getQueryId().toString();
    }
    String filename = task.getRetriever().getClass().getSimpleName() + ".csv";
    File outFolder = new File(baseFolder, queryIdString);
    outFolder.mkdirs();
    File out = new File(outFolder, filename);
    ArrayList<String> ids = new ArrayList<>(resultList.size());
    for (ScoreElement e : resultList) {
        ids.add(e.getId());
    }
    Map<String, MediaSegmentDescriptor> segments = mediaSegmentReader.lookUpSegments(ids);
    Set<String> objectIds = new HashSet<>();
    for (MediaSegmentDescriptor sd : segments.values()) {
        objectIds.add(sd.getObjectId());
    }
    Map<String, MediaObjectDescriptor> objects = mediaObjectReader.lookUpObjects(objectIds);
    try (PrintWriter writer = new PrintWriter(out)) {
        // header
        writer.println("\"rank\", \"id\", \"score\", \"path\"");
        int rank = 1;
        for (ScoreElement e : resultList) {
            writer.print(rank++);
            writer.print(',');
            writer.print(e.getId());
            writer.print(',');
            writer.print(e.getScore());
            writer.print(',');
            writer.print('"');
            writer.print(objects.get(segments.get(e.getId()).getObjectId()).getPath().replace('\\', '/'));
            writer.println('"');
        }
        writer.flush();
    } catch (FileNotFoundException e) {
        LOGGER.error("could not write file '{}': {}", out.getAbsolutePath(), LogHelper.getStackTrace(e));
    }
}
Also used : MediaObjectDescriptor(org.vitrivr.cineast.core.data.entities.MediaObjectDescriptor) ScoreElement(org.vitrivr.cineast.core.data.score.ScoreElement) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) ReadableQueryConfig(org.vitrivr.cineast.core.config.ReadableQueryConfig) MediaSegmentDescriptor(org.vitrivr.cineast.core.data.entities.MediaSegmentDescriptor) File(java.io.File) HashSet(java.util.HashSet) PrintWriter(java.io.PrintWriter)

Example 5 with ScoreElement

use of org.vitrivr.cineast.core.data.score.ScoreElement in project cineast by vitrivr.

the class SegmentTags method getSimilar.

private List<ScoreElement> getSimilar(Iterable<WeightedTag> tags, ReadableQueryConfig qc) {
    ArrayList<String> tagids = new ArrayList<>();
    TObjectFloatHashMap<String> tagWeights = new TObjectFloatHashMap<>();
    float weightSum = 0f;
    /* Sum weights for normalization at a later point*/
    for (WeightedTag wt : tags) {
        tagids.add(wt.getId());
        tagWeights.put(wt.getId(), wt.getWeight());
        if (wt.getWeight() > 1) {
            LOGGER.error("Weight is > 1 -- this makes little sense.");
        }
        weightSum += Math.min(1, wt.getWeight());
    }
    if (tagids.isEmpty() || weightSum <= 0f) {
        return Collections.emptyList();
    }
    /* Retrieve all elements matching the provided ids */
    List<Map<String, PrimitiveTypeProvider>> rows = this.selector.getRows("tagid", tagids.stream().map(StringTypeProvider::new).collect(Collectors.toList()));
    Map<String, TObjectFloatHashMap<String>> maxScoreByTag = new HashMap<>();
    /* Prepare the set of relevant ids (if this entity is used for filtering at a later stage) */
    Set<String> relevant = null;
    if (qc != null && qc.hasRelevantSegmentIds()) {
        relevant = qc.getRelevantSegmentIds();
    }
    /* Iterate over all matches */
    for (Map<String, PrimitiveTypeProvider> row : rows) {
        String segmentId = row.get("id").getString();
        /* Skip segments which are not desired by the query-config */
        if (relevant != null && !relevant.contains(segmentId)) {
            continue;
        }
        String tagid = row.get("tagid").getString();
        float score = row.get("score").getFloat() * (tagWeights.containsKey(tagid) ? tagWeights.get(tagid) : 0f);
        if (score > 1) {
            LOGGER.warn("Score is larger than 1 - this makes little sense");
            score = 1f;
        }
        /* Update maximum score by tag*/
        maxScoreByTag.putIfAbsent(segmentId, new TObjectFloatHashMap<>());
        float prev = maxScoreByTag.get(segmentId).get(tagid);
        if (prev == Constants.DEFAULT_FLOAT_NO_ENTRY_VALUE) {
            maxScoreByTag.get(segmentId).put(tagid, score);
        } else {
            maxScoreByTag.get(segmentId).put(tagid, Math.max(score, prev));
        }
    }
    ArrayList<ScoreElement> _return = new ArrayList<>();
    final float normalizer = weightSum;
    /* per segment, the max score for all tags is summed and divided by the normalizer */
    maxScoreByTag.forEach((segmentId, tagScores) -> _return.add(new SegmentScoreElement(segmentId, MathHelper.sum(tagScores.values()) / normalizer)));
    return _return;
}
Also used : StringTypeProvider(org.vitrivr.cineast.core.data.providers.primitive.StringTypeProvider) TObjectFloatHashMap(gnu.trove.map.hash.TObjectFloatHashMap) HashMap(java.util.HashMap) ScoreElement(org.vitrivr.cineast.core.data.score.ScoreElement) SegmentScoreElement(org.vitrivr.cineast.core.data.score.SegmentScoreElement) ArrayList(java.util.ArrayList) TObjectFloatHashMap(gnu.trove.map.hash.TObjectFloatHashMap) SegmentScoreElement(org.vitrivr.cineast.core.data.score.SegmentScoreElement) WeightedTag(org.vitrivr.cineast.core.data.tag.WeightedTag) TObjectFloatHashMap(gnu.trove.map.hash.TObjectFloatHashMap) HashMap(java.util.HashMap) Map(java.util.Map) PrimitiveTypeProvider(org.vitrivr.cineast.core.data.providers.primitive.PrimitiveTypeProvider)

Aggregations

ScoreElement (org.vitrivr.cineast.core.data.score.ScoreElement)11 ArrayList (java.util.ArrayList)9 ReadableQueryConfig (org.vitrivr.cineast.core.config.ReadableQueryConfig)7 CorrespondenceFunction (org.vitrivr.cineast.core.data.CorrespondenceFunction)7 HashMap (java.util.HashMap)6 DistanceElement (org.vitrivr.cineast.core.data.distance.DistanceElement)6 SegmentDistanceElement (org.vitrivr.cineast.core.data.distance.SegmentDistanceElement)6 List (java.util.List)5 QueryConfig (org.vitrivr.cineast.core.config.QueryConfig)5 SegmentContainer (org.vitrivr.cineast.core.data.segments.SegmentContainer)5 FloatVectorImpl (org.vitrivr.cineast.core.data.FloatVectorImpl)4 SegmentScoreElement (org.vitrivr.cineast.core.data.score.SegmentScoreElement)4 StagedFeatureModule (org.vitrivr.cineast.core.features.abstracts.StagedFeatureModule)4 Pair (org.vitrivr.cineast.core.data.Pair)3 HPCP (org.vitrivr.cineast.core.util.audio.HPCP)3 FFTUtil (org.vitrivr.cineast.core.util.dsp.fft.FFTUtil)3 STFT (org.vitrivr.cineast.core.util.dsp.fft.STFT)3 HanningWindow (org.vitrivr.cineast.core.util.dsp.fft.windows.HanningWindow)3 MathHelper (org.vitrivr.cineast.core.util.math.MathHelper)3 Map (java.util.Map)2