-
Notifications
You must be signed in to change notification settings - Fork 1
/
brain.c
executable file
·306 lines (221 loc) · 8.34 KB
/
brain.c
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/* brain.c
* Nathan W Brei
* 6.087 Final Project: image2dxf
* 26 January 2010
*/
/* brain.c runs through the process of noise reduction, binarization,
and contour mapping, with redundant algorithms where
necessary. THIS IS WHERE THE <PROVERBIAL> MAGIC HAPPENS!!! */
#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include "scribe.h"
#include "toolchest.h"
#define MAX_WINDOW_SIZE 600
#define WAIT_TIME 1000
/* Global variables, shared with main */
int visualize = 0; /* Whether or not to include visualization */
int magic_number = 0; /* Algorithm-specific behavior */
int algorithm = 0; /* Chosen algorithm */
int invert = 0; /* Whether or not image comes from webcam */
int val1 = 0; /* Algorithm-specific parameters, scale from 0 to 255 */
int val2 = 0;
int val3 = 0;
int quality=1000;
IplImage* target; /* The image we are playing with */
CvSeq* contour; /* The contours we end up with */
CvMemStorage* storage;
/* C is really spoiling me; the Java student I once was recoils at my
utter lack of encapsulation and willy-nilly global variable
access. */
/* image_from_file loads the user-specified image from file. */
void image_from_file (char* image_name){
/* Load the image */
target=cvLoadImage(image_name, CV_LOAD_IMAGE_GRAYSCALE);
/* If loading failed, abort. */
if(!target){
fprintf(stderr, "\n\e[91mError: Unable to load image.\n\e[0m");
abort();
}
if(invert) cvNot(target, target);
}
/* void write_contours(void)
Writes all of the contour information to the DXF file */
void write_contours(void){
puts("Eventually write contours to file.");
/* CvSeq* p = contour->
for( ; contour != 0; contour = contour->h_next ){
dxf_point();
}
*/
}
/* void run_manual (void) The interactive edge-detection
procedure. Without this, we basically have no hope of determining
sensible algorithm parameters. Given a collection of similar
images, we can manually find the proper parameters on a reference
image, and from there process the rest non-interactively.
This gets a little bit harder to read because it is event-driven.
Sorry about that.
*/
void on_mouse(int event, int x, int y, int flags, void* param);
void refresh_results(void);
void run_manual (void){
/* Create window showing binarization */
cvNamedWindow("Binarized", CV_WINDOW_AUTOSIZE);
/* Create window showing resulting contours */
cvNamedWindow("Contourized", CV_WINDOW_AUTOSIZE);
/* Create window showing all three sliders */
cvNamedWindow("Adjust parameters- then click on image",CV_WINDOW_AUTOSIZE);
cvCreateTrackbar("Value 1", "Adjust parameters- then click on image",
&val1, 255, NULL);
cvCreateTrackbar("Value 2", "Adjust parameters- then click on image",
&val2, 255, NULL);
cvCreateTrackbar("Value 3", "Adjust parameters- then click on image",
&val3, 255, NULL);
cvSetMouseCallback("Binarized", on_mouse, NULL);
cvSetMouseCallback("Contourized", on_mouse, NULL);
/* Invert image, obviously */
cvNot(target, target);
/* Put results into windows */
refresh_results();
cvSetTrackbarPos("Value 1", "Adjust parameters- then click on image", val1);
cvSetTrackbarPos("Value 2", "Adjust parameters- then click on image", val2);
cvSetTrackbarPos("Value 3", "Adjust parameters- then click on image", val3);
/* Window sizing and placement */
int max = (target->width > target->height) ?
target->width : target->height;
cvResizeWindow("Binarized", (target->width*400/max),
(target->height*400/max));
cvResizeWindow("Contourized", (target->width*400/max),
(target->height*400/max));
cvResizeWindow("Adjust parameters- then click on image", 850, 150);
cvMoveWindow("Binarized",100,100);
cvMoveWindow("Contourized",550,100);
cvMoveWindow("Adjust parameters- then click on image",100,550);
/* Until the user presses a key, do nothing. */
char c = -1;
while (c==-1) c = cvWaitKey(0);
/* Program flow passes to slider callback function */
/* Write contours to file */
write_contours();
/* Deallocate last resources */
cvReleaseMemStorage(&storage);
cvDestroyWindow("Binarize");
cvDestroyWindow("Contourize");
cvDestroyWindow("Adjust parameters- then click on image");
/* Print values for future reference */
printf("Algorithm %d, val1=%d val2=%d val3=%d\n",algorithm,
val1,val2,val3);
}
void refresh_results(void){
/* Create resultant images */
IplImage* backuptarget = cvCloneImage(target);
IplImage* contourtarget =
cvCreateImage(cvSize(target->width,target->height), 8, 3);
cvZero( contourtarget );
/* Run some binarize algorithm */
switch(algorithm){
case 0: binarize_threshold(); break;
case 1: binarize_adaptive_threshold(); break;
case 2: binarize_canny(); break;
case 3: binarize_median_canny(); break;
default: binarize_threshold(); break;
}
/* Write binarized image to screen */
cvShowImage("Binarized", target);
/* Run some contourize algorithm */
contourize_simple();
/* Write contours to screen */
CvSeq* p = contour;
for( ; p != 0; p = p->h_next ){
/* Trippy colors differentiate each contour level */
CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
cvDrawContours( contourtarget, p, color, color, -1,
CV_FILLED, 8,cvPoint(0,0) );
}
cvShowImage("Contourized", contourtarget);
cvReleaseImage(&contourtarget);
cvReleaseImage(&target);
target = cvCloneImage(backuptarget);
cvReleaseImage(&backuptarget);
}
/* void on_mouse(...)
callback function for mouse events.
We use this instead of the trackbar event because we want to
refresh in discrete, occasional intervals */
void on_mouse(int event, int x, int y, int flags, void* param){
/* on mouseUp, set vals based on trackbar vals. */
if(event==CV_EVENT_LBUTTONUP){
printf("Running with values %d %d %d\n",val1,val2,val3);
refresh_results();
}
}
/* void run_automatic (void) The non-interactive edge-detection
procedure. This is the real heart of the program, managing all of
the different algorithms as well as notable output.
*/
void run_automatic (void){
if(visualize) {
/* Create window, show original */
cvNamedWindow("image2dxf", CV_WINDOW_AUTOSIZE);
//cvSetMouseCallback("image2dxf", on_mouse, NULL);
cvShowImage("image2dxf", target);
/* Resize as necessary */
int max = (target->width > target->height) ?
target->width : target->height;
cvResizeWindow("image2dxf", (target->width*MAX_WINDOW_SIZE/max),
(target->height*MAX_WINDOW_SIZE/max));
/* Wait for user acknowledgement */
cvWaitKey(WAIT_TIME);
}
/* Contourizing algorithms treat white as object of interest, black
as background. So we have to invert. We do it at this stage so that
we don't confuse the user. */
cvNot(target, target);
if(visualize){
/* Wait for user acknowledgement */
cvShowImage("image2dxf", target);
cvWaitKey(WAIT_TIME);
}
/* Run some binarize algorithm */
switch(algorithm){
case 0: binarize_threshold(); break;
case 1: binarize_adaptive_threshold(); break;
case 2: binarize_canny(); break;
case 3: binarize_median_canny(); break;
default: binarize_threshold(); break;
}
if(visualize){
/* Wait for user acknowledgement */
cvShowImage("image2dxf", target);
cvWaitKey(WAIT_TIME);
}
/* Run some contourize algorithm */
contourize_simple();
/* This is where it gets artistic */
if(visualize){
/* Black background time! Note we need to recreate target in COLOR */
CvSize targetsize = cvSize(target->width,target->height);
cvReleaseImage(&target);
target=cvCreateImage( targetsize, 8, 3 );
cvZero( target );
/* Write contours to screen */
CvSeq* p = contour;
for( ; p != 0; p = p->h_next ){
/* Trippy colors differentiate each contour level */
CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
cvDrawContours( target, p, color, color, -1,
CV_FILLED, 8,cvPoint(0,0) );
}
/* Wait for user acknowledgement */
cvShowImage("image2dxf", target);
cvWaitKey(0);
/* Deallocate resources */
cvReleaseImage(&target);
cvDestroyWindow("image2dxf");
}
/* Write contours to file */
write_contours();
/* Deallocate last resources */
cvReleaseMemStorage(&storage);
}