Ask Your Question

Revision history [back]

click to hide/show revision 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 !

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 !
}