在opencv中自动计算Canny操作的低和高阈值
image-processing
opencv
4
0

在openCV中,精简运算符的高低阈值是强制性的:

cvCanny(input,output,thresh1,thresh2)

在Matlab中,有一个选项可以自动计算这些值:

edge(input,'canny')

我已经研究了Matlab的edge代码,这对于自动计算这些值并不是很简单。

您是否知道canny运算符的任何实现以及针对opencv的自动阈值计算?

谢谢

参考资料:
Stack Overflow
收藏
评论
共 5 个回答
高赞 时间 活跃

我在寻找一种自动计算Canny阈值的方法时偶然发现了这个答案。

希望这对寻求佳能算法自动阈值确定方法的人有所帮助...


如果您的图像由不同的前景和背景组成,则前景对象的边缘可以通过以下方式使用:

  1. 使用以下方法计算Otsu的阈值:

     double otsu_thresh_val = cv::threshold( orig_img, _img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU ); 

    我们不需要_img 。我们仅对otsu_thresh_val感兴趣,但是不幸的是,当前OpenCV中没有允许您仅计算阈值的方法。

  2. 对于Canny算法,将Otsu的阈值用作较高阈值,并将其一半作为较低阈值。

     double high_thresh_val = otsu_thresh_val, lower_thresh_val = otsu_thresh_val * 0.5; cv::Canny( orig_img, cannyOP, lower_thresh_val, high_thresh_val ); 

与此相关的更多信息可以在本文中找到:Otsu方法在Canny算子中的应用研究 。有关Otsu实施的说明,请参见此处

收藏
评论

您可以使用输入灰度图像的平均值,并使用标准偏差定义上下阈值。您可以在此处获得更详细的说明和opencv代码: http : //www.kerrywong.com/2009/05/07/canny-edge-detection-auto-thresholding/

收藏
评论

我浏览了Matlab Canny边缘检测的源代码,并设法用OpenCV 3用Java编写了它。

private static Mat getpartialedge(Mat image){
    double nonEdgeRate = 0.6;
    double thresholdRate = 0.6;
    double w = image.cols();
    double h = image.rows();
    int bins = 256;
    Mat sobel = new Mat();
    Mat sobelx = new Mat();
    Mat sobely = new Mat();
    Mat sobelxabs = new Mat();
    Mat sobelyabs = new Mat(); 
    Size gsz = new Size(5, 5);
    if(false) {
        Imgproc.Canny(image, sobel, 41, 71);
    }else {

        //Imgproc.GaussianBlur(graycopy,graycopy, gsz, 2);
        //Imgproc.dilate(image, image, kernel8);
        Imgproc.GaussianBlur(image, image, gsz, 2);


        int apertureSize = 3;
        Imgproc.Sobel(image, sobelx, CvType.CV_16S, 1, 0, apertureSize, 1, 0);
        Core.convertScaleAbs(sobelx, sobelxabs);
        Imgproc.Sobel(image, sobely, CvType.CV_16S, 0, 1, apertureSize, 1, 0);
        Core.convertScaleAbs(sobely, sobelyabs);
        Core.addWeighted(sobelxabs, 1, sobelyabs, 1, 0, sobel);
        sobel.convertTo(sobel, CvType.CV_8U);


        Mat equalized = new Mat();
        Imgproc.equalizeHist(sobel, equalized);
        Imgcodecs.imwrite(filePath + "aftersobel(eq).png", equalized);
        Imgcodecs.imwrite(filePath + "aftersobel.png", sobel);


        Mat hist = new Mat();
        List<Mat> matList = new ArrayList<Mat>();
        matList.add(sobel);
        Imgproc.calcHist(matList, new MatOfInt(0), new Mat(), hist, new MatOfInt(bins), new MatOfFloat(0f, 256f));
        float accu = 0;
        float t = (float) (nonEdgeRate * w * h);
        float bon = 0;
        float[] accutemp = new float[bins];
        for (int i = 0; i < bins; i++) {
            float tf[] = new float[1];
            hist.get(i, 0, tf);
            accu = accu + tf[0];
            accutemp[i] = accu;
            if (accu > t) {
                bon = (float) i;
                break;
            }
        }
        Imgproc.threshold(sobel, sobel, bon, 255, Imgproc.THRESH_BINARY);
        double ut = bon;
        double lt = thresholdRate * bon;


        Imgproc.Canny(image, sobel, lt, ut);
        //Imgproc.dilate(sobel, sobel, kernel2);
    }
    return sobel;
}

文件路径是保存输出图像的位置。并且输入图像应该是U8数据类型的灰度图像。基本原理是通过亮度将nonEdgeRate(60%)像素排除为非边缘像素。直方图用于对亮度进行排序,并且将设置上限阈值,以使其下方有60%的像素。通过将上限阈值乘以thresholdRate(0.6)来设置下限阈值。

请注意,在我的特定用例中,我自己对double nonEdgeRate = 0.6和double thresholdRate = 0.6进行了调整。在Matlab中,原始值分别为0.7和0.4。

收藏
评论

查看此链接: http : //www.pyimagesearch.com/2015/04/06/zero-parameter-automatic-canny-edge-detection-with-python-and-opencv/

他们使用基本统计信息实施类似的解决方案,以确定Canny边缘检测的低阈值和高阈值。

def auto_canny(image, sigma=0.33):
     # compute the median of the single channel pixel intensities
     v = np.median(image)

    # apply automatic Canny edge detection using the computed median
    lower = int(max(0, (1.0 - sigma) * v))
    upper = int(min(255, (1.0 + sigma) * v))
    edged = cv2.Canny(image, lower, upper)

    # return the edged image
    return edged
收藏
评论

另外,通过将代码放入OpenCV版本中,可以自动执行此操作。我在OpenCV用户邮件列表中找到它,因此无法保证。 :)

讨论: http : //opencv-users.1802565.n2.nabble.com/Automatic-thresholding-in-cvCanny-td5871024.html GitHub(代码): https : //gist.github.com/756833

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号