Skip to content

Commit

Permalink
st1002: implementation of Range Image Local Set
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 committed Feb 7, 2023
1 parent be4ac43 commit 6e91977
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ 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 1204 | Motion Imagery Identification System (MIIS) Core Identifier | Implemented as of ST 1204.3. | |
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
+ '}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.jmisb.examples.rangeimagegenerator;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.jmisb.api.common.KlvParseException;
import org.jmisb.api.video.CodecIdentifier;

/** Range image file generator */
public class GeneratorCLI {

/** @param args the command line arguments */
public static void main(String[] args) throws KlvParseException {
final Options commandLineOptions = new Options();
commandLineOptions.addOption(new Option("o", "outputFile", true, "Output file name"));
commandLineOptions.addOption(
new Option(null, "coding", true, "The video coding to use (H.264 or H.265)"));
commandLineOptions.addOption(new Option("h", "help", false, "Show help message"));
CommandLineParser commandLineParser = new DefaultParser();
CommandLine commandLine;
try {
commandLine = commandLineParser.parse(commandLineOptions, args);
Generator generator = new Generator();
if (commandLine.hasOption("h")) {
showHelp(commandLineOptions);
return;
}
if (commandLine.hasOption("coding")) {
String codecName = commandLine.getOptionValue("coding");
if (codecName.equalsIgnoreCase("H.264") || codecName.equalsIgnoreCase("H264")) {
generator.setCodec(CodecIdentifier.H264);
} else if (codecName.equalsIgnoreCase("H.265")
|| codecName.equalsIgnoreCase("H265")) {
generator.setCodec(CodecIdentifier.H265);
}
}
if (commandLine.hasOption("outputFileBase")) {
generator.setOutputFile(commandLine.getOptionValue("outputFile"));
}
generator.generate();
} catch (ParseException ex) {
showHelp(commandLineOptions);
}
}

private static void showHelp(final Options commandLineOptions) {
String header = "Generate test MISB ST 1002 range image files\n\n";
String footer =
"\nPlease report issues at /~https://github.com/WestRidgeSystems/jmisb/issues";
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("generator", header, commandLineOptions, footer, true);
}
}
Binary file added examples/rangeimagegenerator/test1280.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 6e91977

Please sign in to comment.