-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSource.cpp
More file actions
208 lines (158 loc) · 8.72 KB
/
Source.cpp
File metadata and controls
208 lines (158 loc) · 8.72 KB
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
#include <iostream>
#include<cvaux.h>
#include<highgui.h>
#include<cxcore.h>
#include<stdio.h>
#include<stdlib.h>
// Need to include this for serial port communication
#include <Windows.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
try{
// Setup serial port connection and needed variables.
HANDLE hSerial = CreateFile(L"\\\\.\\COM16", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hSerial !=INVALID_HANDLE_VALUE)
{
printf("Port opened! \n");
DCB dcbSerialParams;
GetCommState(hSerial,&dcbSerialParams);
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.Parity = NOPARITY;
dcbSerialParams.StopBits = ONESTOPBIT;
SetCommState(hSerial, &dcbSerialParams);
}
else
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
printf("Serial port doesn't exist! \n");
}
printf("Error while setting up serial port! \n");
}
char outputChars[] = "c";
DWORD btsIO;
// Setup OpenCV variables and structures
CvSize size640x480 = cvSize(640, 480); // use a 640 x 480 size for all windows, also make sure your webcam is set to 640x480 !!
CvCapture* p_capWebcam; // we will assign our web cam video stream to this later . . .
IplImage* p_imgOriginal; // pointer to an image structure, this will be the input image from webcam
IplImage* p_imgProcessed; // pointer to an image structure, this will be the processed image
IplImage* p_imgHSV; // pointer to an image structure, this will hold the image after the color has been changed from RGB to HSV
// IPL is short for Intel Image Processing Library, this is the structure used in OpenCV 1.x to work with images
CvMemStorage* p_strStorage = cvCreateMemStorage(0); // necessary storage variable to pass into cvHoughCircles()
CvSeq* p_seqCircles; // pointer to an OpenCV sequence, will be returned by cvHough Circles() and will contain all circles
// call cvGetSeqElem(p_seqCircles, i) will return a 3 element array of the ith circle (see next variable)
float* p_fltXYRadius; // pointer to a 3 element array of floats
// [0] => x position of detected object
// [1] => y position of detected object
// [2] => radius of detected object
int i; // loop counter
char charCheckForEscKey; // char for checking key press (Esc exits program)
p_capWebcam = cvCaptureFromCAM(0); // 0 => use 1st webcam, may have to change to a different number if you have multiple cameras
if(p_capWebcam == NULL) { // if capture was not successful . . .
printf("error: capture is NULL \n"); // error message to standard out . . .
getchar(); // getchar() to pause for user see message . . .
return(-1); // exit program
}
// declare 2 windows
cvNamedWindow("Original", CV_WINDOW_AUTOSIZE); // original image from webcam
cvNamedWindow("Processed", CV_WINDOW_AUTOSIZE); // the processed image we will use for detecting circles
cvNamedWindow("afterClassification", CV_WINDOW_AUTOSIZE);
p_imgProcessed = cvCreateImage(size640x480, // 640 x 480 pixels (CvSize struct from earlier)
IPL_DEPTH_8U, // 8-bit color depth
1); // 1 channel (grayscale), if this was a color image, use 3
p_imgHSV = cvCreateImage(size640x480, IPL_DEPTH_8U, 3);
// Variables for Arduino Control
int motorPin1 = 3;
int motorPin2 = 4;
// Main program loop
while(1) { // for each frame . . .
p_imgOriginal = cvQueryFrame(p_capWebcam); // get frame from webcam
if(p_imgOriginal == NULL) { // if frame was not captured successfully . . .
printf("error: frame is NULL \n"); // error message to std out
getchar();
break;
}
// Change the color model from RGB (BGR) to HSV. This makes it easier to choose a color based on Hue
cvCvtColor(p_imgOriginal, p_imgHSV, CV_BGR2HSV);
cvInRangeS(p_imgHSV, // function input
cvScalar(20, 180, 150), // min filtering value (if color is greater than or equal to this)
cvScalar(40, 260, 270), // max filtering value (if color is less than this)
p_imgProcessed); // function output
cvShowImage("afterClassification",p_imgProcessed);
// smooth the processed image, this will make it easier for the next function to pick out the circles
cvSmooth(p_imgProcessed, // function input
p_imgProcessed, // function output
CV_GAUSSIAN, // use Gaussian filter (average nearby pixels, with closest pixels weighted more)
9, // smoothing filter window width
9); // smoothing filter window height
// fill sequential structure with all circles in processed image
p_seqCircles = cvHoughCircles(p_imgProcessed, // input image, nothe that this has to be grayscale (no color)
p_strStorage, // provide function with memory storage, makes function return a pointer to a CvSeq
CV_HOUGH_GRADIENT, // two-pass algorithm for detecting circles, this is the only choice available
2, // size of image / 2 = "accumulator resolution", i.e. accum = res = size of image / 2
p_imgProcessed->height / 4, // min distance in pixels between the centers of the detected circles
100, // high threshold of Canny edge detector, called by cvHoughCircles
50, // low threshold of Canny edge detector, called by cvHoughCircles
10, //10 // min circle radius, in pixels
400); // max circle radius, in pixels
// Run this if the camera doesn't detect any circles
// Run this if the camera doesn't detect any circles
// Run this if the camera can see at least one circle
for(i=0; i < p_seqCircles->total; i++) { // for each element in sequential circles structure (i.e. for each object detected)
p_fltXYRadius = (float*)cvGetSeqElem(p_seqCircles, i); // from the sequential structure, read the ith value into a pointer to a float
printf("object position x = %f, y = %f, r = %f \n", p_fltXYRadius[0], // x position of center point of circle
p_fltXYRadius[1], // y position of center point of circle
p_fltXYRadius[2]); // radius of circle
// Reset servo orientation as the camera now has focus of a circle
// Servo orientation is important only when the camera doesn't see a circle
// Check whether camera should turn to its left if the circle gets near the right end of the screen
if (p_fltXYRadius[0] > 540)
{
outputChars[0] = 's';
printf("sending STOP");
WriteFile(hSerial, outputChars, strlen(outputChars), &btsIO, NULL);
}else if (p_fltXYRadius[0] < 100)
{
outputChars[0] = 's';
printf("sending STOP");
WriteFile(hSerial, outputChars, strlen(outputChars), &btsIO, NULL);
}else
{
outputChars[0] = 'c';
printf("sending COntinue reason p_fltXYRadius is %f",p_fltXYRadius[0]);
WriteFile(hSerial, outputChars, strlen(outputChars), &btsIO, NULL);
}
// draw a small green circle at center of detected object
cvCircle(p_imgOriginal, // draw on the original image
cvPoint(cvRound(p_fltXYRadius[0]), cvRound(p_fltXYRadius[1])), // center point of circle
3, // 3 pixel radius of circle
CV_RGB(0,255,0), // draw pure green
CV_FILLED); // thickness, fill in the circle
// draw a red circle around the detected object
cvCircle(p_imgOriginal, // draw on the original image
cvPoint(cvRound(p_fltXYRadius[0]), cvRound(p_fltXYRadius[1])), // center point of circle
cvRound(p_fltXYRadius[2]), // radius of circle in pixels
CV_RGB(255,0,0), // draw pure red
3); // thickness of circle in pixels
} // end for
cvShowImage("Original", p_imgOriginal); // original image with detectec ball overlay
cvShowImage("Processed", p_imgProcessed); // image after processing
charCheckForEscKey = cvWaitKey(10); // delay (in ms), and get key press, if any
if(charCheckForEscKey == 27) break; // if Esc key (ASCII 27) was pressed, jump out of while loop
} // end while
cvReleaseCapture(&p_capWebcam); // release memory as applicable
// cvReleaseMemStorage(&p_strStorage); // deallocate necessary storage variable to pass into cvHoughCircles
cvDestroyWindow("Original");
cvDestroyWindow("Processed");
cvDestroyWindow("afterClassification");
// This closes the Serial Port
CloseHandle(hSerial);
}catch(...)
{
printf("exception");
cvWaitKey(0);
}
return(0);
}