OpenCV使用Harris算法實現角點檢測

純粹閱讀,請移步OpenCV使用Harris算法實現角點檢測

效果圖

效果圖

原圖

源碼

KqwOpenCVFeaturesDemo

角點是兩條邊緣的交點或者在局部鄰域中有多個顯著邊緣方向的點。Harris角點檢測是一種在角點檢測中最常見的技術。

Harris角點檢測器在圖像上使用滑動窗口計算亮度的變化。

封裝

這裏用到了RxJava。主要是因爲圖片處理是耗時操作,會阻塞線程,爲了防止界面卡頓,這裏使用RxJava進行了線程切換。

/**
 * Harris角點檢測
 *
 * @param bitmap 要檢測的圖片
 */
public void harris(Bitmap bitmap) {
    if (null != mSubscriber)
        Observable
                .just(bitmap)
                // 檢測邊緣
                .map(new Func1<Bitmap, Mat>() {
                    @Override
                    public Mat call(Bitmap bitmap) {
                        Mat grayMat = new Mat();
                        Mat cannyEdges = new Mat();

                        // Bitmap轉爲Mat
                        Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
                        Utils.bitmapToMat(bitmap, src);

                        // 原圖置灰
                        Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY);
                        // Canny邊緣檢測器檢測圖像邊緣
                        Imgproc.Canny(grayMat, cannyEdges, 10, 100);

                        return cannyEdges;
                    }
                })
                // Harris對角檢測
                .map(new Func1<Mat, Bitmap>() {

                    @Override
                    public Bitmap call(Mat cannyEdges) {
                        Mat corners = new Mat();
                        Mat tempDst = new Mat();

                        // 找出角點
                        Imgproc.cornerHarris(cannyEdges, tempDst, 2, 3, 0.04);

                        // 歸一化Harris角點的輸出
                        Mat tempDstNorm = new Mat();
                        Core.normalize(tempDst, tempDstNorm, 0, 255, Core.NORM_MINMAX);
                        Core.convertScaleAbs(tempDstNorm, corners);

                        // 在新的圖像上繪製角點
                        Random r = new Random();
                        for (int i = 0; i < tempDstNorm.cols(); i++) {
                            for (int j = 0; j < tempDstNorm.rows(); j++) {
                                double[] value = tempDstNorm.get(j, i);
                                if (value[0] > 150) {
                                    Core.circle(corners, new Point(i, j), 5, new Scalar(r.nextInt(255), 2));
                                }
                            }
                        }

                        // Mat轉Bitmap
                        Bitmap processedImage = Bitmap.createBitmap(corners.cols(), corners.rows(), Bitmap.Config.ARGB_8888);
                        Utils.matToBitmap(corners, processedImage);

                        return processedImage;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(mSubscriber);
}

使用

// 圖片特徵提取的工具類
mFeaturesUtil = new FeaturesUtil(new Subscriber<Bitmap>() {
    @Override
    public void onCompleted() {
        // 圖片處理完成
        dismissProgressDialog();
    }

    @Override
    public void onError(Throwable e) {
        // 圖片處理異常
        dismissProgressDialog();
    }

    @Override
    public void onNext(Bitmap bitmap) {
        // 獲取到處理後的圖片
        mImageView.setImageBitmap(bitmap);
    }
});

// Harris角點檢測
mFeaturesUtil.harris(mSelectImage);
發佈了198 篇原創文章 · 獲贊 281 · 訪問量 87萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章