从一堆对象中提取一个对象并检测边缘

时间:2014-06-26 16:02:24

标签: c++ opencv image-processing feature-detection edge-detection

对于我的大学项目,我需要通过检测叶子的边缘来鉴定植物叶子形状的植物种类。 (我使用的是OpenCV 2.4.9和C ++),但是源图像已经在工厂的真实环境中获得并且具有多个叶子。请参见下面的示例图像。所以在这里我需要提取一个叶子的边缘模式以进一步处理。

enter image description here

使用Canny Edge Detector我可以识别整个图像的边缘。

enter image description here

但是我不知道如何从这里开始提取只有一片叶子的边缘图案,可能会更清晰完整的叶子。我不知道即使这也是可能的。任何人都可以告诉我,如果这是可能的如何提取一片叶子的边缘我只是想知道我需要应用于图像的图像处理步骤。我不想要任何代码示例。我是图像处理和OpenCV的新手,通过实验学习。

提前致谢。

修改

正如路易斯所说,在使用Canny边缘检测进行边缘检测后,我已经完成了与图像接近的形态,但似乎仍然很难从图像中找到最大的轮廓。 以下是我处理图像所采取的步骤

  1. 应用双边滤镜以降低噪音

    bilateralFilter(img_src, img_blur, 31, 31 * 2, 31 / 2);
    
  2. 通过直方图均衡来调整对比度

    cvtColor(img_blur,img_equalized,CV_BGR2GRAY);
    
  3. 应用Canny边缘检测器

    Canny(img_equalized, img_edge_detected, 20, 60, 3);
    
  4. 删除一些背景数据的阈值二进制图像

    threshold(img_edge_detected, img_threshold, 1, 255,THRESH_BINARY_INV);
    
  5. 图像的形态学结束

    morphologyEx(img_threshold, img_closed, MORPH_CLOSE, getStructuringElement(MORPH_ELLIPSE, Size(2, 2)));
    
  6. 以下是我得到的结果图片。

    这个结果我得到的是上面的原始图像

    enter image description here

    第二张图像的源图像和结果

    来源:

    enter image description here

    结果:

    enter image description here

    有没有办法检测最大轮廓并从图像中提取它?

    请注意,我的最终目标是使用真实的环境图像创建植物识别系统,但在这里我不能使用模板匹配或掩盖的东西,因为用户必须拍摄图像并上传它,因此系统没有关于叶子的任何先前想法。

    这是完整的代码

    #include <opencv\cv.h>
    #include <opencv\highgui.h>
    using namespace cv;
    
    int main()
    {
    Mat img_src,     img_blur,img_gray,img_equalized,img_edge_detected,img_threshold,img_closed;
    //Load original image
    img_src = imread("E:\\IMAG0196.jpg");
    
    //Apply Bilateral Filter to reduce noise
    bilateralFilter(img_src, img_blur, 31, 31 * 2, 31 / 2);
    
    //Adjust contrast by histogram equaliztion
    cvtColor(img_blur,img_equalized,CV_BGR2GRAY);
    
    //Apply Canny edge detector
    Canny(img_equalized, img_edge_detected, 20, 60, 3);
    
    //Threshold binary image to remove some background data
    threshold(img_edge_detected, img_threshold, 15, 255,THRESH_BINARY_INV);
    
    //Morphological close of the image
    morphologyEx(img_threshold, img_closed, MORPH_CLOSE, getStructuringElement(MORPH_ELLIPSE, Size(2, 2)));
    
    imshow("Result", img_closed);
    waitKey(0);
    return 0;
    }
    

    谢谢。

1 个答案:

答案 0 :(得分:6)

这里有一个类似的问题:

边缘信息似乎不是图像的良好描述符,但如果您想尝试它,我将执行以下步骤:

  1. 加载图片并将其转换为灰度
  2. 检测边缘 - Canny,Sobel尝试并找到最适合您的方式
  3. 将阈值设置为消除大多数背景的给定值 - 二值化图像
  4. 关闭图像 - 形态关闭不要关闭窗口!
  5. 计算并识别图像中的对象(Blob,Watershed)
  6. 检查每个对象的形状(假设您已经描述了之前可以找到的叶子的形状或像椭圆这样的标准形状),其特征如下:
  7. 如果给定的对象具有您描述为叶子的给定形状,那么您会检测到叶子!
  8. 我相信给定的图像是在现实世界中拍摄的,这些算法表现不佳,但这是一个开始。希望它有所帮助:)。

    - 06月06日编辑

    因为您之前没有关于叶子的信息,我认为我们能做的最好的事情如下:

    • 加载图片
    • 双边过滤器
    • 的Canny
    • 提取轮廓
    • 假设:周长最大的轮廓是叶
    • 凸壳3或2个最大轮廓(蓝线是凸壳完成)
    • 使用此凸包对图像进行图形切割并对其进行细分

    如果您执行这些步骤,您最终会得到以下图片:

    Leaf 1 segmentation

    Leaf 2 segmentation

    我不会在这里发布代码,但你可以在我凌乱的github中查看它。我希望你不要介意它是用python制作的。

    Leaf - Github

    尽管如此,我还有一些事情可以改善结果。路线图将是:

    • 在图表中定义蒙版(如文档中所述)
    • 应用区域生长可以提供更好的凸壳
    • 移除触摸图像边框的所有边缘有助于识别较大边缘

    嗯,再次,我希望它有所帮助

相关问题