VNContoursObservation taking 715 times as long as OpenCV findCountours

VNContoursObservation is taking 715 times as long as OpenCV’s findContours() when creating directly comparable results.

VNContoursObservation creates comparable results when I have set the maximumImageDimension property to 1024. If I set it lower, it runs a bit faster, but creates lower quality contours and still takes over 100 times as long.

I have a hard time believing Apple doesn’t know what they are doing, so does anyone have an idea what is going on and how to get it to run much faster? There doesn’t seem to be many options, but nothing I’ve tried closes the gap. Setting the detectsDarkOnLight property to true makes it run even slower.

OpenCV findContours runs with a binary image, but I am passing a RGB image to Vision assuming it would convert it to an appropriate format.

OpenCV:

double taskStart = CFAbsoluteTimeGetCurrent();
int contoursApproximation = CV_CHAIN_APPROX_NONE;
int contourRetrievalMode = CV_RETR_LIST;
findContours(input, contours, hierarchy, contourRetrievalMode, contoursApproximation, cv::Point(0,0));
NSLog(@"###### opencv findContours: %f", CFAbsoluteTimeGetCurrent() - taskStart);

###### opencv findContours: 0.017616 seconds

Vision:

let taskStart = CFAbsoluteTimeGetCurrent()
        
let contourRequest = VNDetectContoursRequest.init()
contourRequest.revision = VNDetectContourRequestRevision1
contourRequest.contrastAdjustment = 1.0
contourRequest.detectsDarkOnLight = false
contourRequest.maximumImageDimension = 1024

let requestHandler = VNImageRequestHandler.init(cgImage: sourceImage.cgImage!, options: [:])

try! requestHandler.perform([contourRequest])
let contoursObservation = contourRequest.results?.first as! VNContoursObservation
print(" ###### contoursObservation: \(CFAbsoluteTimeGetCurrent() - taskStart)")

###### contoursObservation: 12.605962038040161

The image I am providing OpenCV is 2048 pixels and the image I am providing Vision is 1024.

Replies

In my experience VNDetectContoursRequest is usually fast but when it encounters a contour which is "jaggy" it stalls for several seconds even on small 512 pixel images. This makes it useless in practice. OpenCV's findContours() does fine with the same input images.