gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:36:28 27 4
gpt4 key购买 nike

在我的大学项目中,我需要通过检测叶子的边缘来根据植物叶子的形状来识别植物的种类。 (我使用的是OpenCV 2.4.9和C++),但是源图是在植物的真实环境中拍摄的,而且不止一片叶子。请参阅下面的示例图像。所以这里我只需要提取一片叶子的边缘图案来进一步处理。

enter image description here

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

enter image description here

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

提前致谢。

编辑

正如 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. 去除一些背景数据的阈值二值图像

    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)));

以下是我得到的结果图像。

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

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. 加载图像并将其转换为灰度
  2. 检测边缘 - Canny、Sobel 尝试它们并找到最适合您的方法
  3. 将阈值设置为消除大部分背景的给定值 - 二值化图像
  4. 关闭图像 - 形态关闭不要关闭窗口!
  5. 计算并识别图像中的对象( Blob 、分水岭)
  6. 检查每个对象的形状(假设您已经描述了之前可以找到的叶子形状或标准形状,如椭圆),例如:
  7. 如果给定的对象具有您描述为叶子的给定形状,那么您就检测到了叶子!

我相信给定图像是在现实世界中拍摄的,这些算法的性能会很差,但这只是一个开始。希望对您有所帮助:)。

-- 发布编辑 06/07

既然你没有关于叶子的先验信息,我认为我们能做的最好的事情如下:

  • 载入图片
  • 双边过滤器
  • 精明
  • 提取轮廓
  • 假设:周长最大的轮廓是叶子
  • Convex hull the 3 or 2 largest contours(蓝线是完成的凸包)
  • 使用这个凸包对图像进行图切并分割

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

Leaf 1 segmentation

Leaf 2 segmentation

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

Leaf - Github

不过,我还有一些事情要完成,可以改善结果。路线图是:

  • 在图形中定义掩码(如文档中所述)
  • 应用区域增长可以得到更好的凸包
  • 移除所有接触图像边界的边缘有助于识别较大的边缘

再说一遍,希望对你有帮助

关于c++ - 从一堆对象中提取一个对象并检测边缘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24435268/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com