Load .yml file into hashmaps using snakeyaml (import junit library)

snake plissken picture snake plissken · Jan 15, 2014 · Viewed 26.2k times · Source

I am trying to load opencv's .yml file into arrayLists mean, projection and labels. I ve create those three arraylists and I am trying to parse into them the elements from the .yml file. I ve found snakeYAML documentation . However I didnt find a way to do so properly. I am trying to use

  final String fileName = "train.yml";
  opencvmatrix mat = new opencvmatrix(); 
  Yaml yaml = new Yaml();

  try {
     InputStream ios = new FileInputStream(new File(fileName));

     // Parse the YAML file and return the output as a series of Maps and Lists
     Map<String,Object> result = (Map<String,Object>)yaml.load(ios);
     System.out.println(result.toString());
     Collection<Object> file = result.values();



  } catch (Exception e) {
     e.printStackTrace();
  }

}

I am receiving as an error the following:

Exception in thread "main" while scanning a directive
in 'reader', line 1, column 1:
%YAML:1.0
^
expected alphabetic or numeric character, but found :(58)
in 'reader', line 1, column 6:
%YAML:1.0
     ^

at org.yaml.snakeyaml.scanner.ScannerImpl.scanDirectiveName(ScannerImpl.java:1269)
at org.yaml.snakeyaml.scanner.ScannerImpl.scanDirective(ScannerImpl.java:1221)
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchDirective(ScannerImpl.java:614)
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:306)
at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:226)
at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:195)
at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:158)
at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:143)
at org.yaml.snakeyaml.composer.Composer.getSingleNode(Composer.java:104)
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:120)
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:481)
at org.yaml.snakeyaml.Yaml.load(Yaml.java:412)
at projectCV.main(projectCV.java:33)
Java Result: 1

EDIT1: I ve noticed that my problems stands for assertEquals which is a function of the class assert part of junit library. I cant find a way to import properly the library to my classpath. I am trying two things, download .jar file and ADD/Jar folder and from project properties->libraries->compile tests-> add library -> Junit 4.10. But I am still having issues.

EDIT2: I change the YAML 1.0 to YAML 1.1, but nothing changes. I am still trying to find a suitable way to read the yml file.

       final String fileName = "train.yml";
  opencvmatrix mat = new opencvmatrix(); 
  Yaml yaml = new Yaml();

  try {
     InputStream ios = new FileInputStream(new File(fileName));

     // Parse the YAML file and return the output as a series of Maps and Lists
     Map<String,Object> result = (Map<String,Object>)yaml.load(ios);
     System.out.println(result.toString());
     Collection<Object> file = result.values();



  } catch (Exception e) {
     e.printStackTrace();
  }

}

WHen I am trying to run this code I am receiving:

Exception in thread "main" Can't construct a java object for tag:yaml.org,2002:opencv- 
matrix; exception=Class not found: opencv-matrix
in 'reader', line 3, column 7:
mean: !!opencv-matrix
      ^

EDIT3: I ve created a class opencvmatrix (like the name of .yml properties), with the properties rows, cols, dt, ArrayList data. The .yml file is like:

num_components: 19
num_components: 19
mean: !!opencvmatrix
rows: 1
cols: 3600
dt: d
data: [ 9.6842105263157890e+01, 1.0257894736842104e+02,
   1.0557894736842104e+02, 1.0794736842105263e+02,
   1.1752631578947367e+02, 1.1631578947368421e+02,
   1.1084210526315789e+02, 1.0373684210526315e+02,
   1.0052631578947368e+02, 9.5263157894736835e+01,
   9.0421052631578945e+01, 8.5631578947368411e+01,
   7.8684210526315780e+01, 7.2105263157894740e+01,
   6.9315789473684205e+01, 6.9105263157894740e+01,
   7.1052631578947370e+01, 7.9631578947368411e+01,
   9.0894736842105260e+01, 1.0121052631578947e+02,
   ....]
   projections:
   - !!opencvmatrix
   rows: 1
   cols: 19
   dt: d
   data: [ 1.6852352677811423e+03, -1.0112905042030820e+03,
      -1.3152188243875064e+03, 4.8298990155435700e+02,
      9.1980535900698968e+01, 6.5624763621018792e+02,
      -1.2380244625181117e+03, -1.8800931631152707e+02,
      -4.1473232893431384e+02, 5.7197035514178856e+02,
      4.9990276749703435e+02, 4.9062987890888604e+02,
      6.1928710580829818e+02, -1.2842392693864540e+03,
      2.4907719466932619e+01, 8.0299588479341844e+02,
      1.1621501008120421e+02, 1.0410492864645674e+02,
      8.5302163830384785e+01 ]
   - !!opencvmatrix
   rows: 1
   cols: 19
   dt: d
   data: [ -1.0313663745467784e+03, 1.9900404646205566e+03,
      -1.2844533156050284e+02, -4.3700867528097513e+02,
      6.6145551346834259e+02, -2.0562483671734990e+03,
      -1.9643774942432364e+02, 4.9329679854416281e+02,
      -2.0003326324501427e+02, 1.0737995038485865e+03,
      5.4161214984553695e+01, 4.7932826490658994e+02,
      8.6307152262273064e+02, 6.7413046532276610e+02,
      6.3835284527337114e+02, 4.1663169960066972e+02,
      3.5883912817427905e+01, -1.2935687563770381e+02,
      -1.6471877227400194e+03 ]
     ...
    labels: !!opencvmatrix
    rows: 1
    cols: 19
    dt: i
    data: [ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3 ]

