Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version
        #include <opencv2/opencv.hpp>
        #include <vector>
        #include <iostream>
        #include <opencv2/imgproc/imgproc_c.h>
        using namespace cv;
        using namespace std;
        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
        }
        Mat img = imread("C:/Users/ugurc/Desktop/yaprak.jpg");
        void thinningIteration(cv::Mat & img, int iter){
            CV_Assert(img.channels()==1);
            CV_Assert(img.depth() != sizeof(uchar));
            CV_Assert(img.rows>3 && img.cols > 3);
            cv::Mat marker = cv::Mat::zeros(img.size(), CV_8UC1);
            int nRows= img.rows;
            int nCols= img.cols;
            if (img.isContinuous()) {
                nCols *= nRows;
                nRows= 1;
            }
            int x, y;
            uchar *pAbove;
                uchar *pCurr;
                uchar *pBelow;
                uchar *nw, *no, *ne;    // north (pAbove)
                uchar *we, *me, *ea;
                uchar *sw, *so, *se;    // south (pBelow)

                uchar *pDst;
                pAbove = NULL;
                   pCurr = img.ptr<uchar>(0);
                   pBelow = img.ptr<uchar>(1);

                   for (y = 1; y < img.rows - 1; ++y) {
                       // shift the rows up by one
                       pAbove = pCurr;
                       pCurr = pBelow;
                       pBelow = img.ptr<uchar>(y + 1);

                       pDst = marker.ptr<uchar>(y);

                       // initialize col pointers
                       no = &(pAbove[0]);
                       ne = &(pAbove[1]);
                       me = &(pCurr[0]);
                       ea = &(pCurr[1]);
                       so = &(pBelow[0]);
                       se = &(pBelow[1]);

                       for (x = 1; x < img.cols - 1; ++x) {
                           // shift col pointers left by one (scan left to right)
                           nw = no;
                           no = ne;
                           ne = &(pAbove[x + 1]);
                           we = me;
                           me = ea;
                           ea = &(pCurr[x + 1]);
                           sw = so;
                           so = se;
                           se = &(pBelow[x + 1]);

                           int A = (*no == 0 && *ne == 1) + (*ne == 0 && *ea == 1) +
                               (*ea == 0 && *se == 1) + (*se == 0 && *so == 1) +
                               (*so == 0 && *sw == 1) + (*sw == 0 && *we == 1) +
                               (*we == 0 && *nw == 1) + (*nw == 0 && *no == 1);
                           int B = *no + *ne + *ea + *se + *so + *sw + *we + *nw;
                           int m1 = iter == 0 ? (*no * *ea * *so) : (*no * *ea * *we);
                           int m2 = iter == 0 ? (*ea * *so * *we) : (*no * *so * *we);

                           if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
                               pDst[x] = 1;
                       }
                   }

                   img &= ~marker;
               }

               void thinning(const cv::Mat& src, cv::Mat& dst)
               {
                   dst = src.clone();
                   dst /= 255;         // convert to binary image

                   cv::Mat prev = cv::Mat::zeros(dst.size(), CV_8UC1);
                   cv::Mat diff;

                   do {
                       thinningIteration(dst, 0);
                       thinningIteration(dst, 1);
                       cv::absdiff(dst, prev, diff);
                       dst.copyTo(prev);
                   } while (cv::countNonZero(diff) > 0);

                   dst *= 255;
               }
               void chain_freeman(const vector<Point> &contours, vector<uchar> &_chain) {
                   int i=0;
                   for (size_t i; i<contours.size()-1; i++) {
                       _chain.push_back(encode(contours[i],contours[i+1]));
                   }
                   _chain.push_back(encode(contours[i],contours[0]));
               }
        int main(){
            Mat img = imread("C:/Users/ugurc/Desktop/yaprak.jpg");
            Mat gray;
            cvtColor(img,gray,CV_BGR2GRAY);
            Mat binary;
            threshold(gray,binary,100,255,THRESH_BINARY_INV);
            thinning(binary,binary);
            //Find contours
            vector<Point> contours;
            findContours(binary,contours, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE);
            vector<uchar> chaincode;
            chain_freeman(contours,chaincode);
            FileStorage fs("chain.txt", 1);
            fs << "chain" << chaincode; // vector<uchar> is nicely supported !

                return 0;
        }

My code is here, Why it gives an error ?