Skip to content

Commit

Permalink
st1002: implementation of Range Image Local Set (#455)
Browse files Browse the repository at this point in the history
This required ST 1202 transformations, which in turn required ST 1010 SDCC.

Includes usual javadoc, unit tests and a generator example.
  • Loading branch information
bradh authored Apr 11, 2023
1 parent be4ac43 commit d05758b
Show file tree
Hide file tree
Showing 129 changed files with 10,496 additions and 4 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/jdk11.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,26 @@ jobs:
with:
file: ./st0903vtrack/target/site/jacoco/jacoco.xml
flags: unittests-st0903-vtrack
- name: Upload ST 1002 implementation test results to Codecov
uses: codecov/codecov-action@v1.5.0
with:
file: ./st1002/target/site/jacoco/jacoco.xml
flags: unittests-st1002
- name: Upload ST 1010 implementation test results to Codecov
uses: codecov/codecov-action@v1.5.0
with:
file: ./st1010/target/site/jacoco/jacoco.xml
flags: unittests-st1010
- name: Upload ST 1108 implementation test results to Codecov
uses: codecov/codecov-action@v1.5.0
with:
file: ./st1108/target/site/jacoco/jacoco.xml
flags: unittests-st1108
- name: Upload ST 1202 implementation test results to Codecov
uses: codecov/codecov-action@v1.5.0
with:
file: ./st1202/target/site/jacoco/jacoco.xml
flags: unittests-st1202
- name: Upload ST 1206 implementation test results to Codecov
uses: codecov/codecov-action@v1.5.0
with:
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ The table below lists the status of currently-supported standards:
| ST 0808 | Ancillary Text Metadata Sets | Implemented as of ST 0808.2. Local Set support only, no universal set support. Deprecated by MISB. | |
| ST 0809 | Meteorological Metadata Local Set | Implemented as of ST 0809.2. No interoperability testing. | |
| ST 0903 | Video Moving Target Indicator and Track Metadata | VMTI and VTrack Local Sets implemented as of ST 0903.5. We also support pre-ST0903.4 files. | |
| ST 1002 | Range Motion Imagery | Partly implemented as of ST 1002.2. No interoperability testing. | |
| ST 1010 | Generalized Standard Deviation and Correlation Coefficient Metadata | Partly implemented as of ST 1010.3. No support for ST 1201 formatted standard deviation values. | |
| ST 1108 | Motion Imagery Interpretability and Quality Metadata | Implemented as of ST 1108.3. ST 1108.2 and earlier is also supported. No interoperability testing. | |
| ST 1201 | Floating Point to Integer Mapping | Fully implemented per ST 1201.5. | |
| ST 1202 | Generalized Transformation Parameters | Mostly implemented as of ST 1202.2. | |
| ST 1204 | Motion Imagery Identification System (MIIS) Core Identifier | Implemented as of ST 1204.3. | |
| ST 1206 | Synthetic Aperture Radar (SAR) Motion Imagery Metadata | Implemented as of ST 1206.1. Unit tests only, no interoperability testing. | |
| ST 1301 | Motion Imagery Identification System (MIIS) - Augmentation Identifiers | Implemented as of ST 1301.2. Validated with CMITT. | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

/** Indicates an error occurred during metadata parsing. */
public class KlvParseException extends Exception {
/** Internal store for inner exception. */
private final byte[] buffer;

/**
Expand Down
4 changes: 4 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ This example considered complete. See [its README](parserplugin/README.md) for m
It does a console dump of the raw KLV in a file to standard output. In this context, "raw" is the de-multiplexed stream content.
This example is considered complete. See [its README](rawklv/README.md) for more information.

## rangeimagegenerator

It generates a test file with video and ST 1002 Range Image KLV metadata. This example is a work-in-progress.

## systemout

It does a console dump of the KLV metadata in a file to standard output (`System.out` in Java, hence the name).
Expand Down
1 change: 1 addition & 0 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<module>rawklv</module>
<module>annotations</module>
<module>timetransfer</module>
<module>rangeimagegenerator</module>
</modules>

<dependencyManagement>
Expand Down
48 changes: 48 additions & 0 deletions examples/rangeimagegenerator/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jmisb</groupId>
<artifactId>examples</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<artifactId>rangeimagegenerator</artifactId>
<packaging>jar</packaging>
<name>Range image generator example</name>
<description>Example code that generates ST 1002 range image test files.</description>
<properties>
<main.class>org.jmisb.examples.rangeimagegenerator.GeneratorCLI</main.class>
</properties>
<dependencies>
<dependency>
<groupId>org.jmisb</groupId>
<artifactId>jmisb-api-ffmpeg</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
<dependency>
<groupId>org.jmisb</groupId>
<artifactId>st1002</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>googleformatter-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
11 changes: 11 additions & 0 deletions examples/rangeimagegenerator/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module org.jmisb.examples.rangeimagegenerator {
requires org.jmisb.api.ffmpeg;
requires org.jmisb.api;
requires org.jmisb.core;
requires org.jmisb.st1002;
requires org.jmisb.st1010;
requires org.jmisb.st1202;
requires commons.cli;
requires java.desktop;
requires org.slf4j;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package org.jmisb.examples.rangeimagegenerator;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.jmisb.api.common.KlvParseException;
import org.jmisb.api.klv.st1204.CoreIdentifier;
import org.jmisb.api.video.CodecIdentifier;
import org.jmisb.api.video.IVideoFileOutput;
import org.jmisb.api.video.KlvFormat;
import org.jmisb.api.video.MetadataFrame;
import org.jmisb.api.video.VideoFileOutput;
import org.jmisb.api.video.VideoFrame;
import org.jmisb.api.video.VideoOutputOptions;
import org.jmisb.core.video.TimingUtils;
import org.jmisb.st1002.GeneralizedTransformation;
import org.jmisb.st1002.IRangeImageMetadataValue;
import org.jmisb.st1002.RangeImageCompressionMethod;
import org.jmisb.st1002.RangeImageEnumerations;
import org.jmisb.st1002.RangeImageLocalSet;
import org.jmisb.st1002.RangeImageMetadataKey;
import org.jmisb.st1002.RangeImageSource;
import org.jmisb.st1002.RangeImageryDataType;
import org.jmisb.st1002.ST1002PrecisionTimeStamp;
import org.jmisb.st1002.ST1002VersionNumber;
import org.jmisb.st1002.SinglePointRangeMeasurement;
import org.jmisb.st1002.SinglePointRangeMeasurementColumn;
import org.jmisb.st1002.SinglePointRangeMeasurementRow;
import org.jmisb.st1010.SDCC;
import org.jmisb.st1202.Denominator_X;
import org.jmisb.st1202.Denominator_Y;
import org.jmisb.st1202.GeneralizedTransformationLocalSet;
import org.jmisb.st1202.GeneralizedTransformationParametersKey;
import org.jmisb.st1202.IGeneralizedTransformationMetadataValue;
import org.jmisb.st1202.SDCC_FLP;
import org.jmisb.st1202.ST1202DocumentVersion;
import org.jmisb.st1202.TransformationEnumeration;
import org.jmisb.st1202.X_Numerator_Constant;
import org.jmisb.st1202.X_Numerator_X;
import org.jmisb.st1202.X_Numerator_Y;
import org.jmisb.st1202.Y_Numerator_Constant;
import org.jmisb.st1202.Y_Numerator_X;
import org.jmisb.st1202.Y_Numerator_Y;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Generator {

private static Logger LOG = LoggerFactory.getLogger(Generator.class);
private final int width = 1280;
private final int height = 960;
private final int bitRate = 500_000;
private final int gopSize = 30;
private final double frameRate = 15.0;
private final double frameDuration = 1.0 / frameRate;
private final int duration = 60;
private KlvFormat klvFormat = KlvFormat.Synchronous;
private CodecIdentifier codec = CodecIdentifier.H264;
private String filename = "rangeimage.ts";

public Generator() throws KlvParseException {}

public void setKlvFormat(KlvFormat klvFormat) {
this.klvFormat = klvFormat;
}

public void setCodec(CodecIdentifier codec) {
this.codec = codec;
}

public void setOutputFile(String filename) {
this.filename = filename;
}

public void generate() throws KlvParseException {
showConfiguration();
CoreIdentifier coreIdentifier = new CoreIdentifier();
coreIdentifier.setMinorUUID(UUID.randomUUID());
coreIdentifier.setVersion(1);

try (IVideoFileOutput output =
new VideoFileOutput(
new VideoOutputOptions(
width, height, bitRate, frameRate, gopSize, klvFormat, codec))) {
output.open(filename);

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
try {
image = ImageIO.read(new File("test1280.jpg"));
} catch (IOException e) {
// TODO: log
}

final long numFrames = duration * Math.round(frameRate);
long startTime = System.currentTimeMillis();
double pts = 1000.0 * System.currentTimeMillis(); // Close enough for this.
for (long i = 0; i < numFrames; ++i) {
output.addVideoFrame(new VideoFrame(image, pts * 1.0e-6));
SortedMap<RangeImageMetadataKey, IRangeImageMetadataValue> values = new TreeMap<>();
values.put(
RangeImageMetadataKey.PrecisionTimeStamp,
new ST1002PrecisionTimeStamp((long) pts));
values.put(RangeImageMetadataKey.DocumentVersion, new ST1002VersionNumber(2));
values.put(
RangeImageMetadataKey.RangeImageEnumerations,
new RangeImageEnumerations(
RangeImageCompressionMethod.NO_COMPRESSION,
RangeImageryDataType.PERSPECTIVE,
RangeImageSource.RANGE_SENSOR));
values.put(
RangeImageMetadataKey.SinglePointRangeMeasurement,
new SinglePointRangeMeasurement(8000));
values.put(
RangeImageMetadataKey.SinglePointRangeMeasurementRowCoordinate,
new SinglePointRangeMeasurementRow(403));
values.put(
RangeImageMetadataKey.SinglePointRangeMeasurementColumnCoordinate,
new SinglePointRangeMeasurementColumn(803));
Map<GeneralizedTransformationParametersKey, IGeneralizedTransformationMetadataValue>
st1202values = new TreeMap<>();
st1202values.put(
GeneralizedTransformationParametersKey.X_Numerator_x, new X_Numerator_X(0));
st1202values.put(
GeneralizedTransformationParametersKey.X_Numerator_y, new X_Numerator_Y(0));
st1202values.put(
GeneralizedTransformationParametersKey.X_Numerator_Constant,
new X_Numerator_Constant(0));
st1202values.put(
GeneralizedTransformationParametersKey.Y_Numerator_x, new Y_Numerator_X(0));
st1202values.put(
GeneralizedTransformationParametersKey.Y_Numerator_y, new Y_Numerator_Y(0));
st1202values.put(
GeneralizedTransformationParametersKey.Y_Numerator_Constant,
new Y_Numerator_Constant(0));
st1202values.put(
GeneralizedTransformationParametersKey.Denominator_x, new Denominator_X(0));
st1202values.put(
GeneralizedTransformationParametersKey.Denominator_y, new Denominator_Y(0));
st1202values.put(
GeneralizedTransformationParametersKey.DocumentVersion,
new ST1202DocumentVersion(2));
SDCC sdcc = new SDCC();
sdcc.setValues(
new double[][] {
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}
});
st1202values.put(GeneralizedTransformationParametersKey.SDCC, new SDCC_FLP(sdcc));
st1202values.put(
GeneralizedTransformationParametersKey.TransformationEnumeration,
TransformationEnumeration.CHILD_PARENT);
values.put(
RangeImageMetadataKey.GeneralizedTransformationLocalSet,
new GeneralizedTransformation(
new GeneralizedTransformationLocalSet(st1202values)));
RangeImageLocalSet localSet = new RangeImageLocalSet(values);
output.addMetadataFrame(new MetadataFrame(localSet, pts));
pts += frameDuration * 1.0e6;
long elapsedTime = System.currentTimeMillis() - startTime;
long requiredElapsedTime = (long) ((i + 1) * frameDuration * 1000.0);
long waitTime = requiredElapsedTime - elapsedTime;
if (waitTime > 0) {
TimingUtils.shortWait(waitTime);
}
}

} catch (IOException e) {
LOG.error("Failed to write file", e);
}
}

private void showConfiguration() {
System.out.println("Generating with configuration:");
System.out.println(toString());
}

@Override
public String toString() {
return "Generator{"
+ "width="
+ width
+ ", height="
+ height
+ ", bitRate="
+ bitRate
+ ", gopSize="
+ gopSize
+ ", frameRate="
+ frameRate
+ ", frameDuration="
+ frameDuration
+ ", duration="
+ duration
+ ",\nklvFormat="
+ klvFormat
+ ",\nfilename="
+ filename
+ '}';
}
}
Loading

0 comments on commit d05758b

Please sign in to comment.