I am writing a code to read and draw ply file format in opengl (c++).
I used glVertex3d function for vertex element. and now i couldn't understand that what's the element face in ply files?? is this for color? any idea?
Faces are polygons. After reading the vertices start reading the faces. Each face line starts with the number of vertices in the polygon. Then that number of 0-offset polygon vertex indices follow.
Say you read the vertices into a vector of structs with x, y, z members (say). Also read the face indices into a struct.
for (int f = 0; f < num_faces; ++f)
{
glBegin(GL_POLYGON);
for (int i = 0; i < face[f].num_vertices; ++i)
{
glVertex3f(face[f].vertex[i].x,face[f].vertex[i].y, face[f].vertex[i].z);
}
glEnd();
}
The element faces describes how many faces (polygon) there are in all of the ply files.
ply
format ascii 1.0 { ascii/binary, format version number }
comment made by Greg Turk { comments keyword specified, like all lines }
comment this file is a cube
element vertex 8 { define "vertex" element, 8 of them in file }
property float x { vertex contains float "x" coordinate }
property float y { y coordinate is also a vertex property }
property float z { z coordinate, too }
element face 6 { there are 6 "face" elements in the file }
property list uchar int vertex_index { "vertex_indices" is a list of ints }
end_header { delimits the end of the header }
0 0 0 { start of vertex list }
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3 { start of face list }
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
If you take a look at where the face list starts and you count to the end, then you should count 6. And the element faces also says 6 to confirm it.
The ply file above was shamefully stolen from http://paulbourke.net/dataformats/ply/
element is a triangle index, because the above example didn't work in meshlab EOF, here is another example:
ply
format ascii 1.0
comment VCGLIB generated
element vertex 8
property float x
property float y
property float z
property float nx
property float ny
property float nz
element face 12
property list uchar int vertex_indices
end_header
-1 24 4.5 -1.570796 1.570796 1.570796
0 21 4.5 1.570796 -1.570796 1.570796
0 24 4.5 1.570796 1.570796 1.570796
-1 21 4.5 -1.570796 -1.570796 1.570796
-1 21 2.5 -1.570796 -1.570796 -1.570796
0 24 2.5 1.570796 1.570796 -1.570796
0 21 2.5 1.570796 -1.570796 -1.570796
-1 24 2.5 -1.570796 1.570796 -1.570796
3 0 1 2
3 1 0 3
3 4 5 6
3 5 4 7
3 4 1 3
3 1 4 6
3 1 5 2
3 5 1 6
3 5 0 2
3 0 5 7
3 4 0 7
3 0 4 3
Related
We have an allocation problem: each node is a fuel source, and every edge contains a number of evenly spaced out lamps (think of them as being 1 m apart from each other). Each fuel source can power lamps that are on the immediate edges around it (it cannot fuel lamps through other nodes). A fuel source also has a radius in which it fuels lamps around it - depending on the radius (in meters) we can calculate the amount of fuel a give fuel source provides - example: a fuel source with a radius of 2 can fuel all the lamps within its radius and, in total, uses up 2 liters of fuel (fuel usage is a function of the radius).
Note that two nodes have only one path between each other (meaning that that the number of edges is equal to the number of nodes - 1).
The goal is to calculate the optimal radii of the fuel sources so that we minimize the fuel usage while fueling all the lamps.
Here is an example graph
The solution to this graph looks like this. The red ellipsoids are supposed to visualize the radii of the fuel sources, and below is a table of the relevant values:
Node, fuel source
Radius, fuel consumption
0
1
1
2
2
0
3
2
4
0
5
0
After we add up all the fuel amounts, we get the result: 5.
The input for the above task looks like this:
6 // 6 nodes (numVertices)
0 1 3 // Node 0 with an edge containing 3 nodes going to node 3 (src dest lights)
1 2 1 // ...
2 3 2
1 4 2
1 5 2
So far I've tried loading up my edges like this (note that this solution is quite cursed, especially with my use of pointers):
struct light {
int count;
};
struct node {
int d;
light* l;
};
std::vector<node*>* tree;
int numVertices;
// Do this for all values in the input
void AddEdge(int src, int dest, int lights) {
light* l = new light{ lights };
tree[src].push_back(new node{ dest, l });
tree[dest].push_back(new node{ src, l });
}
And then I solved the graph by using a greedy algorithm to 'remove' as many lamps per step as possible:
void Solve() {
int fuel = 0;
while (true) {
int maxNode = 0;
int maxNodeLights = 0;
for (int A = 0; A < numVertices; A++)
{
int lightsOnNode = 0;
for (node* B : tree[A])
{
lightsOnNode += B->l->count;
}
if (lightsOnNode > maxNodeLights) {
maxNodeLights = lightsOnNode;
maxNode = A;
}
}
if (maxNodeLights > 0) {
bool addedRange = false;
for (node* B : tree[maxNode])
{
if (B->l->count > 0) {
B->l->count--;
addedRange = true;
}
}
if (addedRange) {
fuel++;
}
}
else {
break;
}
}
std::cout << fuel << '\n';
}
If we were to parse the input string from the example case it would look like this:
numVertices = 6;
AddEdge(0, 1, 3);
AddEdge(1, 2, 1);
AddEdge(2, 3, 2);
AddEdge(1, 4, 2);
AddEdge(1, 5, 2);
Solve();
This works for simple graphs like the one above, but it fails by a small margin once a more complex graph is introduced, since the greedy algorithm doesn't look ahead if there is a better option a couple steps in the future.
A long test case can be found here. The fuel amount consumed by this graph is 77481.
New, failing test cases:
1 0 4
2 1 1
3 2 4
4 3 1
5 1 2
6 1 1
7 2 2
8 3 2
9 1 1
10 1 3
11 5 1
12 0 2
13 10 4
14 3 3
15 5 4
(Output: 16. Correct output: 17)
1 0 2
2 1 3
3 2 2
4 1 4
5 4 3
6 3 2
7 5 3
8 3 4
(Output: 10. Correct output: 11)
1 0 4
2 0 3
3 0 4
4 3 3
5 2 2
6 3 1
7 2 1
8 3 2
9 3 2
10 2 1
11 9 1
12 4 2
13 5 2
14 8 2
15 9 1
16 14 2
17 3 3
18 3 4
(Output: 15. Correct output: 16)
Algorithm pseudocode:
WHILE lamps remain unfueled
LOOP over sources
IF source has exactly one edge with unfueled lamps
SET fuel source to source at other end of unfueled edge
INCREMENT radius of fuel source with unfueled edge lamp count
LOOP over edges on fuel source
IF edge fueled lamp count from fuel sourve < fuel source radius
SET edge fueled lamp count from fuel source to fuel source radius
C++ code for this is at https://github.com/JamesBremner/LampLighter.
Sample output
Input
0 1 1
1 2 1
2 3 1
3 4 1
0 5 1
5 6 1
6 7 1
7 8 1
0 9 1
9 10 1
10 11 1
11 12 1
Source radii
0 r=0
1 r=1
2 r=0
3 r=1
4 r=0
5 r=1
6 r=0
7 r=1
8 r=0
9 r=1
10 r=0
11 r=1
12 r=0
Total fuel 6
Handling different numbers of lamps on each edge
0 1 3
1 2 1
0 5 3
5 6 1
Source radius
0 r=2
1 r=1
2 r=0
5 r=1
6 r=0
Total fuel 4
Another test
lamp ..\test\data11_19_2.txt
Output:
1 0 2
2 1 3
3 2 2
4 1 4
5 4 3
6 3 2
7 5 3
8 3 4
Source radius
1 r=3
0 r=0
2 r=0
3 r=4
4 r=0
5 r=3
6 r=0
7 r=0
8 r=0
Total fuel 10
Acknowledgement: This algorithm is based on an insight from MarkB who suggested that fueling should begin at leaf nodes and work "downwards"
Hello Friends, I was trying to make Triplet form of a sparse matrix using pointers and DMA but the output in first row is returning garbage values can anyone help me in resolving this issue.
int main(){
int k=0,z=0,arr[6][6]={
{15,0,0,22,0,-15},
{0,11,3,0,0,0},
{0,0,0,-6,0,0},
{0,0,0,0,0,0},
{91,0,0,0,0,0},
{0,0,28,0,0,0}
};
int **trip=new int *[3];
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
if (arr[i][j]==0){
z++;
}
else{
trip[k]=new int(1);
trip[k][0]=i;
trip[k][1]=j;
trip[k][2]=arr[i][j];
k++;
}
}
}
}
Output-
-65511600 22028 -65511568
0 3 22
0 5 -15
1 1 11
1 2 3
2 3 -6
4 0 91
5 2 28
Expected Output
0 0 15
0 3 22
0 5 -15
1 1 11
1 2 3
2 3 -6
4 0 91
5 2 28
I have an input file of the following format:
# 1 2 3 4 5 6 7
0 0 0 1
1 0 0 1
2 0 0 1
3 0 0 1
5 0 0 1
6 0 0 1
# 0 0 2 2 4 4 5
0 0 0 1
0 1 0 1
0 2 0 1
0 3 0 1
# 9 10 11 12 13 14 15 16 17 18
0 0 0 1
0 0 1 1
0 0 2 1
0 0 3 1
Each line preceded by a # must be read into its own vector. The entries in between these vectors represent matrices that also must be read into their own matrix.
So from the input file above, what I want to end up having is the following:
knot1 = {1 2 3 4 5 6 7}
cp1= { {0,0,0,1} {1,0,0,1} {2,0,0,1} {3,0,0,1} {5,0,0,1} {6,0,0,1} }
knot2 = {0 0 2 2 4 4 5}
cp2= {{...} {...} {...} {...} }
knot3 = {9 10 11 12 13 14 15 16 17 18}
cp3= {{...} {...} {...} {...} }
Note, each vector is not necessarily the same size! Same goes for the matrices. Also, the number of #vectors and matrices can vary as well.
Here is what I have so far:
ifstream file;
file.open(filename.c_str());
if(file.fail()){
cout << "Cannot open " << filename << endl;
}
int curr_line = 0;
vector<int> knot_locations; //stores the locations of the #vectors
while(!file.eof()){ //loops over input file checking to see where the #vectors are
curr_line++;
string line;
getline(file,line);
if(line[0]=='#'){
knot_locations.push_back(curr_line);
}
}
for(int i=0; i < knot_locations.size(); i++){
file.seekg(std::ios::beg);
for(int i=0; i < knot_locations[i] - 1; ++i){ // this loop skips to the line that contains the #vectors.
file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
}
so now that I am at the line
containing the vector, how can I read
in JUST that SINGLE line into a vector?!
I'm not sure how to turn a string into
a vector of floats. Also, since I know all the
locations of the vectors, I can read everything
else between into the matrices. But again, same
problem. I am not sure how to go about actually
reading these into a numeric array/vector given a line (string)
file.close();
Probably better ways of doing this. Any ideas on how to go about this problem? The key is to be able to read all the vectors marked with a # into their own vector. There can be anywhere between 1-3 of these vectors. And in between each of these vectors is a matrix of unknown rows/columns that also need to be read into their own matrix. What I have above just locates the # marked vectors. Need help on how to read a string line into a numeric array OR a recommendation on a different way to go about this.
Thank you.
The problem is defined as follows:
You're given a square. The square is lined with flat flagstones size 1m x 1m. Grass surround the square. Flagstones may be at different height. It starts raining. Determine where puddles will be created and compute how much water will contain. Water doesn't flow through the corners. In any area of grass can soak any volume of water at any time.
Input:
width height
width*height non-negative numbers describing a height of each flagstone over grass level.
Output:
Volume of water from puddles.
width*height signs describing places where puddles will be created and places won't.
. - no puddle
# - puddle
Examples
Input:
8 8
0 0 0 0 0 1 0 0
0 1 1 1 0 1 0 0
0 1 0 2 1 2 4 5
0 1 1 2 0 2 4 5
0 3 3 3 3 3 3 4
0 3 0 1 2 0 3 4
0 3 3 3 3 3 3 0
0 0 0 0 0 0 0 0
Output:
11
........
........
..#.....
....#...
........
..####..
........
........
Input:
16 16
8 0 1 0 0 0 0 2 2 4 3 4 5 0 0 2
6 2 0 5 2 0 0 2 0 1 0 3 1 2 1 2
7 2 5 4 5 2 2 1 3 6 2 0 8 0 3 2
2 5 3 3 0 1 0 3 3 0 2 0 3 0 1 1
1 0 1 4 1 1 2 0 3 1 1 0 1 1 2 0
2 6 2 0 0 3 5 5 4 3 0 4 2 2 2 1
4 2 0 0 0 1 1 2 1 2 1 0 4 0 5 1
2 0 2 0 5 0 1 1 2 0 7 5 1 0 4 3
13 6 6 0 10 8 10 5 17 6 4 0 12 5 7 6
7 3 0 2 5 3 8 0 3 6 1 4 2 3 0 3
8 0 6 1 2 2 6 3 7 6 4 0 1 4 2 1
3 5 3 0 0 4 4 1 4 0 3 2 0 0 1 0
13 3 6 0 7 5 3 2 21 8 13 3 5 0 13 7
3 5 6 2 2 2 0 2 5 0 7 0 1 3 7 5
7 4 5 3 4 5 2 0 23 9 10 5 9 7 9 8
11 5 7 7 9 7 1 0 17 13 7 10 6 5 8 10
Output:
103
................
..#.....###.#...
.......#...#.#..
....###..#.#.#..
.#..##.#...#....
...##.....#.....
..#####.#..#.#..
.#.#.###.#..##..
...#.......#....
..#....#..#...#.
.#.#.......#....
...##..#.#..##..
.#.#.........#..
......#..#.##...
.#..............
................
I tried different ways. Floodfill from max value, then from min value, but it's not working for every input or require code complication. Any ideas?
I'm interesting algorithm with complexity O(n^2) or o(n^3).
Summary
I would be tempted to try and solve this using a disjoint-set data structure.
The algorithm would be to iterate over all heights in the map performing a floodfill operation at each height.
Details
For each height x (starting at 0)
Connect all flagstones of height x to their neighbours if the neighbour height is <= x (storing connected sets of flagstones in the disjoint set data structure)
Remove any sets that connected to the grass
Mark all flagstones of height x in still remaining sets as being puddles
Add the total count of flagstones in remaining sets to a total t
At the end t gives the total volume of water.
Worked Example
0 0 0 0 0 1 0 0
0 1 1 1 0 1 0 0
0 1 0 2 1 2 4 5
0 1 1 2 0 2 4 5
0 3 3 3 3 3 3 4
0 3 0 1 2 0 3 4
0 3 3 3 3 3 3 0
0 0 0 0 0 0 0 0
Connect all flagstones of height 0 into sets A,B,C,D,E,F
A A A A A 1 B B
A 1 1 1 A 1 B B
A 1 C 2 1 2 4 5
A 1 1 2 D 2 4 5
A 3 3 3 3 3 3 4
A 3 E 1 2 F 3 4
A 3 3 3 3 3 3 A
A A A A A A A A
Remove flagstones connecting to the grass, and mark remaining as puddles
1
1 1 1 1
1 C 2 1 2 4 5 #
1 1 2 D 2 4 5 #
3 3 3 3 3 3 4
3 E 1 2 F 3 4 # #
3 3 3 3 3 3
Count remaining set size t=4
Connect all of height 1
G
C C C G
C C 2 D 2 4 5 #
C C 2 D 2 4 5 #
3 3 3 3 3 3 4
3 E E 2 F 3 4 # #
3 3 3 3 3 3
Remove flagstones connecting to the grass, and mark remaining as puddles
2 2 4 5 #
2 2 4 5 #
3 3 3 3 3 3 4
3 E E 2 F 3 4 # # #
3 3 3 3 3 3
t=4+3=7
Connect all of height 2
A B 4 5 #
A B 4 5 #
3 3 3 3 3 3 4
3 E E E E 3 4 # # #
3 3 3 3 3 3
Remove flagstones connecting to the grass, and mark remaining as puddles
4 5 #
4 5 #
3 3 3 3 3 3 4
3 E E E E 3 4 # # # #
3 3 3 3 3 3
t=7+4=11
Connect all of height 3
4 5 #
4 5 #
E E E E E E 4
E E E E E E 4 # # # #
E E E E E E
Remove flagstones connecting to the grass, and mark remaining as puddles
4 5 #
4 5 #
4
4 # # # #
After doing this for heights 4 and 5 nothing will remain.
A preprocessing step to create lists of all locations with each height should mean that the algorithm is close to O(n^2).
This seems to be working nicely. The idea is it is a recursive function, that checks to see if there is an "outward flow" that will allow it to escape to the edge. If the values that do no have such an escape will puddle. I tested it on your two input files and it works quite nicely. I copied the output for these two files for you. Pardon my nasty use of global variables and what not, I figured it was the concept behind the algorithm that mattered, not good style :)
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int SIZE_X;
int SIZE_Y;
bool **result;
int **INPUT;
bool flowToEdge(int x, int y, int value, bool* visited) {
if(x < 0 || x == SIZE_X || y < 0 || y == SIZE_Y) return true;
if(visited[(x * SIZE_X) + y]) return false;
if(value < INPUT[x][y]) return false;
visited[(x * SIZE_X) + y] = true;
bool left = false;
bool right = false;
bool up = false;
bool down = false;
left = flowToEdge(x-1, y, value, visited);
right = flowToEdge(x+1, y, value, visited);
up = flowToEdge(x, y+1, value, visited);
down = flowToEdge(x, y-1, value, visited);
return (left || up || down || right);
}
int main() {
ifstream myReadFile;
myReadFile.open("test.txt");
myReadFile >> SIZE_X;
myReadFile >> SIZE_Y;
INPUT = new int*[SIZE_X];
result = new bool*[SIZE_X];
for(int i = 0; i < SIZE_X; i++) {
INPUT[i] = new int[SIZE_Y];
result[i] = new bool[SIZE_Y];
for(int j = 0; j < SIZE_Y; j++) {
int someInt;
myReadFile >> someInt;
INPUT[i][j] = someInt;
result[i][j] = false;
}
}
for(int i = 0; i < SIZE_X; i++) {
for(int j = 0; j < SIZE_Y; j++) {
bool visited[SIZE_X][SIZE_Y];
for(int k = 0; k < SIZE_X; k++)//You can avoid this looping by using maps with pairs of coordinates instead
for(int l = 0; l < SIZE_Y; l++)
visited[k][l] = 0;
result[i][j] = flowToEdge(i,j, INPUT[i][j], &visited[0][0]);
}
}
for(int i = 0; i < SIZE_X; i++) {
cout << endl;
for(int j = 0; j < SIZE_Y; j++)
cout << result[i][j];
}
cout << endl;
}
The 16 by 16 file:
1111111111111111
1101111100010111
1111111011101011
1111000110101011
1011001011101111
1110011111011111
1100000101101011
1010100010110011
1110111111101111
1101101011011101
1010111111101111
1110011010110011
1010111111111011
1111110110100111
1011111111111111
1111111111111111
The 8 by 8 file
11111111
11111111
11011111
11110111
11111111
11000011
11111111
11111111
You could optimize this algorithm easily and considerably by doing several things. A: return true immediately upon finding a route would speed it up considerably. You could also connect it globally to the current set of results so that any given point would only have to find a flow point to an already known flow point, and not all the way to the edge.
The work involved, each n will have to exam each node. However, with optimizations, we should be able to get this much lower than n^2 for most cases, but it still an n^3 algorithm in the worst case... but creating this would be very difficult(with proper optimization logic... dynamic programming for the win!)
EDIT:
The modified code works for the following circumstances:
8 8
1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 1
1 0 1 1 1 1 0 1
1 0 1 0 0 1 0 1
1 0 1 1 0 1 0 1
1 0 1 1 0 1 0 1
1 0 0 0 0 1 0 1
1 1 1 1 1 1 1 1
And these are the results:
11111111
10000001
10111101
10100101
10110101
10110101
10000101
11111111
Now when we remove that 1 at the bottom we want to see no puddling.
8 8
1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 1
1 0 1 1 1 1 0 1
1 0 1 0 0 1 0 1
1 0 1 1 0 1 0 1
1 0 1 1 0 1 0 1
1 0 0 0 0 1 0 1
1 1 1 1 1 1 0 1
And these are the results
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
I know there is a lot of material related to hidden markov model and I have also read all the questions and answers related to this topic. I understand how it works and how it can be trained, however I am not able to solve the following problem I am having when trying to train it for a simple dynamic gesture.
I am using HMM implementation for OpenCV
I have looked into previously asked questions and answer here. Which has really helped me in understanding and using markov models.
I have total of two dynamic gestures, which are both symmetric (swipe left and swipe right)
There are total of 5 observations in which 4 are the different stages in the gesture and 5th one is an observation when non of these stages are occuring.
Swipe left gesture consists of the following observation: 1->2->3->4 (which should trigger a swipe left state)
Likewise Swipe Right gesture consists of the following observation: 4->3->2->1
I have 25 sequences. I am taking 20 observations for each of the sequence, which are used to train hidden markov model using Baum-Welch algorithm.
The following is the input sequence:
1 0 1 1 0 2 2 2 2 0 0 2 3 3 3 0 0 4 4 4
4 4 4 4 4 0 3 3 3 3 3 0 0 1 0 0 1 1 0 1
4 4 4 4 4 4 0 3 3 3 3 3 0 0 1 0 0 1 1 0
4 4 4 4 4 4 4 0 3 3 3 3 3 0 0 1 0 0 1 1
1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4 4 4 4
1 1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4 4 4
0 1 1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4 4
0 0 1 1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4
4 4 0 0 3 0 3 3 3 3 0 0 0 0 0 1 1 1 1 1
4 4 4 0 0 3 0 3 3 3 3 0 0 0 0 0 1 1 1 1
4 4 4 4 0 0 3 0 3 3 3 3 0 0 0 0 0 1 1 1
1 1 1 1 0 0 2 2 0 3 2 3 3 3 0 0 4 4 4 4
1 1 1 1 1 0 0 2 2 0 3 2 3 3 3 0 0 4 4 4
1 1 1 1 1 1 0 0 2 2 0 3 2 3 3 3 0 0 4 4
1 3 4 4 4 0 3 0 0 0 0 0 3 2 0 0 1 1 1 1
In this sequence you can see pattern for Swipe left and Swipe right gestures.
To train the hidden markov model I am initilizing it with the following values and then calling the train function to get the output:
TRANS:
0.7 0.15 0.15
0.3 0.4 0.3
0.3 0.4 0.3
EMIS:
0.3 0.1 0.1 0.1 0.1
0.2 0.1 0.2 0.2 0.3
0.2 0.3 0.2 0.2 0.1
INIT:
0.6 0.2 0.2
After training the output is:
TRANS:
0.81611 0.0847926 0.0990979
0.398458 0.346433 0.255109
0.371391 0.35587 0.272739
EMIS:
0.534127 0.125568 0.0824495 0.200169 0.0576869
0.294653 0.0250053 0.0500311 0.200616 0.429694
0.238808 0.075001 0.0500019 0.130455 0.505733
INIT:
0.443984 0.391323 0.164693
Using this model in my recognition program, I am not getting results.
I want the system to remain in a NULL STATE unless one of the gesture is detected.
In the Transition and Emission matrix I gave my guess values for both these gesture.
What do you think I might be doing wrong? Any pointers or help?
Lastly here is the code I am using for doing this (if anyone wants to have a look)
double TRGUESSdata[] = {0.7, 0.15, 0.15,
0.3, 0.4, 0.3,
0.3, 0.4, 0.3};
cv::Mat TRGUESS = cv::Mat(3,3,CV_64F,TRGUESSdata).clone();
double EMITGUESSdata[] = {0.3, 0.1, 0.1, 0.1, 0.1,
0.2, 0.1, 0.2, 0.2, 0.3,
0.2, 0.3, 0.2, 0.2, 0.1};
cv::Mat EMITGUESS = cv::Mat(3,5,CV_64F,EMITGUESSdata).clone();
double INITGUESSdata[] = {0.6 , 0.2 , 0.2};
cv::Mat INITGUESS = cv::Mat(1,3,CV_64F,INITGUESSdata).clone();
std::cout << seq.rows << " " << seq.cols << std::endl;
int a = 0;
std::ifstream fin;
fin.open("observations.txt");
for(int y =0; y < seq.rows; y++)
{
for(int x = 0; x<seq.cols ; x++)
{
fin >> a;
seq.at<signed int>(y,x) = (signed int)a;
std::cout << a;
}
std::cout << std::endl;
}
hmm.printModel(TRGUESS,EMITGUESS,INITGUESS);
hmm.train(seq,1000,TRGUESS,EMITGUESS,INITGUESS);
hmm.printModel(TRGUESS,EMITGUESS,INITGUESS);
Here fin is used to read the observation I have from my other code.
What does the 0 mean in your model ? It seems to me in your data there are no direct transitions for both states, it always goes back to the state 0. Try something like the following in your data for a state transition sequence.
1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 4
1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 2 2 3 3 4 4 0 0 0 0 0
4 4 3 3 2 2 1 1 0 0 0 0 0 0 0 0 0
4 4 4 3 3 3 2 2 2 2 2 1 1 1 1 1 1
As a general rule:
I would recommend to work with openCV only after you have a proof of concept in Matlab/octave. This has two reasons. First of all you know exactly what you want to do and how it works, and don't waste your time implementing and debugging your theory in a 'low' level language (compared to matlab). Debugging algorithms in openCV is really time-consuming.
Secondly after you know your stuff works as expected, if you implement it and hit a bug (of openCV or C++, python) you know it's not your theory, not your implementation, it's the framework. It happened to me already two times that employed computer scientists implemented directly from a paper (after being told not to do so), spending 80% of the remaining time to debug the algorithm without ANY success only to find out that: they didn't really get the theory or some submodule of openCV had a slight bug which degenerated their results.
The link you've mentioned uses a HMM toolbox in matlab. Try to implement and understand your problem there, it's really worth spending the time. Not only you can verify each step for correctness, you can use the itermediate matrices with your openCV code after you have a working model.