I\'m a program that find contours in a stream, for example :
I want to find \"set of points \
Interesting task :) Here is my solution:
Here is code:
#include
#include
#include
#include
#include
#include "opencv2/opencv.hpp"
#include "fstream"
#include "iostream"
using namespace std;
using namespace cv;
int Thinning(unsigned char * ucBinedImg, unsigned char * ucThinnedImage, long lWidth, long lHeight, long lIterativeLimit)
{
if(ucBinedImg == NULL)
return -1;
if(ucThinnedImage == NULL)
return -2;
if(lIterativeLimit == -1)
lIterativeLimit = 60000;
unsigned char x1, x2, x3, x4, x5, x6, x7, x8, xp;
unsigned char g1, g2, g3, g4;
unsigned char b1, b2, b3, b4;
unsigned char np1, np2, npm;
unsigned char *pUp, *pDown, *pImg;
long lDeletedPoints = 0;
// set border
memcpy(ucThinnedImage, ucBinedImg, lWidth*lHeight);
for(long it=0; itnp2?np2:np1;
g2 = npm>=2 && npm<=3;
g3 = (x1 && (x2 || x3 || !x8)) == 0;
g4 = (x5 && (x6 || x7 || !x4)) == 0;
// first part
if(g1 && g2 && g3)
{
// delete this point
ucThinnedImage[lWidth*i + j] = 0;
++lDeletedPoints;
}
}
}
//syn
memcpy(ucBinedImg, ucThinnedImage, lWidth*lHeight);
for(long i=1; inp2?np2:np1;
g2 = npm>=2 && npm<=3;
g3 = (x1 && (x2 || x3 || !x8)) == 0;
g4 = (x5 && (x6 || x7 || !x4)) == 0;
// second part
if(g1 && g2 && g4)
{
// delete this point
ucThinnedImage[lWidth*i + j] = 0;
++lDeletedPoints;
}
}
}
//syn
memcpy(ucBinedImg, ucThinnedImage, lWidth*lHeight);
// if no points to be deleted
if(lDeletedPoints == 0)
break;
}
// clear edge bar
for(long i=0; i=lHeight-16)
ucThinnedImage[i*lWidth+j] = 0;
else if(j<16)
ucThinnedImage[i*lWidth+j] = 0;
else if(j>=lWidth-16)
ucThinnedImage[i*lWidth+j] = 0;
}
}
return 0;
}
void Thinning(Mat& src,Mat& dst,long IterativeLimit=-1)
{
Mat bin_img=src&1;
if(!dst.empty()){dst.release();}
dst=Mat::zeros(src.size(),CV_8UC1);
Thinning(bin_img.data,dst.data,bin_img.cols,bin_img.rows,IterativeLimit);
dst*=255;
}
int main(int argc, char* argv[])
{
namedWindow("source");
namedWindow("result");
Mat img=imread("raw_image.jpg",0);
cv::threshold(img,img,128,255,cv::THRESH_BINARY);
int erosion_size=5;
Mat element = getStructuringElement( cv::MORPH_ELLIPSE,Size( 2*erosion_size + 1, 2*erosion_size+1 ),Point( erosion_size, erosion_size ) );
cv::dilate(img,img,element);
Mat thinned;
Thinning(img,thinned);
vector lines;
HoughLines(thinned, lines, 0.5, CV_PI/360, 50, 0, 0 );
float hist_theta[2]={0,0};
float hist_rho[2]={0,0};
float n[2]={0,0};
for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0], theta = lines[i][1];
if(fabs(theta-CV_PI/2)
Here is a hack in this source it uses two 1D histograms for postprocessing. In real life application it should use 2D histogram for close lines averaging.