Image processing 如何识别图像中的不同对象?

Image processing 如何识别图像中的不同对象?,image-processing,opencv,pattern-matching,computer-vision,Image Processing,Opencv,Pattern Matching,Computer Vision,我打算写一个程序,从一个近乎坚实的背景中检测和区分某些物体。前景和背景有一个高对比度的差异,我会进一步增加,以帮助在对象识别过程。我计划使用Hough变换技术和OpenCV 如上图所示,我想分别识别圆形对象和方形对象(或有限形状集合中的任何其他形状)。因为我对图像处理还比较陌生,所以我不知道这种情况是否需要神经网络来实现,是否需要事先学习每个形状。模板匹配之类的技术能让我不用神经网络就可以做到这一点吗?这些帖子会让你开始: (高级方形检测) 您可能需要调整这些代码中的一些参数以匹配圆/

我打算写一个程序,从一个近乎坚实的背景中检测和区分某些物体。前景和背景有一个高对比度的差异,我会进一步增加,以帮助在对象识别过程。我计划使用Hough变换技术和OpenCV


如上图所示,我想分别识别圆形对象和方形对象(或有限形状集合中的任何其他形状)。因为我对图像处理还比较陌生,所以我不知道这种情况是否需要神经网络来实现,是否需要事先学习每个形状。模板匹配之类的技术能让我不用神经网络就可以做到这一点吗?

这些帖子会让你开始:

  • (高级方形检测)


您可能需要调整这些代码中的一些参数以匹配圆/正方形,但这些示例中显示了该技术的核心。

如果您想检测除圆以外的形状(我假设您是这样做的),我建议使用倒角匹配来快速启动,尤其是你的对比度很好

用简单的术语解释的基本前提如下:

  • 执行边缘检测(例如,在opencv中执行
    cvCanny
  • 创建距离图像,其中每个像素的值表示距离最近的边的距离
  • 获取要检测的形状,沿形状的边缘定义采样点,并尝试在距离图像上匹配这些点。基本上,您只需在距离图像上添加值,这些值位于给定对象特定位置的采样点坐标下
  • 找到一个好的最小化算法,其有效性取决于您的应用
  • 这种基本方法是一种通用的解决方案,通常效果很好,但是如果没有进一步的改进,它会非常缓慢

    通常,首先分离感兴趣的对象是个好主意,这样您就不必总是对整个图像进行完整搜索。找到一个好的
    阈值
    ,以便可以分离对象。您仍然不知道它是哪个对象,但您只需要在该对象附近进行匹配

    另一个好主意是,与其在高分辨率图像上进行完全搜索,不如先在非常低的分辨率上进行搜索。结果不会非常准确,但您可以知道哪些区域值得在更高分辨率上进行搜索,这样您就不会在没有任何感兴趣的区域浪费时间


    有许多更高级的技术,但仍然值得一看基本的倒角匹配,因为它是大量技术的基础

    假设对象是简单的形状,下面是一种使用阈值+轮廓近似的方法。轮廓近似是基于这样的假设,即曲线可以由一系列短线段近似,这些线段可用于确定轮廓的形状。例如,三角形有三个顶点,正方形/矩形有四个顶点,五边形有五个顶点,等等

  • 获取二值图像。我们加载图像,转换为灰度、高斯模糊,然后获取二值图像

  • 检测形状。使用轮廓近似过滤查找轮廓并识别每个轮廓的形状。这可以通过计算轮廓周长和获得实际轮廓近似值来实现


  • 输入图像

    检测到以绿色亮显的对象

    标记轮廓

    代码

    导入cv2
    def检测_形(c):
    #计算轮廓周长并执行轮廓近似
    shape=“”
    peri=cv2.弧长(c,真)
    近似值=cv2.近似聚合度(c,0.04*peri,真)
    #三角
    如果len(近似值)=3:
    shape=“三角形”
    #正方形还是长方形
    elif len(近似值)=4:
    (x,y,w,h)=cv2.边界矩形(近似值)
    ar=w/浮子(h)
    #正方形的纵横比大约为
    #等于1,否则,形状为矩形
    shape=“square”如果ar>=0.95且ar
    
    import cv2
    
    def detect_shape(c):
        # Compute perimeter of contour and perform contour approximation
        shape = ""
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.04 * peri, True)
    
        # Triangle
        if len(approx) == 3:
            shape = "triangle"
    
        # Square or rectangle
        elif len(approx) == 4:
            (x, y, w, h) = cv2.boundingRect(approx)
            ar = w / float(h)
    
            # A square will have an aspect ratio that is approximately
            # equal to one, otherwise, the shape is a rectangle
            shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
    
        # Star
        elif len(approx) == 10:
            shape = "star"
    
        # Otherwise assume as circle or oval
        else:
            shape = "circle"
    
        return shape
    
    # Load image, grayscale, Gaussian blur, and adaptive threshold
    image = cv2.imread('1.jpg')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (7,7), 0)
    thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,31,3)
    
    # Find contours and detect shape
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
        # Identify shape
        shape = detect_shape(c)
    
        # Find centroid and label shape name
        M = cv2.moments(c)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
        cv2.putText(image, shape, (cX - 20, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (36,255,12), 2)
    
    cv2.imshow('thresh', thresh)
    cv2.imshow('image', image)
    cv2.waitKey()