Algorithm 复杂背景下的实时目标识别

Algorithm 复杂背景下的实时目标识别,algorithm,opencv,image-processing,computer-vision,object-detection,Algorithm,Opencv,Image Processing,Computer Vision,Object Detection,我正在尝试使用android智能手机在道路上实时检测广告牌。目标是裁剪广告牌对象(感兴趣区域)的区域并将其保存到数据库中 例如: 对于预处理,我使用灰度缩放和Canny边缘检测(使用Otsu阈值设置上下阈值)。然后,采用基于轮廓的方法通过检测点来检测物体是否为矩形。我在android studio中使用Java OpenCV进行实现。当我运行这个程序时,它只检测普通背景中的矩形物体,如果矩形物体与背景有很高的对比度。目前,它只能检测90度的矩形,无法检测圆形矩形的对象。此外,我的程序完全无法

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

例如:

对于预处理,我使用灰度缩放和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;
            }
        }
下面是我用于基于轮廓的检测的代码

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;
            }
        }
ArrayList等高线=新建ArrayList();
//找到等高线并将其全部存储为列表
Imgproc.findContours(matData.monology.clone()、等高线、new Mat()、Imgproc.RETR\u EXTERNAL、Imgproc.CHAIN\u SIMPLE);
final int width=matData.monology.rows();
最终整数高度=matData.monology.cols();
int matArea=宽度*高度;
对于(int i=0;ilhs.intValue()-rhs.intValue());
double mincos=cos.getFirst();
double maxcos=cos.getLast();
如果(points.size()==4&&mincos>=-0.3&&maxcos