CvInvoke.Canny() - gives different results on different computers

时间:2018-02-01 18:30:32

标签: opencv image-processing emgucv opencvsharp canny-operator

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

2 个答案:

答案 0 :(得分:0)

行。
我不能说我已经100%理解了这个问题的原因,但我确实在所有电脑之间保持稳定 事情是,我首先使用静态方法CvInvoke.Canny()并发送输入&amp;输出Umat - 它可能不确定原始图像是什么类型,然后(通过访问某些windows dll或优先级或其他东西?)它导致每台计算机上做出不同的决策,因此不同的Umat翻译导致了不同的结果 (...也许)

BUT
当我将输入图像加载到Image<Gray, Byte>并使用其自己的 Canny方法(以及其他方法)时 - 所有这些都是稳定的,毫无疑问,无论如何它运行的是什么计算机 所以工作代码是:

UMat inputImageUMAT = new Image<Gray, byte>(inputFileName).ToUMat();
Image<Gray, Byte> binaryImage = inputImageUMAT.ToImage<Gray,Byte>().ThresholdBinary(new Gray(threshold), new Gray(255));
binaryImage = binaryImage.Erode(1);
binaryImage = binaryImage.Dilate(1);
binaryImage = binaryImage.PyrDown();
binaryImage = binaryImage.PyrUp();
binaryImage = binaryImage.Canny(1, 0, 3, true);

答案 1 :(得分:0)

我写信给EMGU的支持,这是他们的惊人答案:

  

我查看了您的代码并使用了UMat。这意味着代码将使用OpenCL(GPU)在可用时加速处理,并在没有兼容的OpenCL驱动程序/设备的工作站上回退到CPU。   我怀疑OpenCL路径产生的结果与CPU路径略有不同。在调用代码中的任何Emgu CV函数之前,您可以使用以下行,并检查是否在整个机器上使结果保持一致:

     

CvInvoke.UseOpenCL = false

     

上面的代码将禁用OpenCL并强制运行所有代码   CPU

毫不奇怪 - 他们是对的。 它确实解决了这个问题