【问题标题】:How to detect triangle edge in opencv or emgu cv?如何检测opencv或emgu cv中的三角形边缘?
【发布时间】:2012-07-11 01:51:12
【问题描述】:

我用的是Emgu CV,想检测图片中的两个锐角,先把图片转成灰度,然后调用cvCanny,然后调用FindContours,但是只找到一个轮廓,三角形没有找到。

代码:

 public static void Do(Bitmap bitmap, IImageProcessingLog log)
    {
        Image<Bgr, Byte> img = new Image<Bgr, byte>(bitmap);
        Image<Gray, Byte> gray = img.Convert<Gray, Byte>();
        using (Image<Gray, Byte> canny = new Image<Gray, byte>(gray.Size))
        using (MemStorage stor = new MemStorage())
        {
            CvInvoke.cvCanny(gray, canny, 10, 5, 3);
            log.AddImage("canny",canny.ToBitmap());

            Contour<Point> contours = canny.FindContours(
             Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
             Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE,
             stor);

            for (int i=0; contours != null; contours = contours.HNext)
            {
                i++;
                MCvBox2D box = contours.GetMinAreaRect();

                Image<Bgr, Byte> tmpImg = img.Copy();
                tmpImg.Draw(box, new Bgr(Color.Red), 2);
                log.AddMessage("contours" + (i) +",angle:"+box.angle.ToString() + ",width:"+box.size.Width + ",height:"+box.size.Height);
                log.AddImage("contours" + i, tmpImg.ToBitmap());
            }
        }
    }

【问题讨论】:

    标签: opencv emgucv


    【解决方案1】:

    (我不知道 emguCV,但我会给你这个想法)

    你可以这样做:

    1. 使用split() 函数将图像拆分为 R、G、B 平面。
    2. 对于每个平面,应用 Canny 边缘检测。
    3. 然后找到其中的轮廓,并使用approxPolyDP函数逼近每个轮廓。
    4. 如果近似轮廓中的坐标数为 3,则它很可能是一个三角形,其值对应于三角形的 3 个顶点。

    下面是python代码:

    import numpy as np
    import cv2
    
    img = cv2.imread('softri.png')
    
    for gray in cv2.split(img):
        canny = cv2.Canny(gray,50,200)
    
        contours,hier = cv2.findContours(canny,1,2)
        for cnt in contours:
            approx = cv2.approxPolyDP(cnt,0.02*cv2.arcLength(cnt,True),True)
            if len(approx)==3:
                cv2.drawContours(img,[cnt],0,(0,255,0),2)
                tri = approx
    
    for vertex in tri:
        cv2.circle(img,(vertex[0][0],vertex[0][1]),5,255,-1)
    
    cv2.imshow('img',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    下面是蓝色平面的精明图:

    下面是最终的输出,三角形和它的顶点分别用绿色和蓝色标记:

    【讨论】:

    • 为什么我们需要分成3个频道?在彩色图像上经过精明之后,这不会同样有效吗?还是转换成灰色?
    • 不用吐了。您只需转换为灰度并使用精明的边缘检测器。
    猜你喜欢
    • 2016-07-29
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多