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 ?