package fr.unistra.pelican.algorithms.io;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.IntegerImage;
import fr.unistra.pelican.PelicanException;
/** This class allows to load a video segmentation from a file using the ODESSA Segmentation Format
* This format is inspired by the Berkeley Segmentation Format for images.
*
* Format Description
*
* Segmentation files end in ".osf".
*
* The overall structure of the file is as follows:
* <header>
* data
* <data>
*
* The first part of the file is the header. The header is ascii text. The header
* is separated from the data with a line containing the literal text "data".
*
* The header can contain the following information, in any order:
*
* date <date string>
* width <int> // width of image
* height <int> // height of image
* length <int> // temporal length of image (in frames)
*
* The {width,height,length} lines are required. All others lines are optional.
*
* The format is designed to be very easy to parse; it is not optimized for space.
* Compress osf files if you want smaller files! Each line in the data section contains 2 integers:
*
* <nb_p> <l>
*
* <l> is the region label; <nb_p> is the number of consecutive pixels to this label
*
* The video is considered as 1D. Dimensions are encapsuled like lines in rows in frames.
*
*
* @author Jonathan Weber
*
*/
public class OdessaSegmentationLoad extends Algorithm {
/**
* Input parameter
*/
public String filename;
/**
* Output parameter
*/
public IntegerImage outputImage;
/**
* Constructor
*
*/
public OdessaSegmentationLoad() {
super.inputs = "filename";
super.outputs="outputImage";
}
@Override
public void launch() throws AlgorithmException {
File f=new File(filename);
int xDim = 0;
int yDim = 0;
int tDim = 0;
try
{
BufferedReader br= new BufferedReader(new FileReader(f));
String line = br.readLine();
while(!line.equalsIgnoreCase("data"))
{
String[] tokens = line.split(" ");
if(tokens[0].equalsIgnoreCase("height"))
{
yDim = Integer.valueOf(tokens[1]);
} else if(tokens[0].equalsIgnoreCase("width"))
{
xDim = Integer.valueOf(tokens[1]);
} else if(tokens[0].equalsIgnoreCase("length"))
{
tDim = Integer.valueOf(tokens[1]);
}
line = br.readLine();
}
if(xDim!=0 && yDim!=0 && tDim!=0)
{
outputImage = new IntegerImage(xDim,yDim,1,tDim,1);
int i=0;
while((line=br.readLine()) != null)
{
String[] tokens = line.split(" ");
int nb_pixel = Integer.valueOf(tokens[0]);
int label = Integer.valueOf(tokens[1]);
for(int j=0;j<nb_pixel;j++,i++)
{
outputImage.setPixelInt(i, label);
}
}
} else
{
throw(new PelicanException(filename+" has a bad format"));
}
}
catch (FileNotFoundException e) {
throw new AlgorithmException("Error opening file " +f,e);
} catch (IOException e) {
throw new AlgorithmException("Error reading file " +f,e);
}catch (NumberFormatException e) {
throw new AlgorithmException("Error reading file " +f + " : value can not be parsed as a double.",e);
}
}
public static IntegerImage exec(String filename) {
return (IntegerImage) new OdessaSegmentationLoad().process(filename);
}
}