OpenCV - Java - 如何删除群集周围的一些像素

时间:2016-05-18 21:47:25

标签: java opencv image-processing

我正在做一个项目,我需要识别图像的某些区域。在处理完图像并删除所有不必要的东西后,我终于得到了我需要的区域,如图中所示(绿色圆圈内的区域)。

我无法使用OpenCV在该区域周围画圆圈。我目前正在使用OpenCV的Java版本。如果有人能指出我如何在图像上实现绿色圆圈的正确方向,那将非常有帮助。

我试图检测那个区域的事情。 斑点探测器 - 没有达到太多。 群集 - 与blob检测器相同。 HoughCircles - 在图像中绘制不必要的圆圈。 FindContour - 没有绘制任何东西,因为它不是一个完美的圆形,椭圆形或任何其他众所周知的多边形。

感谢您的帮助。

After processing I want image to look as shown below

2 个答案:

答案 0 :(得分:1)

这是一个解决方案:

  1. 打开以清洁所有细长图案的图像。
  2. 连接组件标签以计算剩余模式
  3. 每个剩余模式的大小计数
  4. 最大的模式是你要圈的那个。
  5. 注意:你想要完美地保留图案,你可以通过重建(侵蚀+测地重建)替换开口。

答案 1 :(得分:0)

我终于找到了解决问题的方法。我使用了OpenCV库中的特征检测器,并为检测器提供了正确的阈值。这对我有用。 Java中的代码如下所示。

public static void main(String[] args){
    try{
        //Validation whether a file name is passed to the function
        if(args.length == 0){
            System.out.println("here...");
            log.error("No file was passed to the function");
            throw new IOException();
        }

        //Read the image from the input
        Mat inputMat = Highgui.imread(args[0],Highgui.CV_LOAD_IMAGE_GRAYSCALE);

        //Create a feature detector. In this case we are using SURF (Speeded-Up Robust Features) detector. 
        MatOfKeyPoint objectKeyPoints = new MatOfKeyPoint();
        FeatureDetector featureDetector = FeatureDetector.create(FeatureDetector.SURF);

        //A temporary file is created to input Hessian Threshold to the SURF detector
        File tempFile = File.createTempFile("config", ".yml");
        String settings = "%YAML:1.0\nhessianThreshold: 7000.\noctaves: 3\noctaveLayers: 4\nupright: 0\n";
        FileWriter writer = new FileWriter(tempFile, false);
        writer.write(settings);
        writer.close();

        //Read the configuration from the temporary file to assign the threshold for the detector
        featureDetector.read(tempFile.getPath());

        //Detect the features in the image provided
        featureDetector.detect(inputMat, objectKeyPoints);

        //Iterate through the list of key points detected in the previous step and find the Key Point with the largest size
        List<KeyPoint> objectKeyPointList = objectKeyPoints.toList();
        KeyPoint impKeyPoint = new KeyPoint();

        for(int i=0; i<objectKeyPointList.size(); i++){
            if(impKeyPoint == null){
                impKeyPoint = objectKeyPointList.get(i);
            }
            else if(impKeyPoint.size < objectKeyPointList.get(i).size){
                impKeyPoint = objectKeyPointList.get(i);
            }
        }

        //If the size of the Key Point is greater than 120 then reduce the size to 120 and if the size is less than 120 then increase to 120 
        if(impKeyPoint.size > 120){
            KeyPoint tempKeyPoint = new KeyPoint();
            tempKeyPoint = impKeyPoint;
            tempKeyPoint.size = 120;
            impKeyPoint = tempKeyPoint;
        }
        else if(impKeyPoint.size < 120){
            KeyPoint tempKeyPoint = new KeyPoint();
            tempKeyPoint = impKeyPoint;
            tempKeyPoint.size = 120;
            impKeyPoint = tempKeyPoint;
        }

        //Convert the Key Point to MatOfKeyPoint since drawKeyPoints accepts only MatOfKeyPoint
        MatOfKeyPoint impMatOfKeyPoint = new MatOfKeyPoint(impKeyPoint);

        //Mat for drawing the circle in the image
        Mat outputImage = new Mat(inputMat.rows(), inputMat.cols(), Highgui.CV_LOAD_IMAGE_COLOR);

        //Green color for the circle
        Scalar greenCircle = new Scalar(0, 255, 0);

        //Draw the circle around the optic nerve when detected
        Features2d.drawKeypoints(inputMat, impMatOfKeyPoint, outputImage, greenCircle, Features2d.DRAW_RICH_KEYPOINTS);

        //Write the image to a file
        Highgui.imwrite("surf_keypoints.png", outputImage);
    }catch(Exception e){
        log.fatal(e.getMessage());
    }

}

希望这对其他人有帮助。