Java opencv robinson mask,图片全黑

Java opencv robinson mask, Image is completely black

我正在研究 open cv,我决定测试 tutorialpoint 的 example 的 Robinson 面具。我复制了代码并使用了灰度jpg。

- 不幸的是,输出的图像是全黑的。
- 我试着注释掉似乎是两个额外的定向过滤器的东西。图像仍然是黑色的。
-我正在使用 java 1.8 和 opencv 3

try{
     int kernelSize = 9;
     System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
     Mat source = Imgcodecs.imread("grayScale2.jpg",  Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
     Mat destination = new Mat(source.rows(),source.cols(),source.type());  
     Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F){
        {
           put(0,0,-1);
           put(0,1,0);
           put(0,2,1);

           put(1,0-2);
           put(1,1,0);
           put(1,2,2);

           put(2,0,-1);
           put(2,1,0);
           put(2,2,1);
        }
     };       

     Imgproc.filter2D(source, destination, -1, kernel);
     Imgcodecs.imwrite("robinsonMaskExample.jpg", destination);

  } catch (Exception e) {
     System.out.println("Error: " + e.getMessage());
  }

您链接我们的代码有点缺陷。它将内核大小定义为 9 x 9,但内核本身显然是 3 x 3。因此,它将内核系数放在内核的左上角,内核本身的其余部分为 0。这是可能是您看不到正确结果的原因。 put 方法在矩阵的行和列中放置一个数字。正如您在定义内核的代码中看到的那样,它将内容放在第 0、1、2 行和第 0、1、2 列中——这隐含地是一个 3 x 3 内核,但内核的大小实际上是 9 x 9 .

因此,请取消注释 您注释掉的那些行,因为正确定义整个边缘检测掩码非常重要。此外,post 就所使用的边缘检测掩码而言是错误的。这实际上是在使用 Sobel operator. I've never heard of a mask called "Robinson" before, but I have heard of a Roberts-Cross 掩码,它是一个 2 x 2 内核,如下所示:

来源:Wikipedia

因此,最简单的解决方法是更改​​内核大小,使其为 3.... 所以只需更改:

int kernelSize = 9;

为此:

int kernelSize = 3;

更广阔的视野:

try{
     int kernelSize = 3; // Change
     System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
     Mat source = Imgcodecs.imread("grayScale2.jpg",  Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
     Mat destination = new Mat(source.rows(),source.cols(),source.type());  
     Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F){
        {
           put(0,0,-1);
           put(0,1,0);
           put(0,2,1);

           put(1,0-2);          
           put(1,1,0);
           put(1,2,2);

           put(2,0,-1);
           put(2,1,0);
           put(2,2,1); // Leave it this way - don't uncomment
        }
     };       

     Imgproc.filter2D(source, destination, -1, kernel);
     Imgcodecs.imwrite("robinsonMaskExample.jpg", destination);

  } catch (Exception e) {
     System.out.println("Error: " + e.getMessage());
  }

这个故事的寓意。让这成为您在线查找教程的一个教训。不要相信所有这些,因为它们有时会给你错误的信息,比如你刚才遇到的错误内核大小和调用错误的边缘检测器。我当然会将它们用作一个很好的起点,但是当涉及到细节时,请始终调试您看到的已经 posted 的代码,以确保他们打算编写的实际上是什么制作完成。