Ask Your Question
0

Is there something missing in the chain code?

asked 2017-05-16 12:07:14 -0600

Nuz gravatar image

I am not able to read the image and how can i retrieve the xml file and save it? Can someone help..

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>

using namespace std;
using namespace cv;

int main() {

Mat img = imread("Outline.jpg"); //outline of foot


imshow("Test", img);

vector<vector<Point> > contours;

findContours(img, contours, RETR_EXTERNAL, CV_CHAIN_CODE);
cout << Mat(contours[0]) << endl;

findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
cout << "CHAIN_APPROX_SIMPLE" << endl;
cout << Mat(contours[0]) << endl;

CvChain* chain = 0;
CvMemStorage* storage = 0;
storage = cvCreateMemStorage(0);
cvFindContours(&IplImage(img), storage, (CvSeq**)(&chain), sizeof(*chain), CV_RETR_TREE, 
CV_CHAIN_CODE);



for (; chain != NULL; chain = (CvChain*)chain->h_next)
{

    CvSeqReader reader;
    int i, total = chain->total;
    cvStartReadSeq((CvSeq*)chain, &reader, 0);
    cout<<"--------------------chain\n";

    for (i = 0; i<total; i++)
    {
        char code;
        CV_READ_SEQ_ELEM(code, reader);
        cout<<"%d"<<code;
    }
}



waitKey(0);

return 0;
    }
edit retag flag offensive close merge delete

Comments

opencv version? 1.0 or 2.4.9 3.2.0-dev?

LBerger gravatar imageLBerger ( 2017-05-16 12:53:09 -0600 )edit

@LBerger 2.4.9

Nuz gravatar imageNuz ( 2017-05-16 13:25:11 -0600 )edit

Sorry it's too old for me. You have an example here and filestorage doc is here.

LBerger gravatar imageLBerger ( 2017-05-16 13:48:13 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2018-03-19 03:45:17 -0600

ugurcabuk gravatar image
        #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 ...
(more)
edit flag offensive delete link more
0

answered 2017-05-18 00:22:57 -0600

berak gravatar image

updated 2018-03-19 03:49:00 -0600

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> &contour, vector<uchar> &_chain) {
    int i=0;
    for (; i<contours.size()-1; i++) {
        _chain.push_back(encode(contour[i],contour[i+1]));
    }
    _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[i], chaincode);
}
edit flag offensive delete link more

Comments

I think, there is a mistake in your code. Because when you run this code, it is given an error. vector<point> &contours is not supported by findcontours ? If you change this line as vector<vector<point> contours, it gives an error, which is called as invalid arguments or something like that. I don't understand...

ugurcabuk gravatar imageugurcabuk ( 2018-03-19 03:21:17 -0600 )edit

please be more precise

berak gravatar imageberak ( 2018-03-19 03:33:10 -0600 )edit
1

Okay, Sorry. When I run this code , it gives an error message that is ;

OpenCV Error: Assertion failed ((_contours.kind() == _InputArray::STD_VECTOR_VECTOR || _contours.kind() == _InputArray::STD_VECTOR_MAT || _contours.kind() == _InputArray::STD_VECTOR_UMAT)) in findContours, file C:\opencv_src\opencv-3.3.0\modules\imgproc\src\contours.cpp, line 1892

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

ugurcabuk gravatar imageugurcabuk ( 2018-03-19 03:38:39 -0600 )edit

you're right. confusion between multiple contours (findContours()) and single ones(chain())

updated above code, hope it'll work better, now.

berak gravatar imageberak ( 2018-03-19 03:50:06 -0600 )edit
1

Yeah, It's okay now but it doesn't give actual result but I can fix that part. By the way, thank you very much :)

ugurcabuk gravatar imageugurcabuk ( 2018-03-19 04:00:51 -0600 )edit

btw, did you try to make an answer yesterday, and deleted that ?

(we were somwhat puzzled about the activity on it)

berak gravatar imageberak ( 2018-03-19 04:03:59 -0600 )edit
1

I don't really remember about yesterday. Almost, I've been dealing with a project and everything is out of my mind...

ugurcabuk gravatar imageugurcabuk ( 2018-03-19 04:12:06 -0600 )edit
1

nvm, it's not important. thanks for your answer, and for pointing out the problem !

berak gravatar imageberak ( 2018-03-19 04:40:56 -0600 )edit
Login/Signup to Answer

Question Tools

2 followers

Stats

Asked: 2017-05-16 12:07:14 -0600

Seen: 145 times

Last updated: Mar 19