【问题标题】:Android: Shape detection with JavaCVAndroid:使用 JavaCV 进行形状检测
【发布时间】:2017-04-22 02:36:31
【问题描述】:

我是 JavaCV 的新手。我正在尝试检测图像中最大的矩形并在原始图像上用颜色勾勒它。我在下面发布了我尝试过的代码,但它不起作用。我得到edgeDetectedImage 正确。我正确地获得了 4 个角点。只是cvDrawLine 不起作用。如果我遗漏了什么,请帮忙:

按钮的OnClick 我正在处理图像并在ImageView 上再次显示它。 在onClickListener的按钮:

if ((new File(path + "trial.jpg")).exists()) {
   opencv_core.IplImage originalImage = opencv_imgcodecs.cvLoadImage(path + "trial.jpg", opencv_imgcodecs.CV_IMWRITE_JPEG_QUALITY);
   opencv_core.IplImage iplImage = opencv_imgcodecs.cvLoadImage(path + "trial.jpg", opencv_imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
   opencv_core.IplImage edgeDetectedImage = applyCannyRectangleEdgeDetection(iplImage, 80);
   opencv_core.CvSeq largestContour = findLargestContour(edgeDetectedImage);
   opencv_core.CvPoint[] cvPoints = new opencv_core.CvPoint[4];
   for(int i=0; i<largestContour.total();i++)
   {
     opencv_core.CvPoint cvPoint = new opencv_core.CvPoint(cvGetSeqElem(largestContour, i));
     cvPoints[i] = cvPoint;
   }
   cvDrawLine(originalImage, cvPoints[0], cvPoints[1], opencv_core.CvScalar.YELLOW, 10, 10, 10);
   cvDrawLine(originalImage, cvPoints[1], cvPoints[2], opencv_core.CvScalar.YELLOW, 10, 10, 10);
   cvDrawLine(originalImage, cvPoints[2], cvPoints[3], opencv_core.CvScalar.YELLOW, 10,10, 10);
   cvDrawLine(originalImage, cvPoints[3], cvPoints[0], opencv_core.CvScalar.YELLOW, 10, 10,10);
   opencv_imgcodecs.cvSaveImage(path + "img1.jpg", originalImage);
                    if ((new File(path + "img1.jpg").exists())) {
                        imageView.setImageDrawable(Drawable.createFromPath(path + "img1.jpg"));
                    }
                }

方法 applyCannyRectangleEdgeDetection(IplImage, int):

private opencv_core.IplImage applyCannyRectangleEdgeDetection(opencv_core.IplImage iplImage, int percent) {
    opencv_core.IplImage destImage = downScaleImage(iplImage, percent);
    OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat();
    Frame grayImageFrame = converterToMat.convert(destImage);
    opencv_core.Mat grayImageMat = converterToMat.convertToMat(grayImageFrame);
    GaussianBlur(grayImageMat, grayImageMat, new opencv_core.Size(5, 5), 0.0, 0.0, BORDER_DEFAULT);
    destImage = converterToMat.convertToIplImage(grayImageFrame);
    cvErode(destImage, destImage);
    cvDilate(destImage, destImage);
    cvCanny(destImage, destImage, 20, 55);
    return destImage;
}

方法downScaleImage(IplImage, int)

private opencv_core.IplImage downScaleImage(opencv_core.IplImage srcImage, int percent) {
    opencv_core.IplImage destImage = cvCreateImage(cvSize((srcImage.width() * percent) / 100, (srcImage.height() * percent) / 100), srcImage.depth(), srcImage.nChannels());
    cvResize(srcImage, destImage);
    return destImage;
}

方法 findLargestContour(IplImage)

private opencv_core.CvSeq findLargestContour(opencv_core.IplImage edgeDetectedImage) {
    opencv_core.IplImage foundContoursOfImage = cvCloneImage(edgeDetectedImage);
    opencv_core.CvMemStorage memory = new opencv_core.CvMemStorage().create();
    opencv_core.CvSeq contours = new opencv_core.CvSeq();
    cvFindContours(foundContoursOfImage, memory, contours, Loader.sizeof(opencv_core.CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, new opencv_core.CvPoint(0, 0));
    int maxWidth = 0;
    int maxHeight = 0;
    opencv_core.CvRect contr = null;
    opencv_core.CvSeq seqFound = null;
    opencv_core.CvSeq nextSeq;
    for (nextSeq = contours; nextSeq != null; nextSeq = nextSeq.h_next()) {
        contr = cvBoundingRect(nextSeq, 0);
        if ((contr.width() >= maxWidth) && (contr.height() >= maxHeight)) {
            maxHeight = contr.height();
            maxWidth = contr.width();
            seqFound = nextSeq;
        }
    }
    opencv_core.CvSeq result = cvApproxPoly(seqFound, Loader.sizeof(opencv_core.CvContour.class), memory, CV_POLY_APPROX_DP, cvContourPerimeter(seqFound) * 0.1, 0);
    return result;
}

【问题讨论】:

    标签: android opencv image-processing javacv edge-detection


    【解决方案1】:

    抱歉,这应该在 cmets 中,但我没有足够的声誉。我从您的代码中可以看出,canny 应用于缩小的图像,轮廓也是如此。您正在原始图像上绘制线条(未按百分比缩小),因此自然看起来不正确(如果看起来不正确但正在绘制某些东西)。否则,您应该提及图像的色彩空间,这对于绘图无关紧要,但对于精明。

    【讨论】:

    • 我正在从缩小的图像中获取点并在图像上绘图。所有的缩小和精明操作都是为了获得这 4 个角点。并使用这些点在原始图像上画线。根据您所说的,尽管尺寸在原始图像上不合适,但至少应该在图像上绘制一些东西。就我而言,图像上没有绘制任何内容。
    • 能贴出图片和角点吗?如果没有,您是否用图像验证了矩形角的坐标?
    • 因为从您的代码看来,轮廓是从您正在绘制的原始图像大小的 0.8 倍的图像中提取的。另外,您使用的是什么版本的 OpenCV?
    猜你喜欢
    • 2012-05-18
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 2014-07-25
    • 2014-03-28
    相关资源
    最近更新 更多