【问题标题】:Opencv findContourOpencv findContour
【发布时间】:2019-05-14 10:33:34
【问题描述】:

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

我曾尝试使用以下方法来检测感兴趣的伤口区域。但是,检测结果不是我想要实现的(见附件命名(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();

        }
    }

originalImage

outputFromAboveMethod

WhatIWant

afterConvextHull

【问题讨论】:

    标签: java android image opencv contour


    【解决方案1】:

    更改代码以绘制找到的轮廓的凸包几乎可以满足您的需求。凸包是轮廓的“轮廓”。例子:

    此代码获取 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 );

    检查这个tutorial,它包含一个工作示例。

    【讨论】:

    • 嗨,感谢您的回复,我已在代码中实现了这一点并且它可以工作,但是,检测中仍然存在一些不准确(它检测到红色之外的一些粉红色区域,我没有'不想要,请参阅问题中的图像“afterConvexHull”),您能否建议我如何改进检测,谢谢。
    • 您可以尝试调整您找到的轮廓的形态:docs.opencv.org/3.4/d9/d61/tutorial_py_morphological_ops.html 另一种选择是使用凸包作为遮罩。您可以使用它来创建仅包含船体内部部分的新图像。然后你可以尝试只选择粉红色或非粉红色部分,并使用按位运算从掩码中删除粉红色部分opencvexamples.blogspot.com/2013/10/… 然后掩码具有最终形状。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 2015-11-15
    • 2015-08-18
    相关资源
    最近更新 更多