OpenCV.霍夫圆

霍夫圆

霍夫圆的变换与霍夫直线类似,其原理较为复杂,这里暂时不以叙述。其检测实现是以灰度图像来找到候选区域,然会进行霍夫检测,以此减少算法的时间复杂度。但该方式极易受到噪声影响,对图像的噪声敏感,故先须进行噪声抑制处理。其函数声明如下:

HoughCircles(image, circles, method, dp, minDist, param1, param2, minRadius, maxRadius);

各参数解释如下:

  • image
    8单位通道的灰度图形。

  • circles
    输出的3个向量的数组,圆心与半径。

  • method
    非可选的基于梯度霍夫变换。

  • dp
    图片分辨率,dp越大,图像就会减少相应的分辨率。

  • minDist
    两圆之间最小距离。

  • param1
    边缘检测中Canny的最高阈值。

  • param2
    累加阈值。

  • minRadius
    检测的最小圆半径,单位像素。

  • maxRadius
    检测的最大圆半径,单位像素。

需要说明的是,霍夫圆检测非常消耗时间,但可以通过指定参数范围来减少时间复杂度。这里的示意图即使肉眼可见为类似五环图,但最终仍检测出了3个圆。

Java代码(JavaFX Controller层)

public class Controller{

    @FXML private Text fxText;
    @FXML private ImageView imageView;

    @FXML public void handleButtonEvent(ActionEvent actionEvent) throws IOException {

        Node source = (Node) actionEvent.getSource();
        Window theStage = source.getScene().getWindow();
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.png");
        fileChooser.getExtensionFilters().add(extFilter);
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JPG Files(*.jpg)", "*.jpg"));
        File file = fileChooser.showOpenDialog(theStage);

        runInSubThread(file.getPath());

    }

    private void runInSubThread(String filePath){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    WritableImage writableImage = houghCircles(filePath);

                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            imageView.setImage(writableImage);
                        }
                    });

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    
    private WritableImage houghCircles(String filePath) throws IOException {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        Mat src = Imgcodecs.imread(filePath);
        Mat dst = new Mat();

        Mat gray = new Mat();
        Imgproc.pyrMeanShiftFiltering(src, gray, 15, 80);
        Imgproc.cvtColor(gray, gray, Imgproc.COLOR_BGR2GRAY);

        Imgproc.GaussianBlur(gray, gray, new Size(3,3), 0);

        Mat circles = new Mat();
        dst.create(src.size(), src.type());
        Imgproc.HoughCircles(gray, circles, Imgproc.HOUGH_GRADIENT, 1, 20,100,25,35,70);
        for (int i = 0; i < circles.cols(); i++) {
            float[] info = new float[3];
            circles.get(0,i, info);
            Imgproc.circle(dst, new Point((int)info[0], (int)info[1]), (int)info[1], new Scalar(255,0,0),2,8,0);
        }

        MatOfByte matOfByte = new MatOfByte();
        Imgcodecs.imencode(".jpg", dst, matOfByte);

        byte[] bytes = matOfByte.toArray();
        InputStream in = new ByteArrayInputStream(bytes);
        BufferedImage bufImage = ImageIO.read(in);

        WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);

        return writableImage;
    }

}


运行图
霍夫圆检测
原图:
五枚便士

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值