我当时在玩开放式简历,因此决定测试tutorialpoint的example作为Robinson面罩。我复制了代码并使用了灰度jpg。
-不幸的是,输出的图像是全黑的。
-我尝试注释掉似乎还有两个其他定向过滤器。图像仍然变黑。
-我在opencv 3中使用java 1.8

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 x3。因此,它将内核系数放在内核的左上角,而内核本身的其余部分为0。这是可能是您看不到正确结果的原因。 put 方法在矩阵的行和列中放置一个数字。正如您在定义内核的代码中所看到的,它将内容放入行0,1,2和列0,1,2-隐式为3 x 3内核,但内核的大小实际上为9 x 9 。

因此,请取消注释注释掉的那些行,因为正确定义整个边缘检测蒙版很重要。此外,就使用的边缘检测蒙版而言,该帖子是错误的。那实际上是使用Sobel operator。我以前从未听说过称为“Robinson”的蒙版,但是我听说过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());
  }

这个故事的寓意。就在线查找教程而言,这是对您的一个教训。不要相信所有这些,因为它们有时会为您提供错误的信息,例如您刚才使用错误的内核大小和将边缘检测器称为错误所经历的。我当然会以它们为一个很好的起点,但是当涉及到细节时,请始终调试您看到已发布的代码,以确保它们打算编写的内容实际上是生成的。

10-08 04:05