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
^
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();
SnakeYaml is YAML 1.1 parser and you are trying to parse YAML 1.0. It's indicated by "%YAML:1.0" directive (see 3.2.3.3 in the specs http://yaml.org/spec/1.0/#id2558635 )
YAML 1.1 has different syntax - "%YAML 1.1" (see 7.1.1 in the specs http://yaml.org/spec/1.1/#id895631 )
You can try to remove that directive from your file or change it to "%YAML 1.1" and hope it will be parsed correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With