Hi,
I am currently implementing obstacle detection using the camera output of a robot's floor-directed video camera. Using canny edge detection as preprocessing I am able to efficiently find contours using findContours. Whenever I find sufficient amounts of contours I send out an obstacle warning. So far so good - code compiles and works using laptop camera. The last remaining issue is that the robot films its own body using the camera (i.e. its base and wheels) and I obviously do not consider them to be obstacles and would hence like to exclude them from contour finding. Seeing that neither canny nor findContours provide masking functionality, I decided to mask the input myself. So what I am currently doing is performing canny edge on the whole image and then overwriting the area to be ignored with zeroes (i.e. color black), before I pass the image to find contours. I do this using copyTo(). However findContours throws an "Unrecognized or unsupported array type in function cvGetMat" exception if my mask indicates to overwrite nothing, and copyTo() an "EXC_BAD_ACCESS" exception if my mask indicates to overwrite everything. I am unable to trace this error, as I assert type and size equality before using copyTo() and input and mask are static and therefore never empty. I would highly appreciate some feedback. I am guessing I am making a very fundamental mistake, as copyTo() should copy nothing given the code below (with the empty mask) and therefore the code should run just as before.
Any feedback is appreciated.
Warm regards, Mark
int detectFloor(VideoCapture floorCam){
if( !floorCam.isOpened() ){
cout << "Could not initialize capturing...\n";
return 0;
}
Mat frame, image, gray, canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
RNG rng(12345);
Mat black(720,1280,CV_8U,0); // The black pixels I am copying later on
Mat mask(720,1280,CV_8U,0); // When to copy them (currently never) - I need to actually build the real mask
// Sensitivity of the contour detection
int thresh = 100;
// Sensitivity of obstacle detection i.e. number of contours needed to raise warning
int critical = 10;
for(;;){
// Capture a 1280*720 frame
floorCam >> frame;
if( frame.empty() )
break;
frame.copyTo(image);
// Convert image to gray for better accuracy during contour detection
cvtColor(image, gray, COLOR_BGR2GRAY);
// Blur image to remove disturbances
blur( gray, gray, Size(3,3) );
// Detect edges using canny to preprocess image for contour detection
Canny( gray, canny_output, thresh, thresh*2, 3 );
// Mask robot from canny_output by filling that area of the image with black
// That way robot contours will be ignored during detection
assert(black.size() == canny_output.size());
assert(black.type() == canny_output.type());
black.copyTo(canny_output, mask);
// Find contours i.e. curves that join continuous points having same color or intensity
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
// Contours indicate presence of alien entities
// Therefore check if sufficient numbers of contours are present to raise alarm
if (contours.size() > critical)
cout << "Warning! Obstacle detected - " << contours.size() << " contours found." << endl;
}
return(0);
}