1 | initial version |
My program is given below and result is image mThresh.
#include <opencv2/opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
vector<Point2d> z;
vector<Point2d> Z;
int main(int argc, char **argv)
{
Mat mTest,mThresh,mConnected;
int nbIter;
int borderType=cv::BORDER_REPLICATE;
Scalar borderValue=cv::morphologyDefaultBorderValue();
Point ancrage=cv::Point(-1,-1);
cv::Mat element = cv::getStructuringElement( MORPH_CROSS,cv::Size( 3, 3 ),cv::Point( 1, 1 ) );
Mat m=imread("C:/Users/Laurent.PC-LAURENT-VISI/Downloads/mergepcbdrill1.jpg",CV_LOAD_IMAGE_GRAYSCALE);
nbIter=1;
Mat m1,m2,m3,m4,m5;
threshold(m,mThresh,150,255,THRESH_BINARY);
erode(mThresh, m1, element,ancrage,nbIter,borderType,borderValue);
findContours(m1,contours,hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
int sizeMax=0,idx=0;
for (int i = 1; i < contours.size(); i++)
{
if (contours[i].size()>sizeMax)
{
idx=i;
sizeMax=contours[i].size();
}
}
Mat mc=Mat::zeros(m.size(),CV_8UC1);
Mat md=Mat::zeros(m.size(),CV_8UC1);
Moments mu = moments( contours[idx], false );
for (int i=0;i<contours[idx].size();i++)
z.push_back(contours[idx][i]);
dft(z,Z,DFT_COMPLEX_OUTPUT|DFT_SCALE);
vector<Point> ctrAppro;
vector<Point2d> derivAppro;
complex<double> I (0,1);
double TwoPI = 2*acos(-1.0);
int fn=300;
for (int i = 0; i < contours[idx].size(); i++)
{
complex<double> zz=complex<double>(Z[0].x,Z[0].y);
complex<double> zzd=complex<double>(0,0);
for (int j = 1; j < fn; j++)
{
double s = double(i) ;
complex<double> cplusn=complex<double>(Z[j].x,Z[j].y);
complex<double> cminusn=complex<double>(Z[Z.size()-j].x,Z[Z.size()-j].y);
zz += cplusn * exp(I*complex<double>(TwoPI*s*j/Z.size()))+cminusn * exp(I*complex<double>(TwoPI*s*(Z.size()-j)/Z.size()));
zzd += cplusn * I*complex<double>(TwoPI*j/Z.size()) *exp(I*complex<double>(TwoPI*s*j/Z.size()))+cminusn*I*complex<double>(-TwoPI*j/Z.size()) * exp(I*complex<double>(TwoPI*s*(Z.size()-j)/Z.size()));
}
ctrAppro.push_back(Point((int)(zz.real()),(int)(zz.imag())));
derivAppro.push_back(Point2d(zzd.real(),zzd.imag()));
}
drawContours(mc,contours,idx, Scalar(128),CV_FILLED);
contours.push_back(ctrAppro);
bool firstHole=false;
Point pp0,pp1,pp2,pp3;
for (int i = 0; i < contours[idx].size(); i += 1)
{
Point p1,p2;
p1 = Point(ctrAppro[i].x+5*derivAppro[i].y/ norm(derivAppro[i]), ctrAppro[i].y-5*derivAppro[i].x/ norm(derivAppro[i])) ;
p2 = Point(ctrAppro[i].x+80*derivAppro[i].y/ norm(derivAppro[i]), ctrAppro[i].y-80*derivAppro[i].x/ norm(derivAppro[i])) ;
line(mc, p1, p2, Scalar(255),2);
cv::LineIterator it(mThresh, p1, p2, 4);
cv::LineIterator it2 = it;
vector<uchar> buf(it.count);
bool hole=true;
for(int nbPt = 0; nbPt < it.count; nbPt++, ++it)
{
if (mThresh.at<uchar>(it.pos()) == 0)
{
hole=false;
break;
}
}
if (hole == true && firstHole==false)
{
p1 = Point(ctrAppro[i].x-4*derivAppro[i].y/ norm(derivAppro[i]), ctrAppro[i].y+4*derivAppro[i].x/ norm(derivAppro[i])) ;
p2 = Point(ctrAppro[i].x+20*derivAppro[i].y/ norm(derivAppro[i]), ctrAppro[i].y-20*derivAppro[i].x/ norm(derivAppro[i])) ;
line(mThresh, p1, p2, Scalar(0),1);
firstHole=true;
i+=4;
pp0=p1;
pp1=p2;
}
else if (hole==false && firstHole==true)
{
p1 = Point(ctrAppro[i].x-4*derivAppro[i].y/ norm(derivAppro[i]), ctrAppro[i].y+4*derivAppro[i].x/ norm(derivAppro[i])) ;
p2 = Point(ctrAppro[i].x+20*derivAppro[i].y/ norm(derivAppro[i]), ctrAppro[i].y-20*derivAppro[i].x/ norm(derivAppro[i])) ;
line(mThresh, p1, p2, Scalar(0),1);
firstHole=false;
i+=4;
pp2=p2;
pp3=p1;
line(mThresh, pp0, pp3, Scalar(255),5);
}
}
drawContours(mc,contours,contours.size()-1, Scalar(255));
imwrite("mdes.png",mc);
imwrite("mthresh.png",mThresh);
return 0;
};
result is