Now without changing the main code I am receiving the following error:

   Can't construct a java object for tag:yaml.org,2002:opencvmatrix; exception=No single
   argument constructor found for class opencvmatrix
   in 'reader', line 1, column 7:
   mean: !!opencvmatrix
      ^

Answer

snake plissken picture snake plissken · Jan 16, 2014

I am finally trying the above code:

public static void main(String[] args) {
    // The path of your YAML file.
    final String fileName = "test.yml";
    ArrayList<String> key = new ArrayList<String>();
    ArrayList<String> value = new ArrayList<String>();
    Yaml yaml = new Yaml();

    try {
        InputStream ios = new FileInputStream(new File(fileName));

        // Parse the YAML file and return the output as a series of Maps and Lists
        Map< String, Object> result = (Map< String, Object>) yaml.load(ios);
        for (Object name : result.keySet()) {   

            key.add(name.toString());
            value.add(result.get(name).toString());    
        }

    } catch (Exception e) {
        e.printStackTrace();
    } 

     System.out.println(key + " " + value); }

Which actually reads .yml file and returns the keys and the correspondant values of the file. My problem is that value contains other objects which with their turn contains others Maps due to the order of the yaml file. Println shows the above in terminal:

[mean, eigenvalues, eigenvectors, projections, labels] [opencvmatrix@16e70aa, opencvmatrix@1a6e106, opencvmatrix@ff8927, [opencvmatrix@859445, opencvmatrix@1c94782, opencvmatrix@175e958, opencvmatrix@2acdad, opencvmatrix@254927, opencvmatrix@1e5c67f, opencvmatrix@4ace42, opencvmatrix@12b710e, opencvmatrix@10b6d81, opencvmatrix@142691b, opencvmatrix@102985e, opencvmatrix@16168c4, opencvmatrix@25417f, opencvmatrix@1ef0642, opencvmatrix@183d912, opencvmatrix@1204e58, opencvmatrix@1f78fae, opencvmatrix@1f9fe08, opencvmatrix@194ddfb], opencvmatrix@7996db]

How can I have access to the returned nested objects???

Edit2: Actually I had to cast the returned objects from the .yaml file to a new class that I have to define. So my code for reading .yml elements (face recognizer trained elements):

ArrayList<String> key = new ArrayList<String>();
    ArrayList<String> value = new ArrayList<String>();

    ArrayList<Object> obj = new ArrayList<Object>();
    ArrayList<Object> objected = new ArrayList<Object>();
    opencvmatrix mean = new opencvmatrix();
    opencvmatrix eigenValues = new opencvmatrix();
    opencvmatrix eigenVectors = new opencvmatrix();
    ArrayList<Object> opencvmatrix4 = new ArrayList<Object>();
    opencvmatrix labels = new opencvmatrix();
     opencvmatrix opencvmatrix6 = new opencvmatrix();
    ArrayList<ArrayList<Double>> projections = new ArrayList<ArrayList<Double>>();
    Yaml yaml = new Yaml();

    try {
        InputStream ios = new FileInputStream(new File(fileName));
        // Parse the YAML file and return the output as a series of Maps and Lists
        Map< String, Object> result = (Map< String, Object>) yaml.load(ios);
        for (Object name : result.keySet()) {
            key.add(name.toString());
            obj.add(result.get(name));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    File file = new File("eigenvalues.txt");
    // creates the file
    file.createNewFile();
    // creates a FileWriter Object
    FileWriter writer = new FileWriter(file);
        // Writes the content to the file


    mean = (opencvmatrix) (obj.get(0));
    eigenValues = (opencvmatrix) (obj.get(1));
    eigenVectors = (opencvmatrix) (obj.get(2));

    opencvmatrix4 = (ArrayList<Object>) obj.get(3);

    for(int i=0; i<opencvmatrix4.size(); i++){

        opencvmatrix6 = (opencvmatrix)opencvmatrix4.get(i);
        projections.add(opencvmatrix6.data);
    }

    //System.out.println(projections.get(0).size());

    labels = (opencvmatrix) (obj.get(4));
    //System.out.println(obj3.data.size());

    writer.write(eigenVectors.data.get(0) + "      ");
    temp.add(eigenVectors.data.get(0));
    eigenMatrix.add(temp);

    for (int i = 1; i < eigenVectors.data.size(); i++) {

        if (i % 3600 == 0) {
            writer.write("\n");
            eigenMatrix.add(temp);
            temp.clear();

        }

         writer.write(eigenVectors.data.get(i) + "      ");
        temp.add(eigenVectors.data.get(i));

    }
    writer.flush();
    writer.close();