when trying to perform some binary manipulations on the exact same image file, but on different computers (&monitors), i get a different result when using the CvInvoke.Canny()
method.
before calling this method, i use several manipulating methods such as: CvInvoke.Threshold()
, CvInvoke.Erode()
, CvInvoke.Dilate()
and more...
the result of all of these is always equal.
it is just when i call:
UMat inputImageUMAT = new Image<Gray, byte>(inputImageBitmap).ToUMat();
UMat imageUmat = new UMat();
CvInvoke.Threshold(imageInputUMAT, imageUmat, threshold, 255,
Emgu.CV.CvEnum.ThresholdType.Binary);
// clear noises with Erode & Dilate:
CvInvoke.Erode(imageUmat, imageUmat, null, new Point(-1, -1), 1,
BorderType.Constant, CvInvoke.MorphologyDefaultBorderValue);
CvInvoke.Dilate(imageUmat, imageUmat, null, new Point(-1, -1), 1,
BorderType.Constant, CvInvoke.MorphologyDefaultBorderValue);
//use image pyr to remove noise:
UMat pyrDown = new UMat();
CvInvoke.PyrDown(imageUmat, pyrDown);
CvInvoke.PyrUp(pyrDown, imageUmat);
// set cannyEdges to hold the outlines of the shapes detected in the image
(according to threshold)
UMat cannyEdges = new UMat();
CvInvoke.Canny(imageUmat, cannyEdges, threshold, threshold);
there is always a difference between the different computers outputs.
nonetheless, every computer always gives the exact same result - time after time.
what is it that might be causing the problem?
i must have the exact same results everywhere...
p.s.
i use the C# nugget: EMGU.CV v3.3.0.2824
edit:
i took the original file: original
and skipped all the manipulations on way and performed Canny
immediately:
UMat inputImageUMAT = new UMat(fileName, ImreadModes.Grayscale);
UMat cannyEdges = new UMat();
CvInvoke.Canny(imageInputUMAT, cannyEdges, threshold, threshold, 3, true);
cannyEdges.Save(outputFileName);
result with threshold 210 machine 1: result_1
result with threshold 210 machine 2: result_2
-- there is 1 pixel difference between the 2 results
I have wrote to EMGU's support, and here is their amazing answer:
I reviewed your code and it is using UMat. That means that the code will using OpenCL (GPU) to speed up the processing when it is available and fall back to CPU for workstation where there is no compatible OpenCL driver / device.
My suspicion is that the result produced by the OpenCL path is slightly different from the CPU path. Can you the following line before calling any of the Emgu CV function in your code and check if that make the result consistent across the machines:
CvInvoke.UseOpenCL = false
The above code will disable OpenCL and force all the code to run on CPU
not surprisingly - they are right. it really did solved the issue.