如何在opencv或emgu cv中检测三角形边?

如何在opencv或emgu cv中检测三角形边?,opencv,emgucv,Opencv,Emgucv,我正在使用Emgu CV,我想检测图片中的两个锐角,首先我将图像转换为灰色,然后调用cvCanny,然后调用FindContours,但只找到一个轮廓,没有找到三角形 代码: publicstaticvoiddo(位图、IImageProcessingLog日志) { 图像img=新图像(位图); 图像灰度=img.Convert(); 使用(图像canny=新图像(灰度大小)) 使用(MemStorage story=new MemStorage()) { cvCanny(灰色,canny,1

我正在使用Emgu CV,我想检测图片中的两个锐角,首先我将图像转换为灰色,然后调用cvCanny,然后调用FindContours,但只找到一个轮廓,没有找到三角形

代码:

publicstaticvoiddo(位图、IImageProcessingLog日志)
{
图像img=新图像(位图);
图像灰度=img.Convert();
使用(图像canny=新图像(灰度大小))
使用(MemStorage story=new MemStorage())
{
cvCanny(灰色,canny,10,5,3);
log.AddImage(“canny”,canny.ToBitmap());
轮廓线=canny.FindContours(
Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_树,
stor);
对于(int i=0;轮廓!=null;轮廓=轮廓.HNext)
{
i++;
MCvBox2D-box=courts.getminarealect();
Image tmpImg=img.Copy();
tmpImg.图纸(框,新Bgr(颜色为红色),2);
log.AddMessage(“等高线”+(i)+”,角度:“+box.angle.ToString()+”,宽度:“+box.size.width+”,高度:“+box.size.height”);
log.AddImage(“等高线”+i,tmpImg.ToBitmap());
}
}
}
(我不知道emguCV,但我会告诉你这个想法)

您可以按如下方式进行操作:

  • 使用
    Split()
    函数将图像拆分为R、G、B平面
  • 对于每个平面,应用Canny边缘检测
  • 然后找到其中的轮廓,并使用
    approxPolyDP
    函数近似每个轮廓
  • 如果近似轮廓中的坐标数为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()
    
    下面是蓝色平面的canny示意图:

    以下是最终输出,三角形及其V形分别用绿色和蓝色标记:


    为什么我们需要分成3个频道?在canny对彩色图像进行处理后,这是否也同样有效?或者变成灰色?没必要吐口水。您只需转换为灰度并使用canny边缘检测器即可。
    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()