-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcut_ext_prova.cpp
executable file
·179 lines (154 loc) · 4.88 KB
/
cut_ext_prova.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
jpeg2ngc_cut
version: 0.1
author: Stefano Zamuner
date: 25/12/2010
description: it calculates the optimal drill-path to cut (externally) the input mask
*/
#ifdef _CH_
#pragma package <opencv>
#endif
#define CV_NO_BACKWARD_COMPATIBILITY
#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include <math.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using namespace cv;
#endif
fstream file;
int dil_img_rows;
double PIX_MM;
double DRILL_MM;
double PRECISION=0.05;
double DEEP=0.0;
double SAFE_HEIGHT=2.0;
double G1_XY_SPEED=400.0;
double G1_Z_SPEED=100.0;
void init_variables(){
cout<<"mm per pixel (x): ";
cin>>PIX_MM;
cout<<"drill diameter (mm): ";
cin>>DRILL_MM;
cout<<"deepness (mm): ";
cin>>DEEP;
cout<<"safe height (mm): ";
cin>>SAFE_HEIGHT;
cout<<"x-y feed rate (mm/min): ";
cin>>G1_XY_SPEED;
cout<<"z feed rate (mm/min): ";
cin>>G1_Z_SPEED;
}
Mat dilate_image(Mat img){
double pix_in_drill= DRILL_MM/PIX_MM;
int scale=1;
double intpart;
double fractpart=modf (pix_in_drill , &intpart);
Mat mat_src=img;
Mat mat_res;
Mat mat_dil;
Mat drill_element;
while(fractpart>PRECISION & fractpart<(1.-PRECISION)){
scale++; // fattore di scala per il resize
PIX_MM=PIX_MM*(double)(scale-1)/(double)scale; // numero di volte da dilatare
pix_in_drill= DRILL_MM/PIX_MM;
fractpart = modf (pix_in_drill , &intpart);
if(fractpart>=0.5){
intpart++;
}
}
drill_element=getStructuringElement(MORPH_ELLIPSE, Size(intpart,intpart), Point(-1, -1));
cout<<"L'immagine verra' riscalata di un fattore "<<scale<<endl;
cout<<"la punta e' composta da "<<intpart<<" pixel."<<endl;
resize(mat_src, mat_res , Size(), scale, scale, INTER_AREA);
dilate(mat_res, mat_dil, drill_element, Point(-1, -1), 1, BORDER_TRANSPARENT, morphologyDefaultBorderValue());
return mat_dil;
}
void write_circuit( CvSeq* d )
{
int total=d->total;
double first_x;
double first_y;
for(int i=0;i<total;i++){
CvPoint* p = CV_GET_SEQ_ELEM(CvPoint, d, i);
if(i==0){
first_x=double(p->x)*PIX_MM;
first_y=((double)dil_img_rows-double(p->y))*PIX_MM;
file<<"g0 x"<< first_x <<" y"<< first_y <<endl;
file<<"g1 f"<<G1_Z_SPEED<<" z-"<<DEEP<<"\n";
}
if(i==1){
file<<"g1 f"<<G1_XY_SPEED<<" x"<< double(p->x)*PIX_MM <<" y"<< ((double)dil_img_rows-double(p->y))*PIX_MM <<endl;
}
if(i>1){
file<<"x"<< double(p->x)*PIX_MM <<"\t"<<" y"<<((double)dil_img_rows-double(p->y))*PIX_MM<<endl;
}
file<<"x"<< first_x <<"\t"<<" y"<<first_y<<endl;
file<<"g0 z"<<SAFE_HEIGHT<<"\n";
}
}
void contour_iterator(CvSeq* contour) //itera tutti i contorni trovati dando la precedenza ai contorni più interni
{
CvSeq* c=contour;
int height=0;
while(c->v_next!=NULL){
c=c->v_next;
height++;
}
for(int i=0;i<=height;i++){
if(c->h_next!=NULL){
contour_iterator(c->h_next);
write_circuit(c);
}
if(c->h_next==NULL){
write_circuit(c);
}
c=c->v_prev;
}
}
void write_gcode(CvSeq* contours)
{
file<<"g21\n"; //set unit to mm
file<<"g0 z"<<SAFE_HEIGHT<<"\n"; //go to SAFE_HEIGHT
contour_iterator(contours); //iter on whole contours
file<<"x0 y0"<<endl; //return home
file<<"z0"<<endl; //return home
file<<"M02\n"; //end gcode
}
int main( int argc, char** argv )
{
char* filename = argv[1]; // image filename
char ngc_filename[strlen(argv[1])]; // output filename
for(int k = 0; k< strlen(argv[1])-4; k++){ // find basename: 'basename.jpg' --> 'basename'
ngc_filename[k]=(char)argv[1][k];
}
ngc_filename[strlen(argv[1])-4]='.';
ngc_filename[strlen(argv[1])-3]='n';
ngc_filename[strlen(argv[1])-2]='g';
ngc_filename[strlen(argv[1])-1]='c';
ngc_filename[strlen(argv[1])]='\0'; // 'basename' --> 'basename.ngc'
Mat img; // image
Mat mat_dilated; // dilated image
Mat mat_thres; // threshold image
CvMemStorage* storage = cvCreateMemStorage(0); // storage
CvSeq* contours = 0; // sequence of points of contours
init_variables();
file.open(ngc_filename, ios::out); // open output ngc file
cout<<"filename: "<<filename<<endl;
img = imread(filename,0);
mat_dilated=dilate_image(img); //dilate input image
mat_thres=mat_dilated;
dil_img_rows=mat_dilated.rows; //save number of rows in dilated image
threshold(mat_dilated, mat_thres, 200.0, 255.0,THRESH_BINARY ); //threshold dilated image
IplImage img_dilated=mat_dilated; //convert to IplImage
IplImage img_thres=mat_thres; //convert to IplImage
cvFindContours( &img_thres, storage, &contours, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) ); //find contours
write_gcode(contours); //write gcode
return 0;
}
#ifdef _EiC
main(1,"");
#endif