它显示异常错误

时间:2016-03-12 08:04:00

标签: java image opencv image-processing

我正在研究使用opencv语言从眼睛中检测瞳孔区域的程序。以下是代码段。它没有编译,抛出CV异常。我不知道该怎么办。我怎样才能让它发挥作用。 (opencv 2.4)

import java.util.ArrayList;
import java.util.List;
import java.lang.Math;
import org.opencv.core.Scalar;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Core;
import org.opencv.core.CvException;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

public class Detect {
    public static void main(String[] args) throws CvException{

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        // Load image
        Mat src = Highgui.imread("tt.jpg");

        // Invert the source image and convert to grayscale
        Mat gray = new Mat();
        Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
        Highgui.imwrite("gray.jpg", gray);
        // Convert to binary image by thresholding it
        Imgproc.threshold(gray, gray, 30, 255, Imgproc.THRESH_BINARY_INV);
        Highgui.imwrite("binary.jpg", gray);
        // Find all contours
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Imgproc.findContours(gray.clone(), contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);

        // Fill holes in each contour
        Imgproc.drawContours(gray, contours, -1, new Scalar(255,255,255), -1);

        for (int i = 0; i < contours.size(); i++)
        {
            double area = Imgproc.contourArea(contours.get(i));
            Rect rect = Imgproc.boundingRect(contours.get(i));
            int radius = rect.width/2;
            System.out.println("Area: "+area);
            // If contour is big enough and has round shape
            // Then it is the pupil
            if (area >= 30 && 
                Math.abs(1 - ((double)rect.width / (double)rect.height)) <= 0.2 &&
                    Math.abs(1 - (area / (Math.PI * Math.pow(radius, 2)))) <= 0.2)  
            {
                Core.circle(src, new Point(rect.x + radius, rect.y + radius), radius, new Scalar(255,0,0), 2);
                System.out.println("pupil");
            }
        }

        Highgui.imwrite("processed.jpg", src);
    }
}

显示以下错误

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file ..\..\..\..\opencv\modules\imgproc\src\color.cpp, line 3739
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: ..\..\..\..\opencv\modules\imgproc\src\color.cpp:3739: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor
]
    at org.opencv.imgproc.Imgproc.cvtColor_1(Native Method)
    at org.opencv.imgproc.Imgproc.cvtColor(Imgproc.java:4598)
    at Detect.main(Detect.java:24)

1 个答案:

答案 0 :(得分:2)

我认为OpenCV认为"tt.jpg"已经是单通道。

根据documentation

  

该功能通过内容而不是文件扩展名确定图像的类型。

要确保格式,您可以使用标志:

Mat src = Highgui.imread("tt.jpg"); // OpenCV decides the type based on the content
Mat src = Highgui.imread("tt.jpg", Highgui.IMREAD_GRAYSCALE); // single-channel image will be loaded, even if it is a 3-channel image
Mat src = Highgui.imread("tt.jpg", Highgui.IMREAD_COLOR); // 3-channel image will be loaded, even if it is a single-channel image

如果您只需要灰度图像:

Mat src = Highgui.imread("tt.jpg", Highgui.IMREAD_GRAYSCALE);