首页 > 解决方案 > Opencv findContour

问题描述

我正在做一个检测伤口的项目,伤口类型如下附件命名(原件)。

我曾尝试使用以下方法来检测感兴趣的伤口区域。但是,检测结果不是我想要达到的(见附件命名(outputFromAboveMethod))。我希望达到的最终结果在附件中,名为(WhatIWant)

任何人都可以帮助我吗?

当前方法的代码:

public class DetectTask extends AsyncTask<Integer, Bitmap, Bitmap> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dlg.setMessage("Processing");
            dlg.show();
        }

        @Override
        protected Bitmap doInBackground(Integer... params) {
            Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(), CvType.CV_8UC3);
            Utils.bitmapToMat(bitmap, mat);

            Mat rgbMat = new Mat();
            Imgproc.cvtColor(mat, rgbMat, Imgproc.COLOR_RGBA2BGR);

            Mat dilatedMat = new Mat();
            Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(7, 7));
            Imgproc.morphologyEx(rgbMat, dilatedMat, Imgproc.MORPH_OPEN, kernel);

            //red
            Mat redMat = new Mat();
            Core.inRange(rgbMat, new Scalar(0, 0, 120), new Scalar(100, 100, 255), redMat);

            //find contour
            Mat hierarchy = new Mat();
            List<MatOfPoint> contours = new ArrayList<>();

            Imgproc.findContours(redMat, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
            double largest_area =0;
            int largest_contour_index = 0;

            for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
                double contourArea = Imgproc.contourArea(contours.get(contourIdx));
                if (contourArea > largest_area) {
                    largest_area = contourArea;
                    largest_contour_index = contourIdx;
                }
            }

            Imgproc.drawContours(mat, contours, largest_contour_index, new Scalar(0, 255, 0, 255), 3);
            Bitmap outputImage= Bitmap.createBitmap(mat.cols(), mat.rows(), Bitmap.Config.ARGB_8888);
            Utils.matToBitmap(mat, outputImage);

            return outputImage;
        }

        @Override
        protected void onPostExecute(final Bitmap outputImage) {
            imageview.setImageBitmap(outputImage);
            dlg.dismiss();

        }
    }

原图

outputFromAboveMethod

我想要的是

后凸包

标签: javaandroidimageopencvcontour

解决方案


更改代码以绘制找到的轮廓的凸包几乎可以满足您的需求。凸包是轮廓的“轮廓”。例子: 在此处输入图像描述

此代码获取 findContours() 的输出并创建凸包列表。

    List<MatOfPoint> hullList = new ArrayList<>();
    for (MatOfPoint contour : contours) {
        MatOfInt hull = new MatOfInt();
        Imgproc.convexHull(contour, hull);
        Point[] contourArray = contour.toArray();
        Point[] hullPoints = new Point[hull.rows()];
        List<Integer> hullContourIdxList = hull.toList();
        for (int i = 0; i < hullContourIdxList.size(); i++) {
            hullPoints[i] = contourArray[hullContourIdxList.get(i)];
        }
        hullList.add(new MatOfPoint(hullPoints));
    }

你可以画一个凸包

Imgproc.drawContours(drawing, hullList, index, color );

检查本教程,它包含一个工作示例。


推荐阅读