Skip to content

Commit

Permalink
Merge pull request #144 from vitrivr/primitive-extraction-support
Browse files Browse the repository at this point in the history
Support for PrimitiveTypeProvider in AbstractFeatureModule
  • Loading branch information
silvanheller authored Nov 2, 2020
2 parents 0246e62 + 9a3288a commit 1415106
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.vitrivr.cineast.core.data.entities;

import org.vitrivr.cineast.core.data.providers.primitive.PrimitiveTypeProvider;

public class SimplePrimitiveTypeProviderFeatureDescriptor {

public static final String[] FIELDNAMES = {"id", "feature"};

/**
* ID of the {@link MediaSegmentDescriptor} this {@link SimplePrimitiveTypeProviderFeatureDescriptor} belongs to.
*/
public final String segmentId;

/**
* Text that is contained in this {@link SimplePrimitiveTypeProviderFeatureDescriptor}.
*/
public final PrimitiveTypeProvider feature;

public SimplePrimitiveTypeProviderFeatureDescriptor(String segmentId, PrimitiveTypeProvider feature) {
this.segmentId = segmentId;
this.feature = feature;
}

public String getSegmentId() {
return this.segmentId;
}

public PrimitiveTypeProvider getFeature() {
return this.feature;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.vitrivr.cineast.core.db.dao.writer;

import org.vitrivr.cineast.core.data.entities.SimplePrimitiveTypeProviderFeatureDescriptor;
import org.vitrivr.cineast.core.db.PersistencyWriter;
import org.vitrivr.cineast.core.db.PersistentTuple;

public class PrimitiveTypeProviderFeatureDescriptorWriter extends AbstractBatchedEntityWriter<SimplePrimitiveTypeProviderFeatureDescriptor> {

private final String entityname;

public PrimitiveTypeProviderFeatureDescriptorWriter(PersistencyWriter<?> writer, String entityname) {
this(writer, entityname, 1);
}

public PrimitiveTypeProviderFeatureDescriptorWriter(PersistencyWriter<?> writer, String entityname, int batchsize) {
super(writer, batchsize, false);
this.entityname = entityname;
this.init();
}

@Override
public void init() {
this.writer.open(this.entityname);
}

@Override
protected PersistentTuple generateTuple(SimplePrimitiveTypeProviderFeatureDescriptor entity) {
return this.writer.generateTuple(entity.getSegmentId(), entity.getFeature());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.vitrivr.cineast.core.data.distance.DistanceElement;
import org.vitrivr.cineast.core.data.distance.SegmentDistanceElement;
import org.vitrivr.cineast.core.data.entities.SimpleFeatureDescriptor;
import org.vitrivr.cineast.core.data.entities.SimplePrimitiveTypeProviderFeatureDescriptor;
import org.vitrivr.cineast.core.data.providers.primitive.FloatArrayProvider;
import org.vitrivr.cineast.core.data.providers.primitive.FloatArrayTypeProvider;
import org.vitrivr.cineast.core.data.providers.primitive.PrimitiveTypeProvider;
Expand All @@ -24,6 +25,7 @@
import org.vitrivr.cineast.core.db.DBSelectorSupplier;
import org.vitrivr.cineast.core.db.PersistencyWriter;
import org.vitrivr.cineast.core.db.PersistencyWriterSupplier;
import org.vitrivr.cineast.core.db.dao.writer.PrimitiveTypeProviderFeatureDescriptorWriter;
import org.vitrivr.cineast.core.db.dao.writer.SimpleFeatureDescriptorWriter;
import org.vitrivr.cineast.core.db.setup.EntityCreator;
import org.vitrivr.cineast.core.features.extractor.Extractor;
Expand All @@ -33,6 +35,7 @@ public abstract class AbstractFeatureModule implements Extractor, Retriever {

private static final Logger LOGGER = LogManager.getLogger();
protected SimpleFeatureDescriptorWriter writer;
protected PrimitiveTypeProviderFeatureDescriptorWriter primitiveWriter;
protected DBSelector selector;
protected final float maxDist;
protected final int vectorLength;
Expand All @@ -59,6 +62,7 @@ public List<String> getTableNames() {
public void init(PersistencyWriterSupplier phandlerSupply, int batchSize) {
this.phandler = phandlerSupply.get();
this.writer = new SimpleFeatureDescriptorWriter(this.phandler, this.tableName, batchSize);
this.primitiveWriter = new PrimitiveTypeProviderFeatureDescriptorWriter(this.phandler, this.tableName, batchSize);
}

@Override
Expand All @@ -72,6 +76,11 @@ protected void persist(String shotId, ReadableFloatVector fv) {
this.writer.write(descriptor);
}

protected void persist(String shotId, PrimitiveTypeProvider fv) {
SimplePrimitiveTypeProviderFeatureDescriptor descriptor = new SimplePrimitiveTypeProviderFeatureDescriptor(shotId, fv);
this.primitiveWriter.write(descriptor);
}

protected void persist(String shotId, List<ReadableFloatVector> fvs) {
List<SimpleFeatureDescriptor> entities = fvs.stream().map(fv -> new SimpleFeatureDescriptor(shotId, fv)).collect(Collectors.toList());
this.writer.write(entities);
Expand Down Expand Up @@ -139,6 +148,11 @@ public void finish() {
this.writer = null;
}

if (this.primitiveWriter != null) {
this.primitiveWriter.close();
this.primitiveWriter = null;
}

if (this.phandler != null) {
this.phandler.close();
this.phandler = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.vitrivr.cineast.core.features.example;

import java.util.List;
import java.util.function.Supplier;

import org.apache.commons.lang3.RandomUtils;
import org.vitrivr.cineast.core.config.ReadableQueryConfig;
import org.vitrivr.cineast.core.data.providers.primitive.PrimitiveTypeProvider;
import org.vitrivr.cineast.core.data.score.ScoreElement;
import org.vitrivr.cineast.core.data.segments.SegmentContainer;
import org.vitrivr.cineast.core.db.setup.AttributeDefinition;
import org.vitrivr.cineast.core.db.setup.AttributeDefinition.AttributeType;
import org.vitrivr.cineast.core.db.setup.EntityCreator;
import org.vitrivr.cineast.core.features.abstracts.AbstractFeatureModule;

/**
* This class serves as an example of how to implement an {@link AbstractFeatureModule}, but having a {@link PrimitiveTypeProvider} as a feature output.
* Since this is in the example package, you have to provide the FQN, i.e. org.vitrivr.cineast.core.features.example.PrimitiveFeatureExample in the config to use it.
*/
public class PrimitiveFeatureExample extends AbstractFeatureModule {

/**
* Our table name
*/
public static final String PRIMITIVE_FEATURE_EXAMPLE_TABLE_NAME = "features_primitiveexample";

/**
* {@link AbstractFeatureModule#vectorLength} is only used in {@link AbstractFeatureModule#initalizePersistentLayer(Supplier)}, so since we overwrite that method, it does not matter what we specify.
* {@link AbstractFeatureModule#maxDist} is used for the correspondence function which processes all scores generated by the {@link #getSimilar(SegmentContainer, ReadableQueryConfig)} method.
*/
public PrimitiveFeatureExample() {
super(PRIMITIVE_FEATURE_EXAMPLE_TABLE_NAME, 5, 1);
}

/**
* Here, you can do whatever you want for a given shot. You can store multiple objects per shot.
*/
@Override
public void processSegment(SegmentContainer shot) {
this.persist(shot.getId(), PrimitiveTypeProvider.fromObject(RandomUtils.nextFloat(0, 5)));
}

/**
* This heavily depends on your feature. In general, you will want to perform some sort of retrieval using the {@link #selector} associated with this feature and then return {@link ScoreElement} which map the id of a multimediasegment or object to a score between 0 and {@link #maxDist}
*/
@Override
public List<ScoreElement> getSimilar(SegmentContainer sc, ReadableQueryConfig qc) {
// not supported by default. Implement your own using this.selector
throw new UnsupportedOperationException();
}

/**
* Here, we initialize the underlying database layer. This heavily depends on your feature.
*/
@Override
public void initalizePersistentLayer(Supplier<EntityCreator> supply) {
supply.get().createFeatureEntity(PRIMITIVE_FEATURE_EXAMPLE_TABLE_NAME, true, new AttributeDefinition("feature", AttributeType.FLOAT));
}
}

0 comments on commit 1415106

Please sign in to comment.