美文网首页
OpenCV 形状识别

OpenCV 形状识别

作者: 梁睿坤 | 来源:发表于2018-09-03 15:15 被阅读200次

    文本将讲述如何使用OpenCV识别一个图片中所包含的形状。

    安装依赖包:

    $ pip install imutils
    

    首先来定义一个类来负责检测图片中的形状:

    import cv2
     
    class ShapeDetector:
        def __init__(self):
            pass
     
        def detect(self, c):
            # 初始化图片名称与大概的形状
            shape = "unidentified"
            peri = cv2.arcLength(c, True)
            approx = cv2.approxPolyDP(c, 0.04 * peri, True)
    

    用于计算图形大至轮廓的算法叫道格拉斯-普克算法 OpenCV中是通过
    cv2.approxPolyDP对此进行实现。

    道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法迭代适应点算法分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算法。

    这个算法可以在1~5%范围内达到原始图像的边缘,通过它我们可以得到图像的“边”。

    ···python

    if the shape is a triangle, it will have 3 vertices

        if len(approx) == 3:
            shape = "triangle"
    
        # if the shape has 4 vertices, it is either a square or
        # a rectangle
        elif len(approx) == 4:
            # compute the bounding box of the contour and use the
            # bounding box to compute the aspect ratio
            (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"
    
        # if the shape is a pentagon, it will have 5 vertices
        elif len(approx) == 5:
            shape = "pentagon"
    
        # otherwise, we assume the shape is a circle
        else:
            shape = "circle"
    
        # return the name of the shape
        return shape
    
    
    当写完这个类就要像我在[《OpenCV定位轮廓的中点》](https://www.jianshu.com/p/9f8915caca13)一文中对图片进行灰度化处理并计算其二值图,最后再找出所有的轮廓:
    
    ```python
    # import the necessary packages
    from pyimagesearch.shapedetector import ShapeDetector
    import argparse
    import imutils
    import cv2
     
    # construct the argument parse and parse the arguments
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--image", required=True,
        help="path to the input image")
    args = vars(ap.parse_args())
    
    image = cv2.imread(args["image"])
    resized = imutils.resize(image, width=300)
    ratio = image.shape[0] / float(resized.shape[0])
     
    # convert the resized image to grayscale, blur it slightly,
    # and threshold it
    gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]
     
    # find contours in the thresholded image and initialize the
    # shape detector
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
        cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if imutils.is_cv2() else cnts[1]
    sd = ShapeDetector()
    

    最后在图型中标出其形状:

    # loop over the contours
    for c in cnts:
        # compute the center of the contour, then detect the name of the
        # shape using only the contour
        M = cv2.moments(c)
        cX = int((M["m10"] / M["m00"]) * ratio)
        cY = int((M["m01"] / M["m00"]) * ratio)
        shape = sd.detect(c)
     
        # multiply the contour (x, y)-coordinates by the resize ratio,
        # then draw the contours and the name of the shape on the image
        c = c.astype("float")
        c *= ratio
        c = c.astype("int")
        cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
        cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
            0.5, (255, 255, 255), 2)
     
        # show the output image
        cv2.imshow("Image", image)
        cv2.waitKey(0)
    

    最终效果如下:

    shape_detection_results.gif

    相关文章

      网友评论

          本文标题:OpenCV 形状识别

          本文链接:https://www.haomeiwen.com/subject/iopbwftx.html