use of org.vitrivr.cineast.core.data.segments.SegmentContainer 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());
}
use of org.vitrivr.cineast.core.data.segments.SegmentContainer in project cineast by vitrivr.
the class HPCPShingle method getFeatures.
/**
* Returns a list of feature vectors given a SegmentContainer.
*
* @param segment SegmentContainer for which to calculate the feature vectors.
* @return List of HPCP Shingle feature vectors.
*/
private List<float[]> getFeatures(SegmentContainer segment) {
/* Create STFT; If this fails, return empty list. */
Pair<Integer, Integer> parameters = FFTUtil.parametersForDuration(segment.getSamplingrate(), WINDOW_SIZE);
STFT stft = segment.getSTFT(parameters.first, (parameters.first - 2 * parameters.second) / 2, parameters.second, new HanningWindow());
if (stft == null) {
return new ArrayList<>(0);
}
HPCP hpcps = new HPCP(this.resolution, this.min_frequency, this.max_frequency);
hpcps.addContribution(stft);
int vectors = Math.max(hpcps.size() - SHINGLE_SIZE, 1);
final SummaryStatistics statistics = new SummaryStatistics();
List<Pair<Double, float[]>> features = new ArrayList<>(vectors);
for (int n = 0; n < vectors; n++) {
Pair<Double, float[]> feature = this.getHPCPShingle(hpcps, n);
features.add(feature);
statistics.addValue(feature.first);
}
final double threshold = 0.25 * statistics.getGeometricMean();
return features.stream().filter(f -> (f.first > threshold)).map(f -> f.second).collect(Collectors.toList());
}
use of org.vitrivr.cineast.core.data.segments.SegmentContainer in project cineast by vitrivr.
the class GenericExtractionItemHandler method run.
@Override
@SuppressWarnings("unchecked")
public void run() {
LOGGER.info("Starting extraction");
this.executorService.execute(pipeline);
final ObjectIdGenerator generator = this.context.objectIdGenerator();
Pair<ExtractionItemContainer, MediaType> pair = null;
/* Initalize all Metadata Extractors */
for (MetadataExtractor extractor : this.metadataExtractors) {
LOGGER.debug("Initializing metadata extractor {}", extractor.getClass().getSimpleName());
if (extractor instanceof MetadataFeatureModule) {
((MetadataFeatureModule<?>) extractor).init(this.context.persistencyWriter());
} else {
extractor.init();
}
}
/* Process until there's nothing left*/
while ((pair = this.nextItem()) != null) {
try {
LOGGER.debug("Processing path {} and mediatype {}", pair.getLeft(), pair.getRight());
if (handlerCache.get(pair.getRight()) == null) {
LOGGER.error("Unknown mediatype {}, exiting extraction", pair.getRight());
break;
}
/* Clear non-reusable segmenter */
handlerCache.compute(pair.getRight(), (mediaType, cache) -> {
Decoder decoder = null;
if (cache.getLeft() != null) {
if (cache.getLeft().canBeReused()) {
decoder = cache.getLeft();
}
}
return ImmutablePair.of(decoder, null);
});
/* Put a new decoder in the cache if there's not one already there */
if (handlerCache.get(pair.getRight()).getLeft() == null) {
Decoder decoder = handlers.get(pair.getRight()).getLeft().get();
handlerCache.compute(pair.getRight(), (mediaType, cache) -> new ImmutablePair<>(decoder, cache.getRight()));
}
/* Put a new segmenter in the cache if there's not one already there */
if (handlerCache.get(pair.getRight()).getRight() == null) {
Segmenter segmenter = handlers.get(pair.getRight()).getRight().get();
handlerCache.compute(pair.getRight(), (mediaType, cache) -> new ImmutablePair<>(cache.getLeft(), segmenter));
}
Decoder decoder = handlerCache.get(pair.getRight()).getLeft();
Segmenter segmenter = handlers.get(pair.getRight()).getRight().get();
if (decoder.init(pair.getLeft().getPathForExtraction(), Config.sharedConfig().getDecoders().get(pair.getRight()), Config.sharedConfig().getCache())) {
/* Create / lookup MediaObjectDescriptor for new file. */
final MediaObjectDescriptor descriptor = this.fetchOrCreateMultimediaObjectDescriptor(generator, pair.getLeft(), pair.getRight());
if (!this.checkAndPersistMultimediaObject(descriptor)) {
continue;
}
final String objectId = descriptor.getObjectId();
int segmentNumber = 1;
segmenter.init(decoder, descriptor);
this.executorService.execute(segmenter);
while (!segmenter.complete()) {
try {
final SegmentContainer container = segmenter.getNext();
if (container != null) {
/* Create segment-descriptor and try to persist it. */
MediaSegmentDescriptor mediaSegmentDescriptor;
if (container.getId() != null) {
mediaSegmentDescriptor = this.fetchOrCreateSegmentDescriptor(objectId, container.getId(), segmentNumber, container.getStart(), container.getEnd(), container.getAbsoluteStart(), container.getAbsoluteEnd());
/* Special case; segment ID is determined by container (image sequences only) */
} else {
mediaSegmentDescriptor = this.fetchOrCreateSegmentDescriptor(objectId, segmentNumber, container.getStart(), container.getEnd(), container.getAbsoluteStart(), container.getAbsoluteEnd());
}
container.setId(mediaSegmentDescriptor.getSegmentId());
container.setSuperId(mediaSegmentDescriptor.getObjectId());
if (!this.checkAndPersistSegment(mediaSegmentDescriptor)) {
continue;
}
int emissionTimeout = 1000;
while (!this.pipeline.emit(container, emissionTimeout)) {
LOGGER.debug("ExtractionPipeline is full - deferring emission of segment. Consider increasing the thread-pool count for the extraction pipeline.");
Thread.sleep(emissionTimeout);
// emissionTimeout += 500;
}
segmentNumber += 1;
}
} catch (InterruptedException e) {
LOGGER.log(Level.ERROR, "Thread was interrupted while the extraction process was running. Aborting...");
break;
}
}
List<MediaObjectMetadataDescriptor> metadata = pair.getLeft().getMetadata().stream().map(el -> MediaObjectMetadataDescriptor.fromExisting(el, objectId)).collect(Collectors.toList());
this.metadataWriter.write(metadata);
/* Extract metadata. */
this.extractAndPersistMetadata(pair.getLeft(), objectId);
/* Force flush the segment, object and metadata information. */
this.mediaSegmentWriter.flush();
this.objectWriter.flush();
this.metadataWriter.flush();
} else {
LOGGER.error("Failed to initialize decoder. File is being skipped...");
}
/* Increment the files counter. */
this.count_processed += 1;
/* Create new decoder pair for a new file if the decoder reports that it cannot be reused.*/
if (!decoder.canBeReused()) {
decoder.close();
final MediaType type = pair.getRight();
handlerCache.compute(type, (mediaType, cache) -> ImmutablePair.of(handlers.get(type).getLeft().get(), cache.getRight()));
}
for (ExtractionCompleteListener completeListener : this.completeListeners) {
completeListener.onCompleted(pair.getLeft());
}
/*
* Trigger garbage collection once in a while. This is specially relevant when many small files are processed, since unused allocated memory could accumulate and trigger swapping.
*/
if (this.count_processed % 50 == 0) {
System.gc();
}
} catch (Throwable t) {
LOGGER.error("Exception while processing path {}, {}", pair.getLeft(), t.getMessage());
t.printStackTrace();
}
}
shutdown();
}
use of org.vitrivr.cineast.core.data.segments.SegmentContainer in project cineast by vitrivr.
the class ExtractionPipeline method run.
/**
* When an object implementing interface <code>Runnable</code> is used to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
/* Set running flag to true. */
synchronized (this) {
this.running = true;
}
/* Process SegmentContainers in Queue: For each Extractor in list dispatch an extraction task. */
while (this.isRunning() || !this.segmentQueue.isEmpty()) {
if (!this.isRunning()) {
LOGGER.debug("Received stop signal, still {} elements left", this.segmentQueue.size());
}
try {
SegmentContainer s = this.segmentQueue.poll(500, TimeUnit.MILLISECONDS);
if (s != null) {
LOGGER.debug("Segment {} is being handed to the extraction pipeline.", s.getId());
for (Extractor f : extractors) {
try {
this.executorService.execute(new ExtractionTask(f, s, this));
LOGGER.debug("Submitted segment {} for feature {}", s.getId(), f.getClass().getSimpleName());
} catch (RejectedExecutionException e) {
this.segmentQueue.clear();
LOGGER.fatal("Failed to submit segment {} for feature {}. Aborting...\n{}", s.getId(), f.getClass().getSimpleName(), LogHelper.getStackTrace(e));
break;
}
}
/* Sort list of extractors by execution time. */
(this.extractors).sort((o1, o2) -> Long.compare(getAverageExecutionTime(o2.getClass().getSimpleName()), getAverageExecutionTime(o1.getClass().getSimpleName())));
}
} catch (InterruptedException e) {
LOGGER.warn("ShotDispatcher was interrupted: {}", LogHelper.getStackTrace(e));
}
}
this.shutdown();
synchronized (this) {
this.running = false;
}
}
Aggregations