Extract one object from bunch of objects and detect edges

为君一笑 提交于 2019-12-18 13:37:49

问题


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.


回答1:


Well there is a similar question that was asked here:

  • opencv matching edge images

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:
    • http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html
    • http://www.math.uci.edu/icamp/summer/research_11/park/shape_descriptors_survey.pdf
  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



来源:https://stackoverflow.com/questions/24435268/extract-one-object-from-bunch-of-objects-and-detect-edges

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!