当前位置: 首页 > 知识库问答 >
问题:

二值阈值图像->应用canny边缘检测->FindOnTour(),这是否改善了轮廓检测?

宓昂雄
2023-03-14

我试图检测黄色物体。我在HSV配色方案中执行颜色分割,使用cvInRange阈值到黄色范围,它返回一个二进制阈值蒙版,检测到的区域显示为白色,而其他颜色被忽略和涂黑。我认为获取边缘不仅会减少findConTour()的计算,还会使边缘平面的变化更加明显。因此,而不是这样做:

    binary thresholded image -> findContour()

我做到了:

    binary thresholded image -> Canny() -> findContour() instead.

请参阅下面显示的图像帧输出的代码附加图片。

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {

     InputFrame = inputFrame.rgba();

     Core.transpose(InputFrame,mat1); //transpose mat1(src) to mat2(dst), sorta like a Clone!
     Imgproc.resize(mat1,mat2,InputFrame.size(),0,0,0);    // params:(Mat src, Mat dst, Size dsize, fx, fy, interpolation)   Extract the dimensions of the new Screen Orientation, obtain the new orientation's surface width & height.  Try to resize to fit to screen.
     Core.flip(mat2,InputFrame,-1);   // mat3 now get updated, no longer is the Origi inputFrame.rgba BUT RATHER the transposed, resized, flipped version of inputFrame.rgba().

     int rowWidth = InputFrame.rows();
     int colWidth = InputFrame.cols();

     Imgproc.cvtColor(InputFrame,InputFrame,Imgproc.COLOR_RGBA2RGB);
     Imgproc.cvtColor(InputFrame,InputFrame,Imgproc.COLOR_RGB2HSV);


 //============= binary threshold image to Yellow mask ============
     Lower_Yellow = new Scalar(21,150,150);    //HSV color scale  H to adjust color, S to control color variation, V is indicator of amt of light required to be shine on object to be seen.
     Upper_Yellow = new Scalar(31,255,360);    //HSV color scale

     Core.inRange(InputFrame,Lower_Yellow, Upper_Yellow, maskForYellow);


 //============== Apply Morphology to remove noise ===================
     final Size kernelSize = new Size(5, 5);  //must be odd num size & greater than 1.
     final Point anchor = new Point(-1, -1);   //default (-1,-1) means that the anchor is at the center of the structuring element.
     final int iterations = 1;   //number of times dilation is applied.  https://docs.opencv.org/3.4/d4/d76/tutorial_js_morphological_ops.html

     Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, kernelSize);

     Imgproc.morphologyEx(maskForYellow, yellowMaskMorphed, Imgproc.MORPH_CLOSE, kernel, anchor, iterations);   //dilate first to remove then erode.  White regions becomes more pronounced, erode away black regions


 //=========== Apply Canny to obtain edge detection ==============
     Mat mIntermediateMat = new Mat();
     Imgproc.GaussianBlur(yellowMaskMorphed,mIntermediateMat,new Size(9,9),0,0);   //better result than kernel size (3,3, maybe cos reference area wider, bigger, can decide better whether inrange / out of range.
     Imgproc.Canny(mIntermediateMat, mIntermediateMat, 5, 120);   //try adjust threshold   //https://stackoverflow.com/questions/25125670/best-value-for-threshold-in-canny


 //============ apply findContour()==================
     List<MatOfPoint> contours = new ArrayList<>();
     Mat hierarchy = new Mat();
     Imgproc.findContours(mIntermediateMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));   


 //===========  Use contourArea to find LargestBlob contour ===============
     double maxArea1 = 0;
     int maxAreaIndex1 = 0;
     //MatOfPoint max_contours = new MatOfPoint();
     Rect r = null;
     ArrayList<Rect> rect_array = new ArrayList<Rect>();

     for(int i=0; i < contours.size(); i++) {
         //if(Imgproc.contourArea(contours.get(i)) > 300) {   //Size of Mat contour @ that particular point in ArrayList of Points.
         double contourArea1 = Imgproc.contourArea(contours.get(i));    
        //Size of Mat contour @ that particular point in ArrayList of Points.
             if (maxArea1 < contourArea1){
                 maxArea1 = contourArea1;
                 maxAreaIndex1 = i;
             }
             //maxArea1 = Imgproc.contourArea(contours.get(i));  //assigned but nvr used
             //max_contours = contours.get(i);
             r = Imgproc.boundingRect(contours.get(maxAreaIndex1));    
             rect_array.add(r);  //will only have 1 r in the array eventually, cos we will only take the one w largestContourArea.
     }


     Imgproc.cvtColor(InputFrame, InputFrame, Imgproc.COLOR_HSV2RGB);


 //============ plot largest blob contour ================
     if (rect_array.size() > 0) {   //if got more than 1 rect found in rect_array, draw them out!

         Iterator<Rect> it2 = rect_array.iterator();    //only got 1 though, this method much faster than drawContour, wont lag. =D
         while (it2.hasNext()) {
             Rect obj = it2.next();
             //if
             Imgproc.rectangle(InputFrame, obj.br(), obj.tl(),
                 new Scalar(0, 255, 0), 1);
         }

     }

原始黄色对象1

HSV颜色空间中的对象2

在cvInrRange变为黄色后-返回二进制阈值掩码3

应用Canny边缘检测4后返回的边缘

共有1个答案

司空温书
2023-03-14

我尝试了这两种方法,发现在阈值图像上应用Canny()有助于使检测更快、更稳定,因此我在代码中保留了这一部分。我的猜测是,在我们应用Canny()之后,可能需要计算的点更少,这也有助于使边缘更明显,因此变得更容易

 类似资料:
  • Canny边缘检测用于检测图像中的边缘。 它接受灰度图像作为输入,并使用多级算法。可以使用类的方法在图像上执行此操作,以下是此方法的语法。 该方法接受以下参数 - image - 表示此操作的源(输入图像)的对象。 edges - 表示此操作的目标(边缘)的对象。 threshold1 - 类型为的变量表示滞后过程的第一个阈值。 threshold2 - 类型为的变量表示滞后过程的第二个阈值。 示

  • 目标 在这一章中,我们将学习 Canny 边缘检测的概念 OpenCV 的 Canny 边缘检测函数:cv2.Canny() 理论基础 Canny边缘检测是一种流行的边缘检测算法。它是由 John F. Canny 于 1986 年开发的。它是一个多阶段算法,我们将学习每个阶段做了什么。 降噪 由于边缘检测容易受到图像中的噪声影响,因此首先要用5x5高斯滤波器去除图像中的噪声。我们在前面的章节已经

  • 目标 在本章中,我们将学习 Canny边缘检测的概念 OpenCV函数: cv.Canny() 理论 Canny Edge Detection是一种流行的边缘检测算法。它由John F. Canny发明 这是一个多阶段算法,我们将经历每个阶段。 降噪 由于边缘检测容易受到图像中噪声的影响,因此第一步是使用5x5高斯滤波器消除图像中的噪声。我们已经在前面的章节中看到了这一点。 查找图像的强度梯度 然

  • 本文向大家介绍python实现canny边缘检测,包括了python实现canny边缘检测的使用技巧和注意事项,需要的朋友参考一下 canny边缘检测原理 canny边缘检测共有5部分组成,下边我会分别来介绍。 1 高斯模糊(略) 2 计算梯度幅值和方向。 可选用的模板:soble算子、Prewitt算子、Roberts模板等等; 一般采用soble算子,OpenCV也是如此,利用soble水平和

  • 我想提取图像的轮廓,用点坐标序列表示。 使用,我能够生成一个只包含图像边缘的二进制图像。然后,我尝试使用来提取轮廓。不过,结果并不好。 对于每一条边,我通常得到两条线,就像它被认为是一个非常薄的区域一样。我想简化我的轮廓,这样我可以把它们画成单线。或者用不同的函数提取它们,直接产生正确的结果会更好。 我查看了OpenCV的文档,但没有找到任何有用的东西,但我想我不是第一个遇到类似问题的人。有什么功

  • 我目前正在阅读OpenCV网站tyring上的示例代码,以查找图像中的轮廓。 我首先读取图像并转换为灰度: 然后,我通过应用阈值将图像转换为二进制: 根据教程...然后,我应该能够调用阈值图像上的: 当尝试执行此代码时,由于某种原因,我得到一个类型错误: 轮廓=cv2。findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_Abrox_SIMPLE)类型错误:图像不