获取不同级别的图像边缘

Posted

技术标签:

【中文标题】获取不同级别的图像边缘【英文标题】:Getting edge of image at different level 【发布时间】:2019-02-08 15:31:48 【问题描述】:

我想在板条箱中画出西红柿的边缘。为此,我使用Canny 边缘检测算法。问题在于,在一个板条箱中,一些西红柿在另一个上面,如下图所示:

正如我们所看到的,有些西红柿比其他西红柿有更多的光线,因此 Canny 的结果如下:

正如我们所见,Canny 无法检测到原始图像中光线较弱的板条箱末端的西红柿边缘。

有没有人可以解决这个问题? (不可能在所有西红柿上都获得均匀的光线,但如果有某种算法可以做到这一点,那将非常有帮助。)

这是我的 OpenCV 代码:

#include <opencv2/opencv.hpp>

using namespace cv;

Mat img, img_gray, img_value, fz, fg, I, pre, cost, vis, G, img_draw, in_que, skip, img_canny;

int main()
    std::string filepath = "/Users/vedanshu/Desktop/IMG_5207.JPG";
    img = imread(filepath);
    cvtColor(img, img_gray, cv::COLOR_BGRA2GRAY);
    img_gray.copyTo(img_value);
    GaussianBlur(img_value, img_value, Size(3, 3), 0, 0, BORDER_DEFAULT);
    Canny(img_gray, img_canny, 50, 50);
    imwrite( "/Users/vedanshu/Desktop/test_canny.png", img_canny );

【问题讨论】:

为了获得更好的对比度,您可以尝试CLAHE。此外,您可以尝试使用 Hough circle transform 代替 Canny,来检测“部分”西红柿。不过,对于非圆形西红柿,这可能会失败。 像这样在容器中的每个番茄周围绘制边界是一项不可能完成的任务。但是,如果您陈述您要解决的总体问题,我们可以提出可行的解决方案。 @Ajay 总体问题是从普通番茄中检测缺陷。正如你在图片中看到的,有些西红柿有一些缺陷,无论如何我必须找到这些缺陷。 在这种情况下,划定边界可能对您确定是否存在缺陷番茄并不重要。我建议您使用带有基于 CNN 的图像分类器的滑动窗口来解决您的问题。我的一般建议是,如果知道对象边界在您的整体目标中不起重要作用,请避免使用边界框进行分割。 【参考方案1】:

我用python回答,它可以很容易地转换为C++。直方图均衡和伽马函数可用于增加灰度图像的对比度。

img = cv2.imread('edge_tomatoes.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('original', gray)
denoise = cv2.fastNlMeansDenoising(gray,None,10,7,21)
hist = cv2.equalizeHist(denoise)
gamma = 2
invGamma = 1/gamma
table = np.array([((i / 255.0) ** invGamma) * 255
                  for i in np.arange(0, 256)]).astype("uint8")
gamm = cv2.LUT(hist, table, hist)
blur = cv2.GaussianBlur(gamm,(3,3),0)
cv2.imshow('modified', hist)
cv2.waitKey(0)
cv2.destroyAllWindows()

此图像显示了原始灰度图像和处理后图像之间的差异。

mask = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
canny = cv2.Canny(mask, 40, 200)
cv2.imshow('result', canny)
cv2.waitKey(0)
cv2.destroyAllWindows()

【讨论】:

以上是关于获取不同级别的图像边缘的主要内容,如果未能解决你的问题,请参考以下文章

图像边缘检测:Canny算子、Prewitt算子和sobel算子

图像边缘检测基于matlab Zernike矩亚像素边缘检测含Matlab源码 1536期

图像处理常用边缘检测算子总结

图像经过Canny算子处理后如何获取边缘位置的像素坐标

边缘检测算子(edge detectors)

图像处理常用边缘检测算子总结