1 | initial version |
you MUST avoid using opencv's dead C api, support for that ended in 2010 already.
maybe it's easier to derivive the freeman chain from the contours instead:
uchar encode(const Point &a, const Point &b) {
uchar up = (a.y > b.y);
uchar left = (a.x > b.x);
uchar down = (a.y < b.y);
uchar right = (a.x < b.x);
uchar equx = (a.y == b.y);
uchar equy = (a.x == b.x);
return (up && equy) ? 0 : // N
(up && right) ? 1 : // NE
(right && equx) ? 2 : // E
(down && right) ? 3 : // SE
(down && equy) ? 4 : // S
(left && down) ? 5 : // SW
(left && equx) ? 6 : // W
7 ; // NW
}
// forward pass
void chain(const vector<Point> &contours, vector<uchar> &_chain) {
int i=0;
for (; i<contours.size()-1; i++) {
_chain.push_back(encode(contours[i],contours[i+1]));
}
_chain.push_back(encode(contours[i],contours[0]));
}
findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); // "dense" contour
vector<uchar> chaincode;
chain(contours, chaincode);
FileStorage fs("freeman.yml", 1);
fs << "chain" << chaincode; // vector<uchar> is nicely supported !
2 | No.2 Revision |
you MUST avoid using opencv's dead C api, support for that ended in 2010 already.
maybe it's easier to derivive the freeman chain from the contours instead:
uchar encode(const Point &a, const Point &b) {
uchar up = (a.y > b.y);
uchar left = (a.x > b.x);
uchar down = (a.y < b.y);
uchar right = (a.x < b.x);
uchar equx = (a.y == b.y);
uchar equy = (a.x == b.x);
return (up && equy) ? 0 : // N
(up && right) ? 1 : // NE
(right && equx) ? 2 : // E
(down && right) ? 3 : // SE
(down && equy) ? 4 : // S
(left && down) ? 5 : // SW
(left && equx) ? 6 : // W
7 ; // NW
}
// forward pass
void chain(const vector<Point> &contours, &contour, vector<uchar> &_chain) {
int i=0;
for (; i<contours.size()-1; i++) {
_chain.push_back(encode(contours[i],contours[i+1]));
_chain.push_back(encode(contour[i],contour[i+1]));
}
_chain.push_back(encode(contours[i],contours[0]));
_chain.push_back(encode(contour[i],contour[0]));
}
vector<vector<Point>> contours;
findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); // "dense" contour
for (size_t i=0; i<contours.size(); i++) {
vector<uchar> chaincode;
chain(contours, chain(contours[i], chaincode);
FileStorage fs("freeman.yml", 1);
fs << "chain" << chaincode; // vector<uchar> is nicely supported !
}