/** @function detectAndDisplay */ vector<PlateRegion> RegionDetector::doCascade(Mat frame) { //float scale_factor = 1; int w = frame.size().width; int h = frame.size().height; vector<Rect> plates; equalizeHist( frame, frame ); resize(frame, frame, Size(w * this->scale_factor, h * this->scale_factor)); //-- Detect plates timespec startTime; getTime(&startTime); Size minSize(config->minPlateSizeWidthPx * this->scale_factor, config->minPlateSizeHeightPx * this->scale_factor); Size maxSize(w * config->maxPlateWidthPercent * this->scale_factor, h * config->maxPlateHeightPercent * this->scale_factor); if (config->opencl_enabled) { ocl::oclMat openclFrame(frame); ((ocl::OclCascadeClassifier*) plate_cascade)->detectMultiScale(openclFrame, plates, config->detection_iteration_increase, 3, 0, minSize, maxSize); } else { plate_cascade->detectMultiScale( frame, plates, config->detection_iteration_increase, 3, 0, //0|CV_HAAR_SCALE_IMAGE, minSize, maxSize ); } if (config->debugTiming) { timespec endTime; getTime(&endTime); cout << "LBP Time: " << diffclock(startTime, endTime) << "ms." << endl; } for( int i = 0; i < plates.size(); i++ ) { plates[i].x = plates[i].x / scale_factor; plates[i].y = plates[i].y / scale_factor; plates[i].width = plates[i].width / scale_factor; plates[i].height = plates[i].height / scale_factor; } vector<PlateRegion> orderedRegions = aggregateRegions(plates); return orderedRegions; }
vector<PlateRegion> DetectorCPU::doCascade(Mat frame, std::vector<cv::Rect> regionsOfInterest) { if (frame.cols > config->maxDetectionInputWidth) { // The frame is too wide this->scale_factor = ((float) config->maxDetectionInputWidth) / ((float) frame.cols); if (config->debugGeneral) std::cout << "Input detection image is too wide. Resizing with scale: " << this->scale_factor << endl; } else if (frame.rows > config->maxDetectionInputHeight) { // The frame is too tall this->scale_factor = ((float) config->maxDetectionInputHeight) / ((float) frame.rows); if (config->debugGeneral) std::cout << "Input detection image is too tall. Resizing with scale: " << this->scale_factor << endl; } int w = frame.size().width; int h = frame.size().height; vector<Rect> plates; equalizeHist( frame, frame ); resize(frame, frame, Size(w * this->scale_factor, h * this->scale_factor)); //-- Detect plates timespec startTime; getTime(&startTime); float maxWidth = ((float) w) * (config->maxPlateWidthPercent / 100.0f) * this->scale_factor; float maxHeight = ((float) h) * (config->maxPlateHeightPercent / 100.0f) * this->scale_factor; Size minSize(config->minPlateSizeWidthPx * this->scale_factor, config->minPlateSizeHeightPx * this->scale_factor); Size maxSize(maxWidth, maxHeight); plate_cascade.detectMultiScale( frame, plates, config->detection_iteration_increase, config->detectionStrictness, 0, //0|CV_HAAR_SCALE_IMAGE, minSize, maxSize ); if (config->debugTiming) { timespec endTime; getTime(&endTime); cout << "LBP Time: " << diffclock(startTime, endTime) << "ms." << endl; } for( uint i = 0; i < plates.size(); i++ ) { plates[i].x = plates[i].x / scale_factor; plates[i].y = plates[i].y / scale_factor; plates[i].width = plates[i].width / scale_factor; plates[i].height = plates[i].height / scale_factor; } vector<PlateRegion> orderedRegions = aggregateRegions(plates); return orderedRegions; }
vector<PlateRegion> Detector::detect(Mat frame, std::vector<cv::Rect> regionsOfInterest) { Mat frame_gray; if (frame.channels() > 2) { cvtColor( frame, frame_gray, CV_BGR2GRAY ); } else { frame.copyTo(frame_gray); } // Apply the detection mask if it has been specified by the user if (detector_mask.mask_loaded) frame_gray = detector_mask.apply_mask(frame_gray); // Setup debug mask image Mat mask_debug_img; if (detector_mask.mask_loaded && config->debugDetector) { frame_gray.copyTo(mask_debug_img); cvtColor(frame_gray, mask_debug_img, CV_GRAY2BGR); } vector<PlateRegion> detectedRegions; for (int i = 0; i < regionsOfInterest.size(); i++) { Rect roi = regionsOfInterest[i]; // Adjust the ROI to be inside the detection mask (if it exists) if (detector_mask.mask_loaded) roi = detector_mask.getRoiInsideMask(roi); // Draw ROIs on debug mask image if (detector_mask.mask_loaded && config->debugDetector) rectangle(mask_debug_img, roi, Scalar(0,255,255), 3); // Sanity check. If roi width or height is less than minimum possible plate size, // then skip it if ((roi.width < config->minPlateSizeWidthPx) || (roi.height < config->minPlateSizeHeightPx)) continue; Mat cropped = frame_gray(roi); int w = cropped.size().width; int h = cropped.size().height; int offset_x = roi.x; int offset_y = roi.y; float scale_factor = computeScaleFactor(w, h); if (scale_factor != 1.0) resize(cropped, cropped, Size(w * scale_factor, h * scale_factor)); float maxWidth = ((float) w) * (config->maxPlateWidthPercent / 100.0f) * scale_factor; float maxHeight = ((float) h) * (config->maxPlateHeightPercent / 100.0f) * scale_factor; Size minPlateSize(config->minPlateSizeWidthPx, config->minPlateSizeHeightPx); Size maxPlateSize(maxWidth, maxHeight); vector<Rect> allRegions = find_plates(cropped, minPlateSize, maxPlateSize); // Aggregate the Rect regions into a hierarchical representation for( unsigned int i = 0; i < allRegions.size(); i++ ) { allRegions[i].x = (allRegions[i].x / scale_factor); allRegions[i].y = (allRegions[i].y / scale_factor); allRegions[i].width = allRegions[i].width / scale_factor; allRegions[i].height = allRegions[i].height / scale_factor; // Ensure that the rectangle isn't < 0 or > maxWidth/Height allRegions[i] = expandRect(allRegions[i], 0, 0, w, h); allRegions[i].x = allRegions[i].x + offset_x; allRegions[i].y = allRegions[i].y + offset_y; } // Check the rectangles and make sure that they're definitely not masked vector<Rect> regions_not_masked; for (unsigned int i = 0; i < allRegions.size(); i++) { if (detector_mask.mask_loaded) { if (!detector_mask.region_is_masked(allRegions[i])) regions_not_masked.push_back(allRegions[i]); } else regions_not_masked.push_back(allRegions[i]); } vector<PlateRegion> orderedRegions = aggregateRegions(regions_not_masked); for (unsigned int j = 0; j < orderedRegions.size(); j++) detectedRegions.push_back(orderedRegions[j]); } // Show debug mask image if (detector_mask.mask_loaded && config->debugDetector && config->debugShowImages) { imshow("Detection Mask", mask_debug_img); } return detectedRegions; }
vector<PlateRegion> DetectorCUDA::doCascade(Mat frame, int offset_x, int offset_y) { if (frame.cols > config->maxDetectionInputWidth) { // The frame is too wide this->scale_factor = ((float) config->maxDetectionInputWidth) / ((float) frame.cols); if (config->debugDetector) std::cout << "Input detection image is too wide. Resizing with scale: " << this->scale_factor << endl; } else if (frame.rows > config->maxDetectionInputHeight) { // The frame is too tall this->scale_factor = ((float) config->maxDetectionInputHeight) / ((float) frame.rows); if (config->debugDetector) std::cout << "Input detection image is too tall. Resizing with scale: " << this->scale_factor << endl; } int w = frame.size().width; int h = frame.size().height; vector<Rect> plates; equalizeHist( frame, frame ); resize(frame, frame, Size(w * this->scale_factor, h * this->scale_factor)); //-- Detect plates timespec startTime; getTimeMonotonic(&startTime); float maxWidth = ((float) w) * (config->maxPlateWidthPercent / 100.0f) * this->scale_factor; float maxHeight = ((float) h) * (config->maxPlateHeightPercent / 100.0f) * this->scale_factor; Size minSize(config->minPlateSizeWidthPx * this->scale_factor, config->minPlateSizeHeightPx * this->scale_factor); gpu::GpuMat cudaFrame, plateregions_buffer; Mat plateregions_downloaded; cudaFrame.upload(frame); int numdetected = cuda_cascade.detectMultiScale(cudaFrame, plateregions_buffer, (double) config->detection_iteration_increase, config->detectionStrictness, minSize); plateregions_buffer.colRange(0, numdetected).download(plateregions_downloaded); for (int i = 0; i < numdetected; ++i) { plates.push_back(plateregions_downloaded.ptr<cv::Rect>()[i]); } if (config->debugTiming) { timespec endTime; getTimeMonotonic(&endTime); cout << "LBP Time: " << diffclock(startTime, endTime) << "ms." << endl; } for( unsigned int i = 0; i < plates.size(); i++ ) { plates[i].x = (plates[i].x / scale_factor) + offset_x; plates[i].y = (plates[i].y / scale_factor) + offset_y; plates[i].width = plates[i].width / scale_factor; plates[i].height = plates[i].height / scale_factor; } vector<PlateRegion> orderedRegions = aggregateRegions(plates); return orderedRegions; }