zoukankan      html  css  js  c++  java
  • opencv计算机视觉学习笔记六

    第七章 目标检测与识别

    梯度直方图histogram of oriented gradient

    图像金字塔 image pyramid

    滑动窗口 sliding window

    1 目标检测与识别

    A HOG描述符

    每个单元包含八个直方图即八个方向(n,nw,w,sw,s,se,e,ne)

    尺度  检测目标可能位于较大图像中

    位置  检测图像可能位于图像的任意位置

    可以使用图像金字塔或是滑动窗口解决

    非最大抑制

    支持向量机

    Svm算法,对于带有标签的训练数据,通过一个优化的超平面对这些数据进行分类

    B  检测人

    示例代码如下;

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time    : 2016/12/12 11:34
    # @Author  : Retacn
    # @Site    : 检测人
    # @File    : hogdescriptor.py
    # @Software: PyCharm
    __author__ = "retacn"
    __copyright__ = "property of mankind."
    __license__ = "CN"
    __version__ = "0.0.1"
    __maintainer__ = "retacn"
    __email__ = "zhenhuayue@sina.com"
    __status__ = "Development"
    
    import cv2
    import numpy as np
    
    
    # 检测某个矩形是否包含另一个矩形
    def is_inside(o, i):
        ox, oy, ow, oh = o
        ix, iy, iw, ih = i
        return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy + ih
    
    
    # 绘制矩形框住检测到的人
    def draw_person(imgae, person):
        x, y, w, h = person
        cv2.rectangle(imgae, (x, y), (x + w, y + h), (0, 255, 255), 2)
    
    
    # 读入图像
    img = cv2.imread('../people.jpg')
    # 创建检测器
    hog = cv2.HOGDescriptor()
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
    
    found, w = hog.detectMultiScale(img)
    
    found_filtered = []
    for ri, r in enumerate(found):
        for qi, q in enumerate(found):
            if ri != qi and is_inside(r, q):
                break
            else:
                found_filtered.append(r)
    for person in found_filtered:
        draw_person(img, person)
    
    # 显示图像
    cv2.imshow('people detection', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    C 创建和训练检测器

    对于检测不同对像,如何建立分类器

    使用svm和词袋(bag-of-word) bow在语言分析中的应用

    示列如下:

    I like opencv and i like python

    I like c++ and python

    I don’t like artichokes

    可以用以下值来建立字典

    {

    I:4,

    Like:4,

    Opencv:2,

    And:2

    Python:2

    C++:1

    Don’t:1

    Artichokes:1

    }

    以上的三句话可以用以下向量表示:

    [2,2,1,1,1,0,0,0]

    [1,1,0,1,1,1,0,0]

    [1,1,0,0,0,0,1,1]

    计算机视觉中的bow

    取样本数据集

    对数据集中的每幅图像提取描述符(sif,surf)

    将每个描述符添加到bow训练器中

    将描述符聚类开k族中(聚类的中心就是视觉单词)

    K-means聚类  用于数据分析的向量化方法

    2 汽车检测

    数据集下载

    The university orlllinois

    http://l2r.cs.uiuc.edu/~cogcomp/DATA/Car/CarData.tar.gz

    Stanforduniversity

    Http://ai.stanford.edu/~jkrause/cars/car_dataset.html

    示例代码如下:

    
    import cv2
    import numpy as np
    from os.path import join
    
    # TODO  定义路径
    datapath = 'E:/notes/python/opencv_python/openLib/CarData/TrainImages'
    
    
    # 取得测试图像的完整路径
    def path(cls, i):
        return '%s/%s%d.pgm' % (datapath, cls, i + 1)
    
    
    pos, neg = 'pos-', 'neg-'
    
    # 使用sif,surf 提取特征描述符
    detect = cv2.xfeatures2d.SIFT_create()  # 提取关键点
    extract = cv2.xfeatures2d.SURF_create()  # 提取特征
    
    # 使用flann匹配器
    flann_params = dict(algorithm=1, trees=5)
    matcher = cv2.FlannBasedMatcher(flann_params, {})
    
    # 创建bow训练器,簇数为40
    bow_kmeans_trainer = cv2.BOWKMeansTrainer(40)
    # 初始化bow提取器
    extract_bow = cv2.BOWImgDescriptorExtractor(extract, matcher)
    
    
    # 取得图像路径,认灰度格式读取图像,返回描述符
    def extract_sift(fn):
        im = cv2.imread(fn, 0)
        return extract.compute(im, detect.detect(im))[1]
    
    
    # 每个类读取8张图像
    for i in range(8):
        bow_kmeans_trainer.add(extract_sift(path(pos, i)))
        bow_kmeans_trainer.add(extract_sift(path(neg, i)))
    
    # 执行k-means分类并返回词汇
    voc = bow_kmeans_trainer.cluster()
    extract_bow.setVocabulary(voc)
    
    
    # 取得基于bow描述符提取器计算得到的描述符
    def bow_features(fn):
        im = cv2.imread(fn, cv2.IMREAD_GRAYSCALE)
        return extract_bow.compute(im, detect.detect(im))
    
    
    # 训练数据和标签
    traindata, trainlables = [], []
    # 生成正负样本图像的标签
    for i in range(20):
        # extend尾部添加
        traindata.extend(bow_features(path(pos, i)));
        trainlables.append(1)
        traindata.extend(bow_features(path(neg, i)));
        trainlables.append(-1)
    
    # 创建svm实例
    svm = cv2.ml.SVM_create()
    # 训练数据和标签
    svm.train(np.array(traindata), cv2.ml.ROW_SAMPLE, np.array(trainlables))
    
    
    # 显示predict结果
    def predict(fn):
        f = bow_features(fn)
        p = svm.predict(f)
        print(fn, '	', p[1][0][0])
        return p
    
    
    # TODO  设置两个样本图像的路径
    car, notcar = '../car.jpg', '../book.jpg'
    car_img = cv2.imread(car)
    notcar_img = cv2.imread(notcar)
    
    # 将图像传给svm,取得检测结果
    car_predict = predict(car)
    notcar_predict = predict(notcar)
    
    # 设置字体样式
    font = cv2.FONT_HERSHEY_SIMPLEX
    
    # 在图片上显示信息说明
    if (car_predict[1][0][0] == 1.0):
        cv2.putText(car_img, "Car Detected", (10, 30), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
    
    if (notcar_predict[1][0][0] == -1.0):
        cv2.putText(notcar_img, "Car Not Detected", (10, 30), font, 1, (0, 0, 255), 2, cv2.LINE_AA)
    
    # 显示图像
    cv2.imshow('BOW+SVM Success', car_img)
    cv2.imshow('BOW+SVM Failure', notcar_img)
    if cv2.waitKey(0) & 0xFF == ord('q'):
        cv2.destroyAllWindows()

    运行结果如下图:

    Svm滑动窗口

    检测同一物体的多个目标

    确定检测到的目标在图像中的位置

    滑动窗口的方法,有点像lcd屏的显示

    示例代码如下:(测试不成功)


  • 相关阅读:
    中序遍历【递归算法】和【非递归算法】
    等价无穷小替换
    轮转访问MAC协议
    曲率
    Java I/O流 01
    Java 集合框架 04
    Java 集合框架 03
    Java 集合框架 02
    Java 集合框架 01
    Java 常见对象 05
  • 原文地址:https://www.cnblogs.com/retacn-yue/p/6194152.html
Copyright © 2011-2022 走看看