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
答案 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
毫不奇怪 - 他们是对的。 它确实解决了这个问题。