direcs  2012-09-30
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
camThread.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) Markus Knapp *
3  * www.direcs.de *
4  * *
5  * This file is part of direcs. *
6  * *
7  * direcs is free software: you can redistribute it and/or modify it *
8  * under the terms of the GNU General Public License as published *
9  * by the Free Software Foundation, version 3 of the License. *
10  * *
11  * direcs is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with direcs. If not, see <http://www.gnu.org/licenses/>. *
18  * *
19  *************************************************************************/
20 
21 #include "camThread.h"
22 
23 
24 CamThread::CamThread() : QThread()
25 {
26  initDone = false;
27  stopped = false;
28 
29  cameraIsOn = false;
30  faceDetectionIsEnabled = false;
31  faceDetectionWasActive = false;
33 
34  mThreshold = 100;
35 }
36 
37 
39 {
40  stopped = true;
41 
42  // Stops the runloop (if running), cleans up all buffers, unsets callbacks, and flushes queues from the Kinect
43 // freenect_sync_stop();
44 }
45 
46 
48 {
49  stopped = true;
50 }
51 
52 
54 {
55 
56  if (initDone==false)
57  {
58  init();
59  }
60 
61  if (cameraIsOn)
62  {
63  // create an empty image with OpenCV
64  Mat rgbMat(Size(640, 480), CV_8UC3, Scalar(0));
65  Mat rgbMat2(Size(640, 480), CV_8UC3, Scalar(0));
66  Mat rgbMat3(Size(640, 480), CV_8UC3, Scalar(0));
67 
68  // create an empty image with OpenCV
69  Mat depthMat(Size(640, 480), CV_16UC1);
70  Mat depthF (Size(640, 480), CV_8UC1);
71 
72  // show empty image with OpenCV
73  // namedWindow("video");
74 
75  // start "threading"...
76  while (!stopped)
77  {
78 
79  //-----------------
80  // get RGB picture
81  //-----------------
82  freenect_sync_get_video((void**)&data, &timestamp, 0, FREENECT_VIDEO_RGB);
83 
84  // convert image
85  rgbMat.data = (uchar*) data;
86  // cvtColor(rgbMat, rgbMat, CV_RGB2BGR); // only when shown in OpenCV window (there we need BGR)!
87 
88  // refresh image with OpenCV
89  // imshow("video", rgbMat);
90 
91  // convert to QImage
92  qimage = QImage( (uchar*) rgbMat.data, rgbMat.cols, rgbMat.rows, rgbMat.step, QImage::Format_RGB888 );
93 
94  // send RGB image to GUI
95  emit camImageComplete (&qimage);
96 
97 
98  //-------------------
99  // get depth picture
100  //-------------------
101  freenect_sync_get_depth((void**)&dataDepth, &timestamp, 0, FREENECT_DEPTH_10BIT);
102 
103  // convert image
104  depthMat.data = (uchar*) dataDepth;
105 
106  // convert again
107  depthMat.convertTo(depthF, CV_8UC1, 255.0/2048.0);
108  cvtColor( depthF, rgbMat2, CV_GRAY2RGB );
109 
110  // convert to QImage
111  qimageDepth = QImage( (uchar*) rgbMat2.data, rgbMat2.cols, rgbMat2.rows, rgbMat2.step, QImage::Format_RGB888 );
112 
113  // send DEPTH image to GUI
115 
116 
117  //-----------------------------------------
118  // do OpenCV stuff here on the depth image
119  //-----------------------------------------
120  /*
121  // canny
122  //
123  cv::cvtColor(rgbMat, gray, CV_RGB2GRAY);
124  GaussianBlur(gray, gray, Size(5, 5), 2, 2);
125  cv::Canny(gray, gray, 20, 60, 3);
126 
127  vector<Vec4i> lines;
128  HoughLinesP(gray, lines, 1, CV_PI/180, 80, 30, 10);
129 
130  for (size_t i = 0; i < lines.size(); i++)
131  {
132  line(rgbMat, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 2, 8);
133  }
134 
135  // convert to QImage
136  qimage = QImage( (uchar*) rgbMat.data, rgbMat.cols, rgbMat.rows, rgbMat.step, QImage::Format_RGB888 );
137  */
138 
139  // contours
140  //
141  vector<vector<Point> > lines;
142  vector<Vec4i> hierarchy;
143 
144  cvtColor( rgbMat2, gray, CV_BGR2GRAY );
145  threshold( gray, gray, mThreshold, 255, CV_THRESH_BINARY );
146 
147  findContours( gray, lines, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
148  drawContours(gray, lines, -1, Scalar(255, 0, 0), 2);
149 
150  // convert to QImage
151  cvtColor( gray, rgbMat3, CV_GRAY2RGB );
152  qimageOpenCV = QImage( (uchar*) rgbMat3.data, rgbMat3.cols, rgbMat3.rows, rgbMat3.step, QImage::Format_RGB888 );
153 
154  // send OpenCV processed image to GUI
156 
157 
158  // let the thread sleep some time
159  msleep(THREADSLEEPTIME);
160 
161  } // while !stopped
162 
163  } // cameraIsOn
164 
165  stopped = false;
166 }
167 
168 
170 {
171  return cameraIsOn;
172 }
173 
174 
176 {
177  if (state == Qt::Checked)
178  {
179  faceDetectionIsEnabled = true;
180  faceDetectionWasActive = true;
181  }
182  else
183  {
184  faceDetectionIsEnabled = false;
185  }
186 }
187 
188 
189 void CamThread::setCascadePath(QString haarClassifierCascade)
190 {
191  if (haarClassifierCascade == "none")
192  {
193  faceDetectionIsEnabled = false;
194  // disable checkBoxes in the GUI
195  emit disableFaceDetection();
196  }
197 
198 
199  haarClassifierCascadeFilename = haarClassifierCascade;
200 }
201 
202 
204 {
205  double angle = 0;
206 
207 
208  // do only *one* init!
209  if (initDone == false)
210  {
211  initDone = true;
212 
213 
214  // constrain the angle from -30 to +30
215  if (angle > 30)
216  {
217  angle = 30;
218  }
219  else if (angle <-30)
220  {
221  angle=-30;
222  }
223 
224 
225  // try to set angle
226  if (freenect_sync_set_tilt_degs(angle, 0))
227  {
228  emit message("<font color=\"#FF0000\">ERROR: could not initialize Kinect camera.</font>");
229 
230  cameraIsOn = false;
231  stopped = true;
232 
233  return false;
234  }
235 
236  }
237 
238 
239  emit message("Kinect camera initialized.");
240  cameraIsOn = true;
241  stopped = false;
242  return true;
243 }
244 
245 
246 void CamThread::setThreshold(int threshold)
247 {
248  mThreshold = threshold;
249 }