复杂背景下的实时对象识别

时间:2016-07-28 12:56:15

标签: algorithm opencv image-processing computer-vision object-detection

我试图使用Android智能手机在道路上进行实时广告广告牌检测。目标是裁剪广告广告牌对象(感兴趣的区域)的区域并将其保存到数据库。

例如: enter image description here

enter image description here

对于预处理,我使用了灰度和Canny边缘检测(Otsu阈值用于设置上限和下限)。然后,我使用基于轮廓的方法通过检查点来检测对象是否是矩形。我在android studio中使用Java OpenCV来实现。当我运行程序时,它只检测普通背景中的矩形对象,如果矩形与背景具有高对比度。目前,它只能检测90度的矩形,并且无法检测圆角矩形的对象。此外,我的程序完全无法在更复杂的背景中检测矩形物体,例如道路场景,我试图检测的物体具有与背景相似的颜色/低对比度,或者有许多遮挡物,如树,交通信号灯和导致检测失败的电缆。

这是我用于边缘检测的代码

Mat destination = new Mat(oriMat.rows(), oriMat.cols(), oriMat.type());
    Imgproc.cvtColor(oriMat, destination, Imgproc.COLOR_RGBA2GRAY);

    Imgproc.GaussianBlur(destination, destination, new Size(3,3), 0, 0, Imgproc.BORDER_DEFAULT);

    double otsuThresholdValue = Imgproc.threshold(destination, destination, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
    double lowerThreshold = otsuThresholdValue*0.5;
    double upperThreshold = otsuThresholdValue;

    Mat canny = new Mat();
    Imgproc.Canny(destination, canny, lowerThreshold, upperThreshold);

    Mat abs = new Mat();
    Core.convertScaleAbs(canny, abs);

    Mat result = new Mat();
    Core.addWeighted(abs, 0.5, abs, 0.5, 0, result);

这是我用于基于轮廓的检测的代码

ArrayList<MatOfPoint> contours = new ArrayList<>();

        // find contours and store them all as a list
        Imgproc.findContours(matData.monoChrome.clone(), contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        final int width = matData.monoChrome.rows();
        final int height = matData.monoChrome.cols();
        int matArea = width * height;
        for (int i = 0; i < contours.size(); i++) {
            double contoursArea = Imgproc.contourArea(contours.get(i));
            MatOfPoint2f approx = new MatOfPoint2f();
            MatOfPoint2f contour = new MatOfPoint2f(contours.get(i).toArray());
            double epsilon = Imgproc.arcLength(contour, true) * 0.1;

            // Imgproc.minAreaRect(contour);

            // approximate contour with accuracy proportional to the contour perimeter
            Imgproc.approxPolyDP(contour, approx, epsilon, true);
            if (Math.abs(contoursArea) < matArea * 0.01 ||
                    !Imgproc.isContourConvex(new MatOfPoint(approx.toArray()))) {
                continue;
            }
            Imgproc.drawContours(matData.resizeMat, contours, i, new Scalar(0, 255, 0));

            List<Point> points = approx.toList();
            int pointCount = points.size();
            LinkedList<Double> cos = new LinkedList<>();
            for (int j = 2; j < pointCount + 1; j++) {
                cos.addLast(angle(points.get(j % pointCount), points.get(j - 2), points.get(j - 1)));
            }
            Collections.sort(cos, (lhs, rhs) -> lhs.intValue() - rhs.intValue());
            double mincos = cos.getFirst();
            double maxcos = cos.getLast();
            if (points.size() == 4 && mincos >= -0.3 && maxcos <= 0.5) {
                for (int j = 0; j < points.size(); j++) {
                    Core.circle(matData.resizeMat, points.get(j), 6, new Scalar(255, 0, 0), 6);
                }
                matData.points = points;

                break;
            }
        }

有什么方法可以用来识别道路上的广告牌? 我很感激任何答案和想法。谢谢!

0 个答案:

没有答案