从一堆对象中提取一个对象并检测边缘 [英] Extract one object from bunch of objects and detect edges

查看:142
本文介绍了从一堆对象中提取一个对象并检测边缘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的大学项目,我需要通过检测叶片的边缘从植物叶片形状中识别植物的种类。 (我使用OpenCV 2.4.9和C ++),但源图像已经采取了植物的真实环境,并有多个叶。请参阅下面的示例图像。所以这里我需要提取一个叶子的边缘模式来进一步处理。





使用Canny边缘检测器可以识别整个图像的边缘。



>



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



提前感谢。



strong>编辑



正如Luis所说,我在使用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. 用于删除某些背景数据的阈值二进制图片

     阈值(img_edge_detected,img_threshold,1,255,THRESH_BINARY_INV); 


  5. 图像的形态关闭

      morphologyEx(img_threshold,img_closed,MORPH_CLOSE,getStructuringElement(MORPH_ELLIPSE,Size(2,2))); 




src =http:/

/i.stack.imgur.com/tP3Ci.pngalt =enter image description here>



第二张图片的来源图片和结果



资料来源:





结果:





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

请注意,我的最终目标是使用真实的环境图像创建植物识别系统,但是在这里我不能使用模板匹配或掩盖类型的东西,因为用户必须



这是完整的代码

  #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;
//加载原始图像
img_src = imread(E:\\IMAG0196.jpg);

//应用双边滤波器以减少噪声
bilateralFilter(img_src,img_blur,31,31 * 2,31/2);

//通过直方图均衡调整对比度
cvtColor(img_blur,img_equalized,CV_BGR2GRAY);

//应用Canny边缘检测器
Canny(img_equalized,img_edge_detected,20,60,3);

//删除一些背景数据的阈值二进制映像
threshold(img_edge_detected,img_threshold,15,255,THRESH_BINARY_INV);

//图像的形态接近
morphologyEx(img_threshold,img_closed,MORPH_CLOSE,getStructuringElement(MORPH_ELLIPSE,Size(2,2)));

imshow(Result,img_closed);
waitKey(0);
return 0;
}

谢谢。






  • 不过,我有几件事要完成才能改善结果。路线图将是:




    • 在图表中定义掩码(如其在文档中所述)



  • 移除所有触摸图片边框的边缘可以帮助识别较大的边缘
  • b
    $ b

    好吧,我希望它能帮助


    For my college project I need to identify a species of a plant from plant leaf shape by detecting edges of a leaf. (I use OpenCV 2.4.9 and C++), but the source image has taken in the real environment of the plant and has more than one leaf. See the below example image. So here I need to extract the edge pattern of just one leaf to process further.

    Using Canny Edge Detector I can identify edges of the whole image.

    But I don't know how to proceed from here to extract edge pattern of just one leaf, may be more clear and complete leaf. I don't know even if this is possible also. Can anyone please tell me if this is possible how to extract edges of one leaf I just want to know the image peocessing steps that I need to apply to the image. I don't want any code samples. I'm new to image processing and OpenCV and learning by doing experiments.

    Thanks in advance.

    Edit

    As Luis said said I have done Morphological close to the image after doing edge detection using Canny edge detection, but it seems still it is difficult me to find the largest contour from the image. Here are the steps I have taken to process the image

    1. Apply Bilateral Filter to reduce noise

      bilateralFilter(img_src, img_blur, 31, 31 * 2, 31 / 2);
      

    2. Adjust contrast by histogram equaliztion

      cvtColor(img_blur,img_equalized,CV_BGR2GRAY);
      

    3. Apply Canny edge detector

      Canny(img_equalized, img_edge_detected, 20, 60, 3);
      

    4. Threshold binary image to remove some background data

      threshold(img_edge_detected, img_threshold, 1, 255,THRESH_BINARY_INV);
      

    5. Morphological close of the image

      morphologyEx(img_threshold, img_closed, MORPH_CLOSE, getStructuringElement(MORPH_ELLIPSE, Size(2, 2)));
      

    Following are the resulting images I'm getting.

    This result I'm getting for the above original image

    Source image and result for second image

    Source :

    Result :

    Is there any way to detect the largest contour and extract it from the image ?

    Note that my final target is to create a plant identification system using real environmental image, but here I cannot use template matching or masking kind of things because the user has to take an image and upload it so the system doesn't have any prior idea about the leaf.

    Here is the full code

    #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;
    }
    

    Thank you.

    解决方案

    Well there is a similar question that was asked here:

    It seems that edge information is not a good descriptor for the image, still if you want to try it I'll do the following steps:

    1. Load image and convert it to grayscale
    2. Detect edges - Canny, Sobel try them and find what it suits you best
    3. Set threshold to a given value that eliminates most background - Binarize image
    4. Close the image - Morphological close dont close the window!
    5. Count and identify objects in the image (Blobs, Watershed)
    6. Check each object for a shape (assuming you have described shapes of the leaf you could find before or a standard shape like an ellipse) features like:
    7. If a given object has a given shape that you described as a leaf then you detected the leaf!.

    I believe that given images are taken in the real world these algorithm will perform poorly but it's a start. Well hope it helps :).

    -- POST EDIT 06/07

    Well since you have no prior information about the leaf, I think the best we could do is the following:

    • Load image
    • Bilateral filter
    • Canny
    • Extract contours
    • Assume: that the contour with the largest perimeter is the leaf
    • Convex hull the 3 or 2 largest contours (the blue line is the convex hull done)
    • Use this convex hull to do a graph cut on the image and segmentate it

    If you do those steps, you'll end up with images like these:

    I won't post the code here, but you can check it out in my messy github. I hope you don't mind it was made in python.

    Leaf - Github

    Still, I have a couple of things to finish that could improve the result.. Roadmap would be:

    • Define the mask in the graphcut (like its described in the doc)
    • Apply region grow may give a better convex hull
    • Remove all edges that touch the border of the image can help to identify larger edges

    Well, again, I hope it helps

    这篇关于从一堆对象中提取一个对象并检测边缘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