source: pacpussensors/trunk/StereoVisionDisparity/ObstacleDetectionComponent.cpp@ 62

Last change on this file since 62 was 56, checked in by phudelai, 10 years ago

Vision component updated for StereoVision for PointGrey Flea3

File size: 61.4 KB
RevLine 
[53]1/*********************************************************************
2// created: 2013/06/19 - 18:40
3// filename: ObstacleDetectionComponent.cpp
4//
5// author: Danilo Alves de Lima and Students of SY27
6// Copyright Heudiasyc UMR UTC/CNRS 6599
7//
8// version: $Id: $
9//
10// purpose: Obstacle detection from stereo image data
11//
12//
13*********************************************************************/
14//#include "GeneralDefinitions.h"
15
16#include "ObstacleDetectionComponent.h"
17
18#include <iostream>
19#include <string>
20#include "opencv2/calib3d/calib3d.hpp"
21#include "opencv2/core/core.hpp"
22
23#include "Pacpus/kernel/ComponentFactory.h"
24#include "Pacpus/kernel/DbiteException.h"
25#include "Pacpus/kernel/DbiteFileTypes.h"
26#include "Pacpus/kernel/Log.h"
27
28using namespace std;
29using namespace pacpus;
30
31DECLARE_STATIC_LOGGER("pacpus.base.ObstacleDetectionComponent");
32
33// Construct the factory
34static ComponentFactory<ObstacleDetectionComponent> sFactory("ObstacleDetectionComponent");
35
36const int kMaxFilepathLength = 512; // TODO: should be same for all images
37
38static const string ObstacleDetectionMemoryName_ref = "DisparityMap-ref";
39static const string ObstacleDetectionMemoryName_dispin = "DisparityMap-disp";
40
41static const string ObstacleDetectionMemoryName_mask1 = "ObstacleDetection-mask1";
42static const string ObstacleDetectionMemoryName_mask2 = "ObstacleDetection-mask2";
43static const string ObstacleDetectionMemoryName_dispout = "ObstacleDetection-disp";
44
[56]45static const string ObstacleDetectionMemoryName_dispMapNorm = "ObstacleDetection-dispMapNorm";
46static const string ObstacleDetectionMemoryName_result = "ObstacleDetection-result";
47
[53]48//////////////////////////////////////////////////////////////////////////
49/* ComparePoints1
50 Description:
51 Compare if the point 1 if less than 2 by the criteria of the higher y e higher x
52 Parameters:
53 pt1 = point 1
54 pt2 = point 2
55*/
56bool ComparePoints1( cv::Point pt1, cv::Point pt2)
57{
58 /*
59 · Strict: pred(X, X) is always false.
60
61 · Weak: If !pred(X, Y) && !pred(Y, X), X==Y.
62
63 · Ordering: If pred(X, Y) && pred(Y, Z), then pred(X, Z).
64 */
65 if(pt1.y > pt2.y)
66 {
67 return true;
68 }
69 else if((pt1.y == pt2.y)&&(pt1.x >= pt2.x))
70 {
71 return true;
72 }
73 else
74 {
75 return false;
76 }
77}
78
79/// Constructor.
80ObstacleDetectionComponent::ObstacleDetectionComponent(QString name)
81 : ComponentBase(name)
82{
83 LOG_TRACE(Q_FUNC_INFO);
84
85 setRecording(0);
86
87 ANG_VARIATION = 20.0;
88 ANG_VARIATION2 = 7.0;
89
90 this->cam_width = 1280; // Image width
91 this->cam_height = 960; // Image height
92 this->cam_channels = 3;
93 this->showdebug = false; // Show frame acquired
94
95 // Size of the image data sizeof(char)*width*height*channels
96 this->mMaxImageInputSize1 = sizeof(char) * this->cam_width * this->cam_height * this->cam_channels;
97
98 // Input data
99 this->shmem_ref = 0; // Shared memory control access to the image data
100 this->shmem_dispin = 0; // Shared memory control access to the image data
101
102 // Output data
103 this->shmem_mask1 = 0; // Shared memory control access to the image data (free space mask)
104 this->shmem_mask2 = 0; // Shared memory control access to the image data (obstacles mask)
105 this->shmem_dispout = 0; // Shared memory control access to the image data (disparity map)
106}
107
108//////////////////////////////////////////////////////////////////////////
109/// Destructor.
110ObstacleDetectionComponent::~ObstacleDetectionComponent()
111{
112 LOG_TRACE(Q_FUNC_INFO);
113
114 if(this->shmem_ref)
115 delete shmem_ref;
116
117 this->shmem_ref = NULL;
118
119 if(this->shmem_dispin)
120 delete shmem_dispin;
121
122 this->shmem_dispin = NULL;
123
124 if(this->shmem_mask1)
125 delete shmem_mask1;
126
127 this->shmem_mask1 = NULL;
128
129 if(this->shmem_mask2)
130 delete shmem_mask2;
131
132 this->shmem_mask2 = NULL;
133
134 if(this->shmem_dispout)
135 delete shmem_dispout;
136
137 this->shmem_dispout = NULL;
138
[56]139 if(this->shmem_dispMapNormalized)
140 delete shmem_dispMapNormalized;
141
142 this->shmem_dispMapNormalized = NULL;
143
144 if(this->shmem_result)
145 delete shmem_result;
146
147 this->shmem_result = NULL;
[53]148}
149
150//////////////////////////////////////////////////////////////////////////
151/// Called by the ComponentManager to start the component
152void ObstacleDetectionComponent::startActivity()
153{
154 LOG_TRACE(Q_FUNC_INFO);
155
156 this->mMaxImageInputSize1 = sizeof(unsigned char) * this->cam_width * this->cam_height * this->cam_channels;
157 this->mMaxImageInputSize2 = sizeof(unsigned short) * this->cam_width * this->cam_height;
158 this->mMaxImageOutputSize = sizeof(unsigned char) * this->cam_width * this->cam_height;
159
160 this->ref_mem_size = sizeof(TimestampedStructImage) + this->mMaxImageInputSize1;
161 this->dispin_mem_size = sizeof(TimestampedStructImage) + this->mMaxImageInputSize2;
162 this->mask1_mem_size = sizeof(TimestampedStructImage) + this->mMaxImageOutputSize;
163 this->mask2_mem_size = sizeof(TimestampedStructImage) + this->mMaxImageOutputSize;
164 this->dispout_mem_size = sizeof(TimestampedStructImage) + this->mMaxImageInputSize2;
165
166 // Allocate memory position for the maximum expected data
167 this->ref_mem = malloc(this->ref_mem_size);
168 this->dispin_mem = malloc(this->dispin_mem_size);
169 this->mask1_mem = malloc(this->mask1_mem_size);
170 this->mask2_mem = malloc(this->mask2_mem_size);
171 this->dispout_mem = malloc(this->dispout_mem_size);
172
173 this->shmem_ref = new ShMem(ObstacleDetectionMemoryName_ref.c_str(), this->ref_mem_size);
174
175 this->shmem_dispin = new ShMem(ObstacleDetectionMemoryName_dispin.c_str(), this->dispin_mem_size);
176
177 this->shmem_mask1 = new ShMem(ObstacleDetectionMemoryName_mask1.c_str(), this->mask1_mem_size);
178
179 this->shmem_mask2 = new ShMem(ObstacleDetectionMemoryName_mask2.c_str(), this->mask2_mem_size);
180
181 this->shmem_dispout = new ShMem(ObstacleDetectionMemoryName_dispout.c_str(), this->dispout_mem_size);
182
[56]183 this->shmem_dispMapNormalized = new ShMem(ObstacleDetectionMemoryName_dispMapNorm.c_str(), (this->cam_width * this->cam_height));
184
185 this->shmem_result = new ShMem(ObstacleDetectionMemoryName_result.c_str(), (this->cam_width * this->cam_height * 3));
186
[53]187 // Run thread
188 THREAD_ALIVE = true;
189 start();
190}
191
192//////////////////////////////////////////////////////////////////////////
193/// Called by the ComponentManager to stop the component
194void ObstacleDetectionComponent::stopActivity()
195{
196 LOG_TRACE(Q_FUNC_INFO);
197
198 if(THREAD_ALIVE)
199 {
200 // Stop thread
201 THREAD_ALIVE = false;
202
203 while(is_running)
204 {
205 msleep(/*MS_DELAY*/10);
206 }
207
208 if(this->shmem_ref)
209 delete shmem_ref;
210
211 this->shmem_ref = NULL;
212
213 if(this->shmem_dispin)
214 delete shmem_dispin;
215
216 this->shmem_dispin = NULL;
217
218 if(this->shmem_mask1)
219 delete shmem_mask1;
220
221 this->shmem_mask1 = NULL;
222
223 if(this->shmem_mask2)
224 delete shmem_mask2;
225
226 this->shmem_mask2 = NULL;
227
228 if(this->shmem_dispout)
229 delete shmem_dispout;
230
231 this->shmem_dispout = NULL;
232
[56]233 if(this->shmem_dispMapNormalized)
234 delete shmem_dispMapNormalized;
235
236 this->shmem_dispMapNormalized = NULL;
237
238 if(this->shmem_result)
239 delete shmem_result;
240
241 this->shmem_result = NULL;
242
[53]243 // Free the malloc memories
244 free(this->ref_mem);
245 free(this->dispin_mem);
246 free(this->mask1_mem);
247 free(this->mask2_mem);
248 free(this->dispout_mem);
249 }
250
251 LOG_INFO("stopped component '" << name() << "'");
252}
253
254//////////////////////////////////////////////////////////////////////////
255/// Called by the ComponentManager to pass the XML parameters to the
256/// component
257ComponentBase::COMPONENT_CONFIGURATION ObstacleDetectionComponent::configureComponent(XmlComponentConfig config)
258{
259 LOG_TRACE(Q_FUNC_INFO);
260
261 // Initialize with default values
262 InitDefault();
263
264 if (config.getProperty("recording") != QString::null)
265 setRecording(config.getProperty("recording").toInt());
266
267 if (config.getProperty("cam_width") != QString::null)
268 this->cam_width = config.getProperty("cam_width").toInt();
269
270 if (config.getProperty("cam_height") != QString::null)
271 this->cam_height = config.getProperty("cam_height").toInt();
272
273 if (config.getProperty("cam_channels") != QString::null)
274 this->cam_channels = config.getProperty("cam_channels").toInt();
275
276 if (config.getProperty("min_disp") != QString::null)
277 this->min_disp = config.getProperty("min_disp").toInt();
278
279 if (config.getProperty("max_disp") != QString::null)
280 this->max_disp = config.getProperty("max_disp").toInt();
281
282 if (config.getProperty("min_disp_norm") != QString::null)
283 this->min_disp_norm = config.getProperty("min_disp_norm").toInt();
284
285 if (config.getProperty("max_disp_norm") != QString::null)
286 this->max_disp_norm = config.getProperty("max_disp_norm").toInt();
287
288 if (config.getProperty("showdebug") != QString::null)
289 this->showdebug = (bool)config.getProperty("showdebug").toInt();
290
291 if (config.getProperty("destiny_roi_x") != QString::null)
292 this->destiny_roi_x = config.getProperty("destiny_roi_x").toInt();
293
294 if (config.getProperty("destiny_roi_y") != QString::null)
295 this->destiny_roi_y = config.getProperty("destiny_roi_y").toInt();
296
297 if (config.getProperty("destiny_roi_width") != QString::null)
298 this->destiny_roi_width = config.getProperty("destiny_roi_width").toInt();
299
300 if (config.getProperty("destiny_roi_height") != QString::null)
301 this->destiny_roi_height = config.getProperty("destiny_roi_height").toInt();
302
303 if( ((this->destiny_roi_height != this->cam_height)||(this->destiny_roi_width != this->cam_width))&&
304 ((this->destiny_roi_height <= this->cam_height)&&(this->destiny_roi_width <= this->cam_width)) )
305 this->use_roi = true;
306
307 LOG_INFO("configured component '" << name() << "'");
308 return ComponentBase::CONFIGURED_OK;
309}
310
311/**
312* Initialize default values
313*/
314void ObstacleDetectionComponent::InitDefault()
315{
316 // Default
317 this->cam_width = this->destiny_roi_width = 1280; // Image width
318 this->cam_height = this->destiny_roi_height = 960; // Image height
319
320 this->destiny_roi_x = this->destiny_roi_y = 0; // Destiny image roi x and y
321
322 this->use_roi = false;
323 this->min_disp = 0;
324 this->max_disp = 255;
325
326 this->min_disp_norm = 0; // Minimum disparity value to equalize the disp map 16
327 this->max_disp_norm = 255; // Maximum disparity value to equalize the disp map 16
328
329 this->showdebug = false; // Show frame acquired
330}
331
332// Thread loop
333void ObstacleDetectionComponent::run()
334{
335 LOG_TRACE(Q_FUNC_INFO);
336
337 this->is_running = true;
338
339
340 if(this->CurrentReferenceFrame.cols != this->cam_width)
341 {
342 this->CurrentReferenceFrame = cv::Mat(cv::Size(this->cam_width , this->cam_height), CV_MAKETYPE(CV_8U, this->cam_channels));
343 }
344
345 // Create the image in which will be read the disparities
346 if(this->CurrentDisparityMap16.cols != this->cam_width)
347 {
348 this->CurrentDisparityMap16 = cv::Mat( this->cam_height, this->cam_width, CV_16S, cv::Scalar(0) );
349 }
350
351 if(this->CurrentSurfaceMask.cols != this->cam_width)
352 {
353 this->CurrentSurfaceMask = cv::Mat(this->cam_height, this->cam_width, CV_MAKETYPE(CV_8U, 1), cv::Scalar(0) );
354 }
355
356 if(this->CurrentObstaclesMask.cols != this->cam_width)
357 {
358 this->CurrentObstaclesMask = cv::Mat(this->cam_height, this->cam_width, CV_MAKETYPE(CV_8U, 1), cv::Scalar(0) );
359 }
360
361 // Images for type convertion
362 cv::Mat Disp_map = cv::Mat( this->CurrentDisparityMap16.rows, this->CurrentDisparityMap16.cols, CV_8UC1 );
363 cv::Mat Disp_map16;
364
365 // Keeps the last image timestamp;
366 road_time_t last_reading = 0;
367
368 // Initialize the output images header
369 this->Mask1ImageHeader.image.width = this->cam_width;
370 this->Mask1ImageHeader.image.height = this->cam_height;
371 this->Mask1ImageHeader.image.channels = 1;
372 this->Mask1ImageHeader.image.width_step = (size_t)(this->Mask1ImageHeader.image.height * this->Mask1ImageHeader.image.channels);
373 this->Mask1ImageHeader.image.data_size = this->mMaxImageOutputSize;
374
375 this->Mask2ImageHeader.image.width = this->cam_width;
376 this->Mask2ImageHeader.image.height = this->cam_height;
377 this->Mask2ImageHeader.image.channels = 1;
378 this->Mask2ImageHeader.image.width_step = (size_t)(this->Mask2ImageHeader.image.height * this->Mask2ImageHeader.image.channels);
379 this->Mask2ImageHeader.image.data_size = this->mMaxImageOutputSize;
380
381 this->DispOutImageHeader.image.width = this->cam_width;
382 this->DispOutImageHeader.image.height = this->cam_height;
383 this->DispOutImageHeader.image.channels = 1;
384 this->DispOutImageHeader.image.width_step = (size_t)(sizeof(unsigned short)*this->DispOutImageHeader.image.height * this->DispOutImageHeader.image.channels);
385 this->DispOutImageHeader.image.data_size = this->mMaxImageInputSize2;
386
387 // Time measurement
388 road_time_t init_time = 0;
389
390 while (THREAD_ALIVE)
391 {
392 init_time = road_time();
393
394 //LOG_INFO("Grab new image");
395 // header + image
396 this->shmem_ref->read(this->ref_mem, this->ref_mem_size);
397 this->shmem_dispin->read(this->dispin_mem, this->dispin_mem_size);
398
399 // Header
400 memcpy( &this->RefImageHeader, this->ref_mem, sizeof(TimestampedStructImage));
401 memcpy( &this->DispInImageHeader, this->dispin_mem, sizeof(TimestampedStructImage));
402
403 // Check image header
404 bool is_ok = false;
405 if( (this->RefImageHeader.image.data_size == this->mMaxImageInputSize1) && (this->RefImageHeader.time != last_reading) &&
406 (this->DispInImageHeader.image.data_size == this->mMaxImageInputSize2) && (this->DispInImageHeader.time == this->RefImageHeader.time) )
407 {
408 is_ok = true;
409 last_reading = this->RefImageHeader.time;
410
411 /*std::cout << "Expected image w: " << ImageHeader.image.width << std::endl;
412 std::cout << "Expected image h: " << ImageHeader.image.height << std::endl;
413 std::cout << "Expected image c: " << ImageHeader.image.channels << std::endl;
414 std::cout << "Expected image data: " << ImageHeader.image.data_size << std::endl;
415 std::cout << "Expected image size: " << image_mem << std::endl;*/
416 }
417 /*else
418 {
419 LOG_ERROR("Error in the image data size!");
420 }*/
421
422 if(is_ok)
423 {
424 // Image data
425 memcpy( (unsigned char*)(this->CurrentReferenceFrame.data), (unsigned char*)((TimestampedStructImage*)this->ref_mem + 1), this->RefImageHeader.image.data_size);
426 memcpy( (unsigned short*)(this->CurrentDisparityMap16.data), (unsigned short*)((TimestampedStructImage*)this->dispin_mem + 1), this->DispInImageHeader.image.data_size);
427
428 if(this->showdebug)
429 {
430 cv::namedWindow( "ObstacleDetectionComponent - Current Reference Frame", CV_WINDOW_NORMAL );
431 cv::imshow("ObstacleDetectionComponent - Current Reference Frame",this->CurrentReferenceFrame);
432 cv::waitKey(1);
433 }
434
435 //============================================= Obstacle Detection ================================================
436
437 cv::Mat v_disp_map, u_disp_map;
438
439 cv::Mat roi_disp = (this->use_roi) ? this->CurrentDisparityMap16(cv::Rect(this->destiny_roi_x, this->destiny_roi_y, this->destiny_roi_width, this->destiny_roi_height)) :
440 this->CurrentDisparityMap16;
441
442 // U/V disparity maps calculation
443 this->CalcUVDisparityMapNorm(roi_disp, v_disp_map, u_disp_map, Disp_map, this->min_disp_norm, this->max_disp_norm);
444
445 /*
446 // Real disparity information
447 Disp_map16 = this->CurrentDisparityMap16/16;
448
449 // Display it as a CV_8UC1 image
450 Disp_map16.convertTo( Disp_map, CV_8UC1);//, double(255)/double(this->max_disp - this->min_disp));
451
452 if(this->showdebug)
453 {
454 cv::namedWindow( "ObstacleDetectionComponent - Current Disparity Map", CV_WINDOW_AUTOSIZE );
455 cv::imshow("ObstacleDetectionComponent - Current Disparity Map", Disp_map);
456 cv::waitKey(1);
457 }
458
459 // U/V disparity maps calculation
460 std::pair<cv::Mat,cv::Mat> par_uv = this->CalcUVDisparityMap(Disp_map);
461 cv::Mat v_disp_map = par_uv.second;
462
463 cv::Mat u_disp_map = par_uv.first;
464 */
465
466 if(this->showdebug)
467 {
468 cv::namedWindow( "ObstacleDetectionComponent - Current V Disparity Map", CV_WINDOW_AUTOSIZE );
469 cv::imshow("ObstacleDetectionComponent - Current V Disparity Map", v_disp_map);
470
471 cv::namedWindow( "ObstacleDetectionComponent - Current U Disparity Map", CV_WINDOW_AUTOSIZE );
472 cv::imshow("ObstacleDetectionComponent - Current U Disparity Map", u_disp_map);
473
474 cv::namedWindow( "ObstacleDetectionComponent - Current Disparity Map Normalized", CV_WINDOW_AUTOSIZE );
475 cv::imshow("ObstacleDetectionComponent - Current Disparity Map Normalized", Disp_map);
476 cv::waitKey(1);
477 }
478
[56]479 //memcpy(this->dispMapNorm_mem, &this->dispMapNormImageHeader, sizeof(TimestampedStructImage));
480 //memcpy((void*)((TimestampedStructImage*)this->dispMapNorm_mem + 1), (void*)Disp_map.data, this->dispMapNormImageHeader.image.data_size);
481 this->shmem_dispMapNormalized->write((void*)Disp_map.data, (this->cam_width * this->destiny_roi_height));
482
[53]483 // Image to detect near obstacles
484 cv::Mat v_disp_map2 = v_disp_map.clone();
485
486 // Find the driveable surface
487 //cv::Mat color_v_disp_map1 = this->FindSurface(v_disp_map, v_disp_map2);
488 cv::Mat color_v_disp_map1 = this->FindSurface2(v_disp_map, v_disp_map2);
489
490 // Find near obstacles
491 //cv::Mat color_v_disp_map2 = this->FindNearObstacles(v_disp_map2, this->min_disp, this->max_disp);
492 std::pair<cv::Mat, cv::Mat> color_uv_disp_map = this->FindNearObstaclesUV(v_disp_map2, u_disp_map, this->min_disp, this->max_disp);
493
494 if(this->showdebug)
495 {
496 cv::namedWindow("ObstacleDetectionComponent - Mapa de Disparidade V + Free Space",CV_WINDOW_AUTOSIZE);
497 cv::imshow("ObstacleDetectionComponent - Mapa de Disparidade V + Free Space", color_v_disp_map1);
498
499 cv::namedWindow("ObstacleDetectionComponent - Mapa de Disparidade V + Obstacles",CV_WINDOW_AUTOSIZE);
500 cv::imshow("ObstacleDetectionComponent - Mapa de Disparidade V + Obstacles", color_uv_disp_map.first);
501
502 cv::namedWindow("ObstacleDetectionComponent - Mapa de Disparidade U + Obstacles",CV_WINDOW_AUTOSIZE);
503 cv::imshow("ObstacleDetectionComponent - Mapa de Disparidade U + Obstacles", color_uv_disp_map.second);
504 cv::waitKey(1);
505 }
506
507 // Remap the v-disparity point in the original image and create binary masks
508 //std::pair<cv::Mat, cv::Mat> masks = this->MaskSurface2(Disp_map, color_v_disp_map1, color_uv_disp_map.first, this->min_disp, this->max_disp, 1);
509 std::pair<cv::Mat, cv::Mat> masks = this->MaskSurface3(Disp_map, color_v_disp_map1, color_uv_disp_map.first, color_uv_disp_map.second, this->min_disp, this->max_disp, 1);
510
511 /*if(this->showdebug)
512 {
513 cv::namedWindow("Mapa de Disparidade V + Mask1",CV_WINDOW_AUTOSIZE);
514 cv::imshow("Mapa de Disparidade V + Mask1", masks.first*255);
515
516 cv::namedWindow("Mapa de Disparidade V + Mask2",CV_WINDOW_AUTOSIZE);
517 cv::imshow("Mapa de Disparidade V + Mask2", masks.second*255);
518 }*/
519
520 //---------------------- Remove commun information -------------------------
521
522 masks.second = masks.second - masks.second.mul( masks.first);
523
524 //---------------------------------------------------------------------------
525
526 //------------------ Write the result in the shared memory ------------------
527
528 if(this->use_roi)
529 {
530 masks.first.copyTo(this->CurrentSurfaceMask(cv::Rect(this->destiny_roi_x, this->destiny_roi_y, this->destiny_roi_width, this->destiny_roi_height)));
531 masks.second.copyTo(this->CurrentObstaclesMask(cv::Rect(this->destiny_roi_x, this->destiny_roi_y, this->destiny_roi_width, this->destiny_roi_height)));
532 }
533 else
534 {
535 this->CurrentSurfaceMask = masks.first;
536 this->CurrentObstaclesMask = masks.second;
537 }
538
539 //----------------------------- Mask 1 --------------------------------------
540 // Complete timestamp header of the mask image 1
541 this->Mask1ImageHeader.time = this->DispInImageHeader.time;
542 this->Mask1ImageHeader.timerange = this->DispInImageHeader.timerange;
543
544 // Copy images header and data to memory
545 memcpy(this->mask1_mem, &this->Mask1ImageHeader, sizeof(TimestampedStructImage));
546 memcpy((void*)((TimestampedStructImage*)this->mask1_mem + 1), (void*)this->CurrentSurfaceMask.data, this->Mask1ImageHeader.image.data_size);
547 this->shmem_mask1->write(this->mask1_mem, this->mask1_mem_size);
548
549 //----------------------------- Mask 2 --------------------------------------
550 // Complete timestamp header of the mask image 2
551 this->Mask2ImageHeader.time = this->DispInImageHeader.time;
552 this->Mask2ImageHeader.timerange = this->DispInImageHeader.timerange;
553
554 // Copy images header and data to memory
555 memcpy(this->mask2_mem, &this->Mask2ImageHeader, sizeof(TimestampedStructImage));
556 memcpy((void*)((TimestampedStructImage*)this->mask2_mem + 1), (void*)this->CurrentObstaclesMask.data, this->Mask2ImageHeader.image.data_size);
557 this->shmem_mask2->write(this->mask2_mem, this->mask2_mem_size);
558
559 //------------------------- Disparity map out -------------------------------
560 // Complete timestamp header of the disp image out
561 this->DispOutImageHeader.time = this->DispInImageHeader.time;
562 this->DispOutImageHeader.timerange = this->DispInImageHeader.timerange;
563
564 // Copy images header and data to memory
565 memcpy(this->dispout_mem, &this->DispOutImageHeader, sizeof(TimestampedStructImage));
566 memcpy((void*)((TimestampedStructImage*)this->dispout_mem + 1), (void*)this->CurrentDisparityMap16.data, this->DispOutImageHeader.image.data_size);
567 this->shmem_dispout->write(this->dispout_mem, this->dispout_mem_size);
568 //---------------------------------------------------------------------------
569
570 // ----------------- Apply the mask in the reference image ------------------
[56]571
572 std::vector<cv::Mat> channels(3);
573 cv::Mat reference;
574 if(this->cam_channels == 1)
[53]575 {
[56]576 cv::cvtColor((this->CurrentReferenceFrame(cv::Rect(this->destiny_roi_x, this->destiny_roi_y, this->destiny_roi_width, this->destiny_roi_height))).clone(), reference, CV_GRAY2BGR);
577 }
578 else
579 {
580 reference = (this->CurrentReferenceFrame(cv::Rect(this->destiny_roi_x, this->destiny_roi_y, this->destiny_roi_width, this->destiny_roi_height))).clone();
581 }
[53]582
[56]583 cv::split(reference, channels);
[53]584
[56]585 masks.second = 1 - masks.second;
586 channels[1] = masks.second.mul(channels[0]); // Activate the red color as obstacles
587 channels[2] = masks.second.mul(channels[1]); // Activate the red color as obstacles
[53]588
[56]589 //masks.second = masks.second - masks.first;
590 //channels[0] = (1 - masks.second).mul(channels[0]); // Activate the yellow color for unclassified area
591
592 cv::merge(channels, reference);
[53]593
[56]594 this->shmem_result->write((void*)reference.data, (this->destiny_roi_width * this->destiny_roi_height * 3));
[53]595
[56]596 if(this->showdebug)
597 {
598 cv::namedWindow("ObstacleDetectionComponent - Final Classification", CV_WINDOW_AUTOSIZE);
[53]599 cv::imshow("ObstacleDetectionComponent - Final Classification", reference);
600 }
601 //---------------------------------------------------------------------------
602
603 //==================================================================================================================
604
605 //std::cout << componentName.toStdString() << " cicle time: " << (road_time() - init_time)/1000000.0 << std::endl;
606 }
607 else
608 {
609 msleep(/*MS_DELAY*/10);
610 }
611
612 if(this->showdebug)
613 cv::waitKey(1); // Give the system permission
614
615 //std::cout << componentName.toStdString() << " cicle time: " << (road_time() - init_time)/1000000.0 << std::endl;
616 }
617
618 this->is_running = false;
619
620 // Destroy the window frame
621 if(this->showdebug)
622 cvDestroyAllWindows();
623}
624
625// Function to calculate the U/V disparity map
626std::pair<cv::Mat, cv::Mat> ObstacleDetectionComponent::CalcUVDisparityMap(cv::Mat disp_map)
627{
628 int l, c, pixel; // local variables for row, line and pixel
629 unsigned char intensity; // pixel intensity
630
631 unsigned char* ptr1; // row pointer for 8 bits image
632 //unsigned short* ptr2; // row pointer for 16 bits image
633
634 // U disparity map iamge
635 cv::Mat u_disp = cv::Mat::zeros(cv::Size(disp_map.cols, 256), CV_8UC1);
636
637 // V disparity map image
638 cv::Mat v_disp = cv::Mat::zeros(cv::Size(256, disp_map.rows), CV_8UC1);
639
640 // run accross the image and add 1 to the respective U/V disparity column
641 for (l = 0; l < disp_map.rows; ++l)
642 {
643 ptr1 = disp_map.ptr<unsigned char>(l);
644
645 for (c = 0; c < disp_map.cols; ++c)
646 {
647 intensity = (unsigned char)ptr1[c];
648
649 if( (intensity > this->min_disp)&&(intensity < this->max_disp))
650 {
651 pixel = intensity*u_disp.cols + c;
652 u_disp.data[pixel] = (unsigned char)(u_disp.data[pixel] + 1);
653
654 pixel = l*v_disp.cols + intensity;
655 v_disp.data[pixel] = (unsigned char)(v_disp.data[pixel] + 1);
656 }
657 }
658 }
659
660 return std::make_pair(u_disp, v_disp);
661}
662
663/* CalcUVDisparityMapNorm
664 Description:
665 Function to calculate the U/V disparity map from a disp map normalized
666 Parameters:
667 disp_map16 = original disparity map 16
668 disp_map_norm = resulted disparity map normalized
669 min_d_norm = Minimum disparity value to equalize the disp map 16
670 max_d_norm = Maximum disparity value to equalize the disp map 16
671*/
672void ObstacleDetectionComponent::CalcUVDisparityMapNorm(cv::Mat disp_map16, cv::Mat &v_disp_map, cv::Mat &u_disp_map, cv::Mat &disp_map_norm, int min_d_norm, int max_d_norm)
673{
674 int l, c, pixel; // local variables for row, line and pixel
675 unsigned char intensity; // pixel intensity
676 int intensity_norm; // pixel intensity
677
678 unsigned char* ptr1; // row pointer for 8 bits image
679 unsigned short* ptr2; // row pointer for 16 bits image
680
681 // Disparity map image normalized
682 disp_map_norm = cv::Mat::zeros(cv::Size(disp_map16.cols, disp_map16.rows), CV_8UC1);
683
684 // U disparity map image
685 u_disp_map = cv::Mat::zeros(cv::Size(disp_map16.cols, 256), CV_8UC1);
686
687 // V disparity map image
688 v_disp_map = cv::Mat::zeros(cv::Size(256, disp_map16.rows), CV_8UC1);
689
690 // percorre a imagem original e soma 1 na coluna do mapa de disparidade V com a mesma
691 // intensidade do pixel
692 for (l = 0; l < disp_map16.rows; ++l)
693 {
694 ptr1 = disp_map_norm.ptr<unsigned char>(l);
695 ptr2 = disp_map16.ptr<unsigned short>(l);
696
697 for (c = 0; c < disp_map16.cols; ++c)
698 {
699 intensity = (unsigned char)(ptr2[c]/16);
700 intensity_norm = (int)((float)((ptr2[c]/16.0f - (float)min_d_norm)*(255.0f)/((float)max_d_norm - (float)min_d_norm)) + 0.5f);
701
702 if( (intensity > this->min_disp)&&(intensity < this->max_disp)&&(intensity_norm > 0)&&(intensity_norm < 255))
703 {
704 pixel = intensity_norm*u_disp_map.cols + c;
705 u_disp_map.data[pixel] = (unsigned char)(u_disp_map.data[pixel] + 1);
706
707 pixel = l*v_disp_map.cols + intensity_norm;
708 v_disp_map.data[pixel] = (unsigned char)(v_disp_map.data[pixel] + 1);
709
710 ptr1[c] = (unsigned char)intensity_norm;
711 }
712 }
713 }
714
715 return;
716}
717
718// Function to find the free space surface from a V-disparity map
719cv::Mat ObstacleDetectionComponent::FindSurface(cv::Mat &v_disp_map, cv::Mat &v_disp_map2)
720{
721 // Parameters of canny and hough transform
722 int tshold1 = 154;
723 int tshold2 = 48;
724 int n_points = 48; //59
725 int minLineLenght = 35; //40
726 int maxLineGap = 12;
727
728
729 // Binary image
730 cv::Mat Img_bin = v_disp_map.clone();//cvCloneImage(v_disp_map);
731
732 // Color V disparity map with red lines
733 cv::Mat color_img = cv::Mat( cv::Size(v_disp_map.cols, v_disp_map.rows), CV_8UC3 );
734
735 // Convert to color image
736 cv::cvtColor(v_disp_map, color_img, CV_GRAY2BGR);
737
738 cv::equalizeHist( Img_bin, Img_bin);
739
740 if(this->showdebug)
741 {
742 // Janela de exibicao
743 cv::namedWindow("ObstacleDetectionComponent - Equalized Image",CV_WINDOW_AUTOSIZE);
744 cv::imshow("ObstacleDetectionComponent - Equalized Image", Img_bin);
745 }
746
747 cv::Canny(Img_bin, Img_bin, tshold1, tshold2, 3);
748
749 // Closing
750 //cv::dilate(Img_bin, Img_bin, cv::Mat(), cv::Point(-1,-1), 2 );
751 //cv::erode(Img_bin, Img_bin, cv::Mat(), cv::Point(-1,-1), 1 );
752
753 if(this->showdebug)
754 {
755 // Janela de exibicao
756 cv::namedWindow("ObstacleDetectionComponent - Binary Image",CV_WINDOW_AUTOSIZE);
757 cv::imshow("ObstacleDetectionComponent - Binary Image", Img_bin);
758 }
759
760 std::vector<cv::Vec4i> lines; //vector for storing the lines found by HoughLine
761
762 // Probabilistic Hough Transform
763 cv::HoughLinesP( Img_bin, lines, 1, CV_PI/180, n_points, minLineLenght, maxLineGap );
764
765 //=============================== Use the lines filter to remove invalid segments ============================
766
767 std::vector<cv::Point> nova_lista = this->LinesFiltering(lines);
768
769 if(!nova_lista.empty())
770 {
771 cv::Point pt_ant = *(nova_lista.begin());
772
773 // Filter the mean angle
774 for(std::vector<cv::Point>::iterator it = nova_lista.begin(); it != nova_lista.end(); ++it)
775 {
776 cv::line( color_img, pt_ant, *it, CV_RGB(255,0,0), 8, 8 );
777
778 pt_ant = *it;
779 }
780 }
781
782 //============================================================================================================
783
784 //======================== Remove invalid line segments by slope angle only ==================================
785 //if (lines.size() != 0)
786 //{
787 // cv::Point pt1, pt2;
788 // double theta;
789
790 // for(int i = 0; i < (int)lines.size();++i)
791 // {
792 // pt1.x = lines[i][0];//(CvPoint*)cvGetSeqElem(lines,i);
793 // pt1.y = lines[i][1];
794 // pt2.x = lines[i][2];
795 // pt2.y = lines[i][3];
796
797 // CheckPoints(pt1, pt2); //Verifica a ordem dos pontos
798 //
799 // theta = Inclination(pt1, pt2); //calcula a inclinacao da reta encontrada
800
801 // // Valor atual do angulo em graus
802 // theta = ((theta*360.0)/(2.0*CV_PI));
803
804 // // Verifica se a reta possui inclinacao para ser possivel plano
805 // if(theta> (90.0 + ANG_VARIATION))
806 // {
807
808 // //Desenha as retas em vermelho
809 // cv::line( color_img, pt1, pt2, CV_RGB(255,0,0), 4, 8 );
810 // }
811 // }
812 //}
813 //==========================================================================================================
814
815 std::vector<cv::Mat> channels(3);
816
817 // Get the V-disparity without detected red lines
818 cv::split(color_img, channels);
819 v_disp_map2 = channels[0];
820
821 // Janela de exibicao
822 //cv::namedWindow("Mapa de Disparidade V + Hough",CV_WINDOW_AUTOSIZE);
823 //cv::imshow("Mapa de Disparidade V + Hough", color_img);
824 //cv::imshow("Mapa de Disparidade V + Hough", v_disp_map2);
825
826 return color_img;
827}
828
829/* FindSurface2
830 Description:
831 Function to find the free space surface from a V-disparity map, based on the frontal plane.
832 Return the V-dysparity map with the red line representing the free surface.
833 Parameters:
834 v_disp_map = Original V-disparity map
835 v_disp_map2 = Orignal V-disparity map less the surface detected
836*/
837cv::Mat ObstacleDetectionComponent::FindSurface2(cv::Mat &v_disp_map, cv::Mat &v_disp_map2)
838{
839 // Parameters
840 int tshold = 40; // Min threshold for the first max value
841 int tshold2 = 35; // Min threshold for the step variation
842 int maxLineLenght = 25;
843 int min_disp_value = 20;
844
845 // Binary image
846 cv::Mat Img_bin = v_disp_map.clone();
847 cv::Mat Img_mask = v_disp_map.clone();
848
849 // Color V disparity map with red lines
850 cv::Mat color_img = cv::Mat( cv::Size(v_disp_map.cols, v_disp_map.rows), CV_8UC3 );
851
852 // Convert to color image
853 cv::cvtColor(v_disp_map, color_img, CV_GRAY2BGR);
854
855
856 //================= Segment the most probable road surface region ===================================
857 /*cv::threshold(Img_mask, Img_mask, tshold, 1, CV_THRESH_BINARY);
858 cv::dilate(Img_mask, Img_mask, cv::Mat(), cv::Point(-1,-1), 2 );
859 cv::erode(Img_mask, Img_mask, cv::Mat(), cv::Point(-1,-1), 1 );
860
861 if(this->showdebug)
862 {
863 cv::imshow( "ObstacleDetectionComponent - Img_mask", Img_mask*255 );
864 }
865
866 Img_bin = Img_bin.mul(Img_mask);*/
867 //===================================================================================================
868
869 // Generate grad_x and grad_y
870 cv::Mat grad, grad_H, grad_S, grad_x, grad_y;
871 cv::Mat abs_grad_x, abs_grad_y;
872
873 // Gradient X
874 //Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
875 //cv::Sobel( Img_bin, grad_x, CV_16S, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT );
876 //cv::convertScaleAbs( grad_x, abs_grad_x );
877
878 // Gradient Y
879 //Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
880 cv::Sobel( Img_bin, grad_y, CV_16S, 0, 1, 3, 1, 0, cv::BORDER_DEFAULT );
881 cv::convertScaleAbs( grad_y, abs_grad_y );
882
883 // Total Gradient (approximate)
884 //cv::addWeighted( abs_grad_x, 0.2, abs_grad_y, 0.8, 0, grad );
885
886 //abs_grad_y = abs_grad_y*255.0;
887 abs_grad_y.convertTo(Img_mask, CV_8U);
888
889 cv::threshold(Img_mask, Img_mask, tshold2, 1, CV_THRESH_BINARY);
890 cv::dilate(Img_mask, Img_mask, cv::Mat(), cv::Point(-1,-1), 2 );
891 cv::erode(Img_mask, Img_mask, cv::Mat(), cv::Point(-1,-1), 1 );
892
893 Img_bin = Img_bin.mul(Img_mask);
894
895 //cv::equalizeHist( abs_grad_y, Img_bin);
896
897 if(this->showdebug)
898 {
899 //cv::imshow( "ObstacleDetectionComponent - Sobel X", abs_grad_x );
900 cv::imshow( "ObstacleDetectionComponent - Sobel Y", abs_grad_y );
901 cv::imshow( "ObstacleDetectionComponent - Img_mask", Img_mask*255 );
902 //cv::imshow( "ObstacleDetectionComponent - Sobel", grad );
903 //cv::imshow( "ObstacleDetectionComponent - Equalized Image", Img_bin);
904 }
905
906 //============================== Mark the most significative points as free space ==============================
907
908 int row_step_count, last_row_step_count; // Keep the sum of the last valid pixels in the step
909 int previous_col = 0;
910
911 int left_limit, right_limit; // Auxiliary variables
912
913 for(int row = Img_bin.rows - 1; row > 0; --row)
914 {
915 row_step_count = 0;
916 last_row_step_count = 0;
917 left_limit = -1;
918 right_limit = -1;
919
920 unsigned char* ptr1 = Img_bin.ptr<unsigned char>(row);
921
922 if(previous_col == 0)
923 {
924 for(int col = 0; col < Img_bin.cols; ++col)
925 {
926 // Find max
927 if(ptr1[previous_col] < ptr1[col])
928 {
929 previous_col = col;
930
931 tshold2 = (int)(0.95*ptr1[previous_col]); // adjust the tshold
932 }
933 }
934
935 if(ptr1[previous_col] < tshold)
936 {
937 previous_col = 0; // position
938 }
939 }
940
941 if(previous_col != 0)
942 {
943 int left = (previous_col - maxLineLenght >= 0) ? previous_col-maxLineLenght : 0;
944 int right = (previous_col + maxLineLenght < Img_bin.cols) ? previous_col + maxLineLenght : Img_bin.cols;
945
946 int limits_found = 0;
947 int l_col = previous_col;
948 int r_col = previous_col;
949
950 int left_count = 0;
951 int right_count = 0;
952
953 while(!limits_found)
954 {
955 //------------------------------- To the left ----------------------------------
956 if(left_limit == -1)
957 {
958 if(l_col > left)
959 --l_col;
960 else
961 left_limit = l_col + left_count;
962 }
963
964 // Find max
965 if(ptr1[previous_col] < ptr1[l_col])
966 {
967 previous_col = l_col;
968 tshold2 = (int)(0.95*ptr1[previous_col]); // adjust the tshold
969 }
970
971 // Check if the pixel intensity is lower than tshold
972 if(left_count < 5)
973 {
974 if(ptr1[l_col] < tshold2)
975 {
976 ++left_count;
977 }
978 else
979 {
980 left_count = 0;
981 }
982 }
983 else
984 {
985 if(left_limit == -1)
986 left_limit = l_col + left_count;
987 }
988 //------------------------------------------------------------------------------
989
990 //------------------------------- To the right ----------------------------------
991 if(right_limit == -1)
992 {
993 if(r_col < right)
994 ++r_col;
995 else
996 right_limit = r_col - right_count;
997 }
998
999 // Find max
1000 if(ptr1[previous_col] < ptr1[r_col])
1001 {
1002 previous_col = r_col;
1003 tshold2 = (int)(0.95*ptr1[previous_col]); // adjust the tshold
1004 }
1005
1006 // Check if the pixel intensity is lower than tshold
1007 if(right_count < 5)
1008 {
1009 if(ptr1[r_col] < tshold2)
1010 {
1011 ++right_count;
1012 }
1013 else
1014 {
1015 right_count = 0;
1016 }
1017 }
1018 else
1019 {
1020 if(right_limit == -1)
1021 right_limit = r_col - right_count;
1022 }
1023 //------------------------------------------------------------------------------
1024
1025 if((left_limit != -1)&&(right_limit != -1))
1026 {
1027 limits_found = 1;
1028 }
1029 }
1030
1031 if((left_limit != -1)&&(right_limit != -1)&&(ptr1[previous_col] > tshold2))
1032 {
1033 cv::line( color_img, cv::Point(left_limit, row), cv::Point(right_limit, row), CV_RGB(255,0,0), 1, 8 );
1034 }
1035 }
1036 }
1037
1038 //==============================================================================================================
1039
1040 std::vector<cv::Mat> channels(3);
1041
1042 // Get the V-disparity without detected red lines
1043 cv::split(color_img, channels);
1044 v_disp_map2 = channels[0];
1045
1046 // Janela de exibicao
1047 //cv::namedWindow("Mapa de Disparidade V + Hough",CV_WINDOW_AUTOSIZE);
1048 //cv::imshow("Mapa de Disparidade V + Hough", color_img);
1049 //cv::imshow("Mapa de Disparidade V + Hough", v_disp_map2);
1050
1051 return color_img;
1052}
1053
1054// Function to find the free space surface from a V-disparity map with mean average
1055cv::Mat ObstacleDetectionComponent::FindAverageSurface(cv::Mat &v_disp_map, cv::Mat &v_disp_map2)
1056{
1057 // Parameters of threshold and hough transform
1058 int tshold1 = 3;
1059 int n_points = 48; //59
1060 int minLineLenght = 35; //40
1061 int maxLineGap = 12;
1062
1063 // Imagem atual em 32F
1064 cv::Mat v_disp_map_current32F = cv::Mat(cv::Size(v_disp_map.cols, v_disp_map.rows), CV_32F, 1);
1065
1066 // Converte tipo de imagem
1067 v_disp_map.convertTo(v_disp_map_current32F, CV_32F);//cvConvertScale(v_disp_map, v_disp_map_current32F);
1068
1069 //Mean disparity map for noise attenuation
1070 static cv::Mat v_disp_map_mean = v_disp_map_current32F.clone();
1071
1072 // Imagem binária da diferenca
1073 cv::Mat ImgBinaria = v_disp_map.clone();//cvCloneImage(v_disp_map);
1074
1075 // Color V disparity map with red lines
1076 cv::Mat color_img = cv::Mat( cv::Size(v_disp_map.cols, v_disp_map.rows), CV_8UC3 );
1077
1078 // Convert to color image
1079 cv::cvtColor(v_disp_map, color_img, CV_GRAY2BGR);
1080
1081 // Running Average
1082 cv::accumulateWeighted(v_disp_map_current32F, v_disp_map_mean, 0.20);//cvRunningAvg(v_disp_map_current32F, v_disp_map_mean, 0.20);
1083
1084 // Convert scale
1085 v_disp_map_mean.convertTo( ImgBinaria, CV_8U); //cvConvertScale(v_disp_map_mean, ImgBinaria, 1.0, 0.0);
1086
1087 // Janela de exibicao
1088 //cv::namedWindow("Imagem Media Movel",CV_WINDOW_AUTOSIZE);
1089 //cv::imshow("Imagem Media Movel", ImgBinaria);
1090
1091 cv::threshold(ImgBinaria, ImgBinaria, tshold1, 255,CV_THRESH_BINARY);
1092
1093 // Janela de exibicao
1094 //cv::namedWindow("Mapa de Disparidade V + binarizacao",CV_WINDOW_AUTOSIZE);
1095 //cv::imshow("Mapa de Disparidade V + binarizacao", ImgBinaria);
1096
1097 // create 3x3 matrix
1098 //static cv::Mat kernel_3x3 = (cv::Mat_<unsigned char>(3,3) << 1, 0, 0, 1, 1, 0, 1, 1, 1);
1099
1100 // Fechamento
1101 //cv::erode(ImgBinaria,ImgBinaria,NULL, cv::Point(-1,-1), 1);
1102 //cv::erode(ImgBinaria,ImgBinaria,kernel_3x3, cv::Point(1,1), 1);
1103
1104 // Janela de exibicao
1105 //cv::namedWindow("Mapa de Disparidade V + binarizacao + erode",CV_WINDOW_AUTOSIZE);
1106 //cv::imshow("Mapa de Disparidade V + binarizacao + erode", ImgBinaria);
1107
1108 // Fechamento
1109 //cv::dilate(ImgBinaria,ImgBinaria,NULL, cv::Point(-1,-1), 1);
1110 //cv::erode(ImgBinaria,ImgBinaria,NULL, cv::Point(-1,-1), 2);
1111
1112 std::vector<cv::Vec4i> lines; //vector for storing the lines found by HoughLine
1113
1114 // Probabilistic Hough Transform
1115 cv::HoughLinesP( ImgBinaria, lines, 1, CV_PI/180, n_points, minLineLenght, maxLineGap );
1116
1117 //=============================== Use the lines filter to remove invalid segments ============================
1118
1119 //std::vector<cv::Point> nova_lista = this->LinesFiltering(lines);
1120 //
1121 //if(!nova_lista.empty())
1122 //{
1123 // cv::Point pt_ant = *(nova_lista.begin());
1124
1125 // // Filter the mean angle
1126 // for(std::vector<cv::Point>::iterator it = nova_lista.begin(); it != nova_lista.end(); ++it)
1127 // {
1128 // cv::line( color_img, pt_ant, *it, CV_RGB(255,0,0), 3, 8 );
1129
1130 // pt_ant = *it;
1131 // }
1132 //}
1133
1134 //============================================================================================================
1135
1136 //======================== Remove invalid line segments by slope angle only ==================================
1137 if (lines.size() != 0)
1138 {
1139 cv::Point pt1, pt2;
1140 double theta;
1141
1142 for(int i = 0; i < (int)lines.size();++i)
1143 {
1144 pt1.x = lines[i][0];//(CvPoint*)cvGetSeqElem(lines,i);
1145 pt1.y = lines[i][1];
1146 pt2.x = lines[i][2];
1147 pt2.y = lines[i][3];
1148
1149 CheckPoints(pt1, pt2); //Verifica a ordem dos pontos
1150
1151 theta = Inclination(pt1, pt2); //calcula a inclinacao da reta encontrada
1152
1153 // Valor atual do angulo em graus
1154 theta = ((theta*360.0)/(2.0*CV_PI));
1155
1156 // Verifica se a reta possui inclinacao para ser possivel plano
1157 if(theta> (90.0 + ANG_VARIATION))
1158 {
1159
1160 //Desenha as retas em vermelho
1161 cv::line( color_img, pt1, pt2, CV_RGB(255,0,0), 6, 8 );
1162 }
1163 }
1164 }
1165 //==========================================================================================================
1166
1167 std::vector<cv::Mat> channels(3);
1168
1169 // Get the V-disparity without detected red lines
1170 cv::split(color_img, channels);
1171 v_disp_map2 = channels[0];
1172
1173 // Janela de exibicao
1174 //cv::namedWindow("Mapa de Disparidade V + Hough",CV_WINDOW_AUTOSIZE);
1175 //cv::imshow("Mapa de Disparidade V + Hough", color_img);
1176 //cv::imshow("Mapa de Disparidade V + Hough", v_disp_map2);
1177
1178 return color_img;
1179}
1180
1181// Function to find the near obstacles from a v-Disparity map
1182cv::Mat ObstacleDetectionComponent::FindNearObstacles(cv::Mat v_disp_map, int min_d, int max_d)
1183{
1184 // Parameters of threshold and hough transform
1185 int tshold1 = 3;
1186 int n_points = 15;
1187 int minLineLenght = 10;
1188 int maxLineGap = 12;
1189
1190 // Image to be processed
1191 cv::Mat v_disp_map_aux = v_disp_map.clone();
1192
1193 // Image with the obstacles highlighted in red
1194 cv::Mat color_img = cv::Mat( cv::Size(v_disp_map.cols, v_disp_map.rows), CV_8UC3);
1195
1196 // Convert color space
1197 cv::cvtColor(v_disp_map_aux, color_img, CV_GRAY2BGR);
1198
1199 // Image binarization
1200 cv::threshold(v_disp_map_aux, v_disp_map_aux, tshold1, 255, CV_THRESH_BINARY);
1201
1202 // Janela de exibicao
1203 //cv::namedWindow("Mapa de Disparidade V + Threshold 2",CV_WINDOW_AUTOSIZE);
1204 //cv::imshow("Mapa de Disparidade V + Threshold 2", v_disp_map_aux);
1205
1206 // Define valid ROI
1207 cv::Mat v_disp_map_aux_ROI = v_disp_map_aux(cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1208 cv::Mat color_img_ROI = color_img( cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1209
1210 std::vector<cv::Vec4i> lines; //vector for storing the lines found by HoughLine
1211
1212 // Probabilistic hough transform
1213 cv::HoughLinesP( v_disp_map_aux_ROI, lines, 1, CV_PI/180, n_points, minLineLenght, maxLineGap );
1214
1215 if (lines.size() != 0)
1216 {
1217 cv::Point pt1, pt2;
1218 double theta;
1219
1220 for(int i = 0; i < (int)lines.size(); ++i)
1221 {
1222 pt1.x = lines[i][0];//(CvPoint*)cvGetSeqElem(lines,i);
1223 pt1.y = lines[i][1];
1224 pt2.x = lines[i][2];
1225 pt2.y = lines[i][3];
1226
1227 this->CheckPoints(pt1, pt2); //Verify the points order
1228
1229 theta = this->Inclination(pt1, pt2); // line slope
1230
1231 // In degrees
1232 theta = ((theta*360.0)/(2.0*CV_PI));
1233
1234 // Verifica se a reta possui inclinacao para ser possivel plano
1235 if((theta < (90.0 + ANG_VARIATION2))&& (theta > (90.0 - ANG_VARIATION2)))
1236 {
1237 //Desenha as retas em vermelho
1238 cv::line( color_img_ROI, pt1, pt2, CV_RGB(255,0,0), 5, 8 );
1239 }
1240 }
1241 }
1242
1243 // Janela de exibicao
1244 //cv::namedWindow("Mapa de Disparidade V + Hough1",CV_WINDOW_AUTOSIZE);
1245 //cv::imshow("Mapa de Disparidade V + Hough1", v_disp_map_aux);
1246
1247 // Janela de exibicao
1248 //cv::namedWindow("Mapa de Disparidade V + Hough2",CV_WINDOW_AUTOSIZE);
1249 //cv::imshow("Mapa de Disparidade V + Hough2", color_img);
1250
1251 return color_img;
1252}
1253
1254// Function to find the near obstacles from the v/u-Disparity maps
1255std::pair<cv::Mat, cv::Mat> ObstacleDetectionComponent::FindNearObstaclesUV(cv::Mat v_disp_map, cv::Mat u_disp_map, int min_d, int max_d)
1256{
1257 // Parameters of threshold and hough transform
1258 int tshold1 = 3;
1259 int tshold2 = 15;
1260 int n_points = 15;
1261 int minLineLenght = 10;
1262 int maxLineGap = 12;
1263
1264 std::vector<cv::Mat> channels(3);
1265
1266 //=================================== V-disparity map process =============================================================
1267 //// Image to be processed
1268 //cv::Mat v_disp_map_aux = v_disp_map.clone();
1269 //
1270 //// Image with the obstacles highlighted in red
1271 //cv::Mat v_color_img = cv::Mat( cv::Size(v_disp_map.cols, v_disp_map.rows), CV_8UC3);
1272
1273 //// Convert color space
1274 //cv::cvtColor(v_disp_map_aux, v_color_img, CV_GRAY2BGR);
1275
1276 //cv::equalizeHist( v_disp_map_aux, v_disp_map_aux);
1277
1278 //// Image binarization
1279 //cv::threshold(v_disp_map_aux, v_disp_map_aux, tshold1, 255, CV_THRESH_BINARY);
1280
1281 //// Janela de exibicao
1282 //if(this->showdebug)
1283 //{
1284 // cv::namedWindow("Mapa de Disparidade V + Threshold 2",CV_WINDOW_AUTOSIZE);
1285 // cv::imshow("Mapa de Disparidade V + Threshold 2", v_disp_map_aux);
1286 //}
1287
1288 //// Define valid ROI
1289 //cv::Mat v_disp_map_aux_ROI = v_disp_map_aux(cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1290 //cv::Mat v_color_img_ROI = v_color_img( cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1291
1292 //std::vector<cv::Vec4i> lines; //vector for storing the lines found by HoughLine
1293
1294 //// Probabilistic hough transform
1295 //cv::HoughLinesP( v_disp_map_aux_ROI, lines, 1, CV_PI/180, n_points, minLineLenght, maxLineGap );
1296 //
1297 //if (lines.size() != 0)
1298 //{
1299 // cv::Point pt1, pt2;
1300 // double theta;
1301
1302 // for(int i = 0; i < (int)lines.size(); ++i)
1303 // {
1304 // pt1.x = lines[i][0];//(CvPoint*)cvGetSeqElem(lines,i);
1305 // pt1.y = lines[i][1];
1306 // pt2.x = lines[i][2];
1307 // pt2.y = lines[i][3];
1308
1309 // this->CheckPoints(pt1, pt2); //Verify the points order
1310 //
1311 // theta = this->Inclination(pt1, pt2); // line slope
1312
1313 // // In degrees
1314 // theta = ((theta*360.0)/(2.0*CV_PI));
1315
1316 // // Verifica se a reta possui inclinacao para ser possivel plano
1317 // //if((theta < (90.0 + ANG_VARIATION2))&& (theta > (90.0 - ANG_VARIATION2)))
1318 // //{
1319 // //Desenha as retas em vermelho
1320 // cv::line( v_color_img_ROI, pt1, pt2, CV_RGB(255,0,0), 5, 8 );
1321 // //}
1322 // }
1323 //}
1324 //
1325 //// Janela de exibicao
1326 ////cv::namedWindow("Mapa de Disparidade V + Hough1",CV_WINDOW_AUTOSIZE);
1327 ////cv::imshow("Mapa de Disparidade V + Hough1", v_disp_map_aux);
1328
1329 //// Janela de exibicao
1330 ////cv::namedWindow("Mapa de Disparidade V + Hough2",CV_WINDOW_AUTOSIZE);
1331 ////cv::imshow("Mapa de Disparidade V + Hough2", color_img);
1332
1333 //================================================================================================================================
1334
1335 //============================================== V-disparity map process =========================================================
1336 // Image to be processed
1337 cv::Mat v_disp_map_aux = v_disp_map.clone();
1338
1339 // Image with the obstacles highlighted in red
1340 cv::Mat v_color_img = cv::Mat( v_disp_map.rows, v_disp_map.cols, CV_8UC3, cv::Scalar(0,0,0));
1341
1342 // Convert color space
1343 //cv::cvtColor(v_disp_map_aux, v_color_img, CV_GRAY2BGR);
1344
1345 //cv::equalizeHist( v_disp_map_aux, v_disp_map_aux);
1346
1347 // Image binarization
1348 cv::threshold(v_disp_map_aux, v_disp_map_aux, tshold1, 255, CV_THRESH_BINARY);
1349
1350 // Janela de exibicao
1351 if(this->showdebug)
1352 {
1353 cv::namedWindow("Mapa de Disparidade V + Threshold 2",CV_WINDOW_AUTOSIZE);
1354 cv::imshow("Mapa de Disparidade V + Threshold 2", v_disp_map_aux);
1355 }
1356
1357 // Define valid ROI
1358 cv::Mat v_disp_map_aux_ROI = v_disp_map_aux(cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1359 cv::Mat v_color_img_ROI = v_color_img( cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1360
1361 cv::split( v_color_img, channels);
1362 channels[2] = v_disp_map_aux;
1363 cv::merge( channels, v_color_img);
1364
1365 //================================================================================================================================
1366
1367 //=============================================== U-disparity map process ========================================================
1368 // Image to be processed
1369 cv::Mat u_disp_map_aux = u_disp_map.clone();
1370
1371 // Image with the obstacles highlighted in red
1372 cv::Mat u_color_img = cv::Mat( cv::Size(u_disp_map.cols, u_disp_map.rows), CV_8UC3, cv::Scalar(0, 0, 0));
1373
1374 // Convert color space
1375 //cv::cvtColor(u_disp_map_aux, u_color_img, CV_GRAY2BGR);
1376
1377 // Image binarization
1378 cv::threshold(u_disp_map_aux, u_disp_map_aux, tshold2, 255, CV_THRESH_BINARY);
1379
1380 // Closing
1381 cv::dilate(u_disp_map_aux, u_disp_map_aux, cv::Mat(), cv::Point(-1,-1), 1 );
1382 cv::erode(u_disp_map_aux, u_disp_map_aux, cv::Mat(), cv::Point(-1,-1), 1 );
1383
1384
1385 if(this->showdebug)
1386 {
1387 // Janela de exibicao
1388 cv::namedWindow("ObstacleDetectionComponent - Image bin u-disp",CV_WINDOW_AUTOSIZE);
1389 cv::imshow("ObstacleDetectionComponent - Image bin u-disp", u_disp_map_aux);
1390 }
1391
1392 cv::split( u_color_img, channels);
1393 channels[2] = u_disp_map_aux;
1394 cv::merge( channels, u_color_img);
1395
1396 // Define valid ROI
1397 //cv::Mat u_disp_map_aux_ROI = v_disp_map_aux(cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1398 //cv::Mat u_color_img_ROI = v_color_img( cv::Rect(min_d, 0, max_d-min_d+1, v_disp_map_aux.rows));
1399 //================================================================================================================================
1400
1401 return std::make_pair(v_color_img, u_color_img);
1402}
1403
1404/* LinesFiltering
1405 Description:
1406 Filter the detected lines related to the distance and angle between them.
1407 Parameters:
1408 lines = line list (point 1 and 2)
1409*/
1410std::vector<cv::Point> ObstacleDetectionComponent::LinesFiltering(std::vector<cv::Vec4i> lines)
1411{
1412 std::vector<cv::Point> lista_pontos;
1413
1414 std::vector<cv::Point> lista_retorno;
1415
1416 std::vector<double> angles;
1417
1418 cv::Point pt1, pt2;
1419 double theta;
1420 double angulo_medio = 0.0;
1421
1422 if (lines.size() != 0)
1423 {
1424 //std::cout << "Found "<< lines.size() << " lines!\n";
1425
1426 // Filtro de angulo maximo
1427 for(int i = 0; i < (int)lines.size(); ++i)
1428 {
1429 pt1.x = lines[i][0];//(CvPoint*)cvGetSeqElem(lines,i);
1430 pt1.y = lines[i][1];
1431 pt2.x = lines[i][2];
1432 pt2.y = lines[i][3];
1433
1434 CheckPoints(pt1, pt2); //Verifica a ordem dos pontos
1435
1436 theta = Inclination(pt1, pt2); //calcula a inclinacao da reta encontrada
1437
1438 // Valor atual do angulo em graus
1439 theta = ((theta*360.0)/(2.0*CV_PI));
1440
1441 //std::cout << "Angle "<< theta << "!\n";
1442
1443 // Verifica se a reta possui inclinacao para ser possivel plano
1444 if(theta> (90.0 + ANG_VARIATION))
1445 {
1446 lista_pontos.push_back(pt1);
1447 lista_pontos.push_back(pt2);
1448
1449 angles.push_back(theta);
1450 }
1451 }
1452
1453 if(!lista_pontos.empty())
1454 {
1455 std::sort(lista_pontos.begin(), lista_pontos.end(), ComparePoints1);
1456 angulo_medio = this->CalcMedian(angles);
1457 }
1458
1459 CvPoint last_item;
1460
1461 // Percorre os pontos ordenados e procura a casca convexa mais a esquerda
1462 for(std::vector<cv::Point>::iterator it = lista_pontos.begin(); it != lista_pontos.end(); ++it)
1463 {
1464 if(lista_retorno.empty())
1465 {
1466 lista_retorno.push_back(*it);
1467
1468 last_item = *it;
1469 }
1470 else
1471 {
1472 if( (it + 1) != lista_pontos.end())
1473 {
1474 // Se tiverem o mesmo y, substitui o ponto
1475 if(last_item.y == (*it).y)
1476 {
1477 // Troca o ultimo elemento
1478 lista_retorno.pop_back();
1479
1480 lista_retorno.push_back(*it);
1481
1482 last_item = *it;
1483 }
1484 else
1485 {
1486 theta = Inclination(*it, last_item); //calcula a inclinacao da reta encontrada
1487
1488 // Valor atual do angulo em graus
1489 theta = ((theta*360.0)/(2.0*CV_PI));
1490
1491 lista_retorno.push_back(*it);
1492
1493 // Percorre os pontos ordenados e procura o maior angulo entre a casca convexa mais a esquerda
1494 for(std::vector<cv::Point>::iterator it2 = it + 1; it2 != lista_pontos.end(); ++it2)
1495 {
1496 // Verifica se o angulo atual e menor que o anterior
1497 if(theta < ((Inclination(*it2, last_item)*360.0)/(2.0*CV_PI)))
1498 {
1499 // Troca o ultimo elemento
1500 lista_retorno.pop_back();
1501
1502 lista_retorno.push_back(*it2);
1503
1504 theta = Inclination(*it2, last_item); //calcula a inclinacao da reta encontrada
1505
1506 // Valor atual do angulo em graus
1507 theta = ((theta*360.0)/(2.0*CV_PI));
1508
1509 it = it2;
1510 }
1511 } // for
1512
1513 last_item = *it;
1514 } // else
1515 } // if( (it + 1) != lista_pontos.end())
1516 } // else
1517 } // for
1518
1519 if(!lista_retorno.empty())
1520 {
1521 last_item = *(lista_retorno.begin());
1522
1523 // Filtro de angulo medio
1524 for(std::vector<cv::Point>::iterator it = lista_retorno.begin() + 1; it != lista_retorno.end(); ++it)
1525 {
1526 theta = Inclination(*it, last_item); //calcula a inclinacao da reta encontrada
1527
1528 // Valor atual do angulo em graus
1529 theta = ((theta*360.0)/(2.0*CV_PI));
1530
1531 // Verifica se a reta possui inclinacao fora da media
1532 if(theta < (0.95*angulo_medio))//((theta > (1.05*angulo_medio))&&(theta < (0.95*angulo_medio)))
1533 {
1534 lista_retorno.resize(it - lista_retorno.begin());
1535
1536 break;
1537 }
1538
1539 last_item = *it;
1540 }
1541 }
1542
1543 }
1544
1545 return lista_retorno;
1546}
1547
1548//Function to check the points order, making the second one with the highest y ever
1549void ObstacleDetectionComponent::CheckPoints(cv::Point &pt1, cv::Point &pt2)
1550{
1551 int aux_x, aux_y;
1552
1553 if(pt1.y > pt2.y)
1554 {
1555 aux_x = pt1.x;
1556 aux_y = pt1.y;
1557
1558 pt1.x = pt2.x;
1559 pt1.y = pt2.y;
1560
1561 pt2.x = aux_x;
1562 pt2.y = aux_y;
1563 }
1564
1565 return;
1566}
1567
1568// Function to calculate the line slope of pt1 to pt2
1569double ObstacleDetectionComponent::Inclination(cv::Point pt1, cv::Point pt2)
1570{
1571 double theta; //angle
1572
1573 theta = fabs((atan2((pt1.y-pt2.y+0.0),(pt1.x-pt2.x+0.0)))); // slope
1574
1575 return theta;
1576}
1577
1578/* CalcMedian
1579 Description:
1580 Calcule the median value of a vector.
1581 Parametros:
1582 vector = vector with data to calculate the median
1583*/
1584template<class A>
1585A ObstacleDetectionComponent::CalcMedian(std::vector<A> vetor) const
1586{
1587 A mediana;
1588
1589 std::sort(vetor.begin(), vetor.end());
1590
1591 mediana = vetor[(int)((double)(vetor.size())/2.0 + 0.5) - 1];
1592
1593 return mediana;
1594}
1595
1596// Function to calculate the free space (v_disp_1) and obstacles (v_disp_2) masks from
1597// a red highlighted V-Disparity map
1598std::pair<cv::Mat, cv::Mat> ObstacleDetectionComponent::MaskSurface2(cv::Mat disp_map, cv::Mat v_disp_1, cv::Mat v_disp_2, int min_d, int max_d, int value)
1599{
1600 // Free space mask
1601 cv::Mat mask1;
1602
1603 // Obstacle Mask
1604 cv::Mat mask2;
1605
1606 // Fill the destiny images with background value
1607 if(value == 1)
1608 {
1609 mask1 = cv::Mat::zeros( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1610 mask2 = cv::Mat::zeros( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1611 }
1612 else
1613 {
1614 mask1 = cv::Mat::ones( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1615 mask2 = cv::Mat::ones( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1616 }
1617
1618 int l, c, pixel, v_disp_pixel; // local variables for row, column and pixel
1619 unsigned char intensity; // pixel intensity
1620 unsigned char intensity_B, intensity_G, intensity_R; //pixel intensity
1621
1622 /*uint8_t* pixelPtr_mask1 = (uint8_t*)mask1.data;
1623 uint8_t* pixelPtr_mask2 = (uint8_t*)mask2.data;
1624 uint8_t* pixelPtr_disp_map = (uint8_t*)disp_map.data;
1625 uint8_t* pixelPtr_v_disp1 = (uint8_t*)v_disp_1.data;
1626 uint8_t* pixelPtr_v_disp2 = (uint8_t*)v_disp_2.data;*/
1627
1628 // run the images associating the red pixels in the v-disparities in the mask1 e mask2
1629 for (l = 0; l < disp_map.rows; ++l)
1630 {
1631 for (c = 0; c < disp_map.cols; ++c)
1632 {
1633 pixel = l*disp_map.cols + c;
1634
1635 intensity = (unsigned char)disp_map.data[pixel];
1636
1637 //--------- Marca os planos trafegaveis --------------------
1638 // Pixel Azul
1639 v_disp_pixel = l*v_disp_1.cols*3 + intensity*3;
1640 intensity_B = (unsigned char)v_disp_1.data[v_disp_pixel];
1641
1642 // Pixel Verde
1643 v_disp_pixel = l*v_disp_1.cols*3 + intensity*3 + 1;
1644 intensity_G = (unsigned char)v_disp_1.data[v_disp_pixel];
1645
1646 // Pixel Vermelho
1647 v_disp_pixel = l*v_disp_1.cols*3 + intensity*3 + 2;
1648 intensity_R = (unsigned char)v_disp_1.data[v_disp_pixel];
1649
1650 if((intensity_B == 0)&&(intensity_G == 0)&&(intensity_R == 255))
1651 {
1652 mask1.data[pixel] = value;
1653 }
1654 //----------------------------------------------------------
1655
1656 //--------- Marca os obstaculos ----------------------------
1657 if( (intensity >= min_d)&&(intensity <= max_d))
1658 {
1659 // Pixel Azul
1660 v_disp_pixel = l*v_disp_2.cols*3 + intensity*3;
1661 intensity_B = (unsigned char)v_disp_2.data[v_disp_pixel];
1662
1663 // Pixel Verde
1664 v_disp_pixel = l*v_disp_2.cols*3 + intensity*3 + 1;
1665 intensity_G = (unsigned char)v_disp_2.data[v_disp_pixel];
1666
1667 // Pixel Vermelho
1668 v_disp_pixel = l*v_disp_2.cols*3 + intensity*3 + 2;
1669 intensity_R = (unsigned char)v_disp_2.data[v_disp_pixel];
1670
1671 if((intensity_B == 0)&&(intensity_G == 0)&&(intensity_R == 255))
1672 {
1673 mask2.data[pixel] = value;
1674 }
1675 }
1676 //----------------------------------------------------------
1677 }
1678 }
1679
1680 /*cv::Mat element = cv::getStructuringElement( cv::MORPH_RECT,
1681 cv::Size( 3, 3 ),
1682 cv::Point( 1, 1 ) );*/
1683
1684 // Espande as regioes brancas da imagem
1685 if(value == 1)
1686 {
1687 //cv::dilate(mask1, mask1, element, cv::Point(1,1), 2);
1688 //cv::dilate(mask2, mask2, element, cv::Point(1,1), 2);
1689
1690 cv::dilate(mask1, mask1, cv::Mat(), cv::Point(-1,-1), 2 );
1691 cv::dilate(mask2, mask2, cv::Mat(), cv::Point(-1,-1), 2 );
1692 }
1693 else
1694 {
1695 //cv::erode(mask1, mask1, element, cv::Point(1,1), 2);
1696 //cv::erode(mask2, mask2, element, cv::Point(1,1), 2);
1697
1698 cv::erode(mask1,mask1,NULL, cv::Point(-1,-1), 2);
1699 cv::erode(mask2,mask2,NULL, cv::Point(-1,-1), 2);
1700 }
1701
1702 //cvNamedWindow("Imagem da mascara1",CV_WINDOW_AUTOSIZE);
1703 //cvShowImage("Imagem da mascara1", mask1);
1704
1705 //cvNamedWindow("Imagem da mascara2",CV_WINDOW_AUTOSIZE);
1706 //cvShowImage("Imagem da mascara2", mask2);
1707
1708 return std::make_pair(mask1, mask2);
1709}
1710
1711// Function to calculate the free space (v_disp_1) and obstacles (v_disp_2/u_disp) masks from
1712// a red highlighted V-Disparity map
1713std::pair<cv::Mat, cv::Mat> ObstacleDetectionComponent::MaskSurface3(cv::Mat disp_map, cv::Mat v_disp_1, cv::Mat v_disp_2, cv::Mat u_disp, int min_d, int max_d, int value)
1714{
1715 // Free space mask
1716 cv::Mat mask1;
1717
1718 // Obstacle Mask
1719 cv::Mat mask2;
1720
1721 // Fill the destiny images with background value
1722 if(value == 1)
1723 {
1724 mask1 = cv::Mat::zeros( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1725 mask2 = cv::Mat::zeros( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1726 }
1727 else
1728 {
1729 mask1 = cv::Mat::ones( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1730 mask2 = cv::Mat::ones( cv::Size(disp_map.cols, disp_map.rows), CV_8UC1 );
1731 }
1732
1733 int l, c, pixel, v_disp_pixel, u_disp_pixel; // local variables for row, column and pixel
1734 unsigned char intensity; // pixel intensity
1735 unsigned char intensity_B_v, intensity_G_v, intensity_R_v; //pixel intensity
1736 unsigned char intensity_B_u, intensity_G_u, intensity_R_u; //pixel intensity
1737
1738 /*uint8_t* pixelPtr_mask1 = (uint8_t*)mask1.data;
1739 uint8_t* pixelPtr_mask2 = (uint8_t*)mask2.data;
1740 uint8_t* pixelPtr_disp_map = (uint8_t*)disp_map.data;
1741 uint8_t* pixelPtr_v_disp1 = (uint8_t*)v_disp_1.data;
1742 uint8_t* pixelPtr_v_disp2 = (uint8_t*)v_disp_2.data;*/
1743
1744 // run the images associating the red pixels in the v-disparities in the mask1 e mask2
1745 for (l = 0; l < disp_map.rows; ++l)
1746 {
1747 for (c = 0; c < disp_map.cols; ++c)
1748 {
1749 pixel = l*disp_map.cols + c;
1750
1751 intensity = (unsigned char)disp_map.data[pixel];
1752
1753 //--------- Marca os planos trafegaveis --------------------
1754 // Pixel Azul
1755 v_disp_pixel = l*v_disp_1.cols*3 + intensity*3;
1756 intensity_B_v = (unsigned char)v_disp_1.data[v_disp_pixel];
1757
1758 // Pixel Verde
1759 v_disp_pixel = l*v_disp_1.cols*3 + intensity*3 + 1;
1760 intensity_G_v = (unsigned char)v_disp_1.data[v_disp_pixel];
1761
1762 // Pixel Vermelho
1763 v_disp_pixel = l*v_disp_1.cols*3 + intensity*3 + 2;
1764 intensity_R_v = (unsigned char)v_disp_1.data[v_disp_pixel];
1765
1766 if((intensity_B_v == 0)&&(intensity_G_v == 0)&&(intensity_R_v == 255))
1767 {
1768 mask1.data[pixel] = value;
1769 }
1770 //----------------------------------------------------------
1771
1772 //--------- Marca os obstaculos ----------------------------
1773 if( (intensity >= min_d)&&(intensity <= max_d))
1774 {
1775 // Pixel Azul
1776 v_disp_pixel = l*v_disp_2.cols*3 + intensity*3;
1777 u_disp_pixel = intensity*u_disp.cols*3 + c*3;
1778 intensity_B_v = (unsigned char)v_disp_2.data[v_disp_pixel];
1779 intensity_B_u = (unsigned char)u_disp.data[u_disp_pixel];
1780
1781 // Pixel Verde
1782 v_disp_pixel = l*v_disp_2.cols*3 + intensity*3 + 1;
1783 u_disp_pixel = intensity*u_disp.cols*3 + c*3 + 1;
1784 intensity_G_v = (unsigned char)v_disp_2.data[v_disp_pixel];
1785 intensity_G_u = (unsigned char)u_disp.data[u_disp_pixel];
1786
1787 // Pixel Vermelho
1788 v_disp_pixel = l*v_disp_2.cols*3 + intensity*3 + 2;
1789 u_disp_pixel = intensity*u_disp.cols*3 + c*3 + 2;
1790 intensity_R_v = (unsigned char)v_disp_2.data[v_disp_pixel];
1791 intensity_R_u = (unsigned char)u_disp.data[u_disp_pixel];
1792
1793 if((intensity_B_v == 0)&&(intensity_G_v == 0)&&(intensity_R_v == 255)&&(intensity_B_u == 0)&&(intensity_G_u == 0)&&(intensity_R_u == 255))
1794 {
1795 mask2.data[pixel] = value;
1796 }
1797 }
1798 //----------------------------------------------------------
1799 }
1800 }
1801
1802 /*cv::Mat element = cv::getStructuringElement( cv::MORPH_RECT,
1803 cv::Size( 3, 3 ),
1804 cv::Point( 1, 1 ) );*/
1805
1806 // Espande as regioes brancas da imagem
1807 if(value == 1)
1808 {
1809 //cv::dilate(mask1, mask1, element, cv::Point(1,1), 2);
1810 //cv::dilate(mask2, mask2, element, cv::Point(1,1), 2);
1811
1812 cv::dilate(mask1, mask1, cv::Mat(), cv::Point(-1,-1), 2 );
1813 cv::dilate(mask2, mask2, cv::Mat(), cv::Point(-1,-1), 2 );
1814 }
1815 else
1816 {
1817 //cv::erode(mask1, mask1, element, cv::Point(1,1), 2);
1818 //cv::erode(mask2, mask2, element, cv::Point(1,1), 2);
1819
1820 cv::erode(mask1,mask1,NULL, cv::Point(-1,-1), 2);
1821 cv::erode(mask2,mask2,NULL, cv::Point(-1,-1), 2);
1822 }
1823
1824 //cvNamedWindow("Imagem da mascara1",CV_WINDOW_AUTOSIZE);
1825 //cvShowImage("Imagem da mascara1", mask1);
1826
1827 //cvNamedWindow("Imagem da mascara2",CV_WINDOW_AUTOSIZE);
1828 //cvShowImage("Imagem da mascara2", mask2);
1829
1830 return std::make_pair(mask1, mask2);
1831}
Note: See TracBrowser for help on using the repository browser.