OpenCV:寻找物体轮廓findContours

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u013419318/article/details/102545955

1 介绍

本文主要介绍OpenCV自带轮廓检索函数findContours()的用法,让我们看看如何在一个二值图像中查找轮廓。函数cv2.findContours() 有三个参数,第一个是输入图像,第二个是轮廓检索模式,第三个是轮廓近似方法。返回值有三个,第一个是图像,第二个是轮廓,第三个是(轮廓的)层析结构。轮廓(第二个返回值)是一个Python列表,其中存储这图像中的所有轮廓。每一个轮廓都是一个Numpy 数组,包含对象边界点(x,y)的坐标。

2 代码

import cv2
import numpy as np
import matplotlib.pylab as plt
import os


# 形态学处理
def Process(img):
    # 高斯平滑
    gaussian = cv2.GaussianBlur(img, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
    # 中值滤波
    median = cv2.medianBlur(gaussian, 5)
    # Sobel算子
    # 梯度方向: x
    sobel = cv2.Sobel(median, cv2.CV_8U, 1, 0, ksize=3)
    # 二值化
    ret, binary = cv2.threshold(sobel, 170, 255, cv2.THRESH_BINARY)
    # 核函数
    element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 1))
    element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 7))
    # 膨胀
    dilation = cv2.dilate(binary, element2, iterations=1)
    # 腐蚀
    erosion = cv2.erode(dilation, element1, iterations=1)
    # 膨胀
    dilation2 = cv2.dilate(erosion, element2, iterations=3)
    return dilation2


def GetRegion(img):
    regions = []
    # 查找轮廓
    _, contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        area = cv2.contourArea(contour)
        if (area < 2000):
            continue
        eps = 1e-3 * cv2.arcLength(contour, True)
        approx = cv2.approxPolyDP(contour, eps, True)
        rect = cv2.minAreaRect(contour)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        height = abs(box[0][1] - box[2][1])
        width = abs(box[0][0] - box[2][0])
        ratio = float(width) / float(height)
        if (ratio < 5 and ratio > 0.3):
            regions.append(box)
    return regions


def detect(img_path,cut_pixels):
    if not os.path.exists(img_path):
        return
    img = plt.imread(img_path)
    # 灰度化
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    prc = Process(gray)
    regions = GetRegion(prc)
    new_regions = []
    for i in range(0,len(regions)):
        if len(regions) == 1:
            new_regions = regions
        if len(regions) == 2:
            new_regions = regions[-1:]
        if len(regions) == 3:
            new_regions = regions[-2:]
        if len(regions) == 4:
            new_regions = regions
    print('[INFO]:Detect %d license plates' % len(new_regions))
    for box in new_regions:
        cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
        print([box])
    cv2.imshow('Result', img)
    # # 保存结果文件名
    cv2.imwrite(os.path.join(os.path.dirname(img_path) + '/images_%d/'%(cut_pixels),os.path.basename(img_path)), img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    # print(regions)
    return new_regions


if __name__ == '__main__':

    # 输入的参数为图片的路径

    detect('1.jpg',67)

3 效果展示

 

猜你喜欢

转载自blog.csdn.net/u013419318/article/details/102545955