• 深度学习与计算机视觉系列(1)_基础介绍


    1.背景

    计算机视觉/computer vision是一个火了N年的topic。持续化升温的原因也非常简单:在搜索/影像内容理解/医学应用/地图识别等等领域应用太多,大家都有一个愿景『让计算机能够像人一样去”看”一张图片,甚至”读懂”一张图片』。

    有几个比较重要的计算机视觉任务,比如图片的分类,物体识别,物体定位于检测等等。而近年来的神经网络/深度学习使得上述任务的准确度有了非常大的提升。加之最近做了几个不大不小的计算机视觉上的项目,爱凑热闹的博主自然不打算放过此领域,也边学边做点笔记总结,写点东西,写的不正确的地方,欢迎大家提出和指正。

    2.基础知识

    为了简单易读易懂,这个系列中绝大多数的代码都使用Python完成。这里稍微介绍一下python和Numpy/Scipy(python中的科学计算包)的一些基础。

    2.1 python基础

    python是一种长得像伪代码,具备高可读性的编程语言。 
    优点挺多:可读性相当好,写起来也简单,所想立马可以转为实现代码,且社区即为活跃,可用的package相当多;缺点:效率一般。

    2.1.1 基本数据类型

    最常用的有数值型(Numbers),布尔型(Booleans)和字符串(String)三种。

    • 数值型(Numbers)

    可进行简单的运算,如下:

    x = 5
    print type(x) # Prints "<type 'int'>"
    print x       # Prints "5"
    print x + 1   # 加; prints "6"
    print x - 1   # 减; prints "4"
    print x * 2   # 乘; prints "10"
    print x ** 2  # 幂; prints "25"
    x += 1  #自加
    print x  # Prints "6"
    x *= 2  #自乘
    print x  # Prints "12"
    y = 2.5
    print type(y) # Prints "<type 'float'>"
    print y, y + 1, y * 2, y ** 2 # Prints "2.5 3.5 5.0 6.25"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    PS:python中没有x++ 和 x– 操作

    • 布尔型(Booleans)

    包含True False和常见的与或非操作

    t = True
    f = False
    print type(t) # Prints "<type 'bool'>"
    print t and f # 逻辑与; prints "False"
    print t or f  # 逻辑或; prints "True"
    print not t   # 逻辑非; prints "False"
    print t != f  # XOR; prints "True" 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 字符串型(String)

    字符串可以用单引号/双引号/三引号声明

    hello = 'hello'   
    world = "world"   
    print hello       # Prints "hello"
    print len(hello)  # 字符串长度; prints "5"
    hw = hello + ' ' + world  # 字符串连接
    print hw  # prints "hello world"
    hw2015 = '%s %s %d' % (hello, world, 2015)  # 格式化字符串
    print hw2015  # prints "hello world 2015"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    字符串对象有很有有用的函数:

    s = "hello"
    print s.capitalize()  # 首字母大写; prints "Hello"
    print s.upper()       # 全大写; prints "HELLO"
    print s.rjust(7)      # 以7为长度右对齐,左边补空格; prints "  hello"
    print s.center(7)     # 居中补空格; prints " hello "
    print s.replace('l', '(ell)')  # 字串替换;prints "he(ell)(ell)o"
    print '  world '.strip()  # 去首位空格; prints "world"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.1.2 基本容器

    • 列表/List

    和数组类似的一个东东,不过可以包含不同类型的元素,同时大小也是可以调整的。

    xs = [3, 1, 2]   # 创建
    print xs, xs[2]  # Prints "[3, 1, 2] 2"
    print xs[-1]     # 第-1个元素,即最后一个
    xs[2] = 'foo'    # 下标从0开始,这是第3个元素
    print xs         # 可以有不同类型,Prints "[3, 1, 'foo']"
    xs.append('bar') # 尾部添加一个元素
    print xs         # Prints 
    x = xs.pop()     # 去掉尾部的元素
    print x, xs      # Prints "bar [3, 1, 'foo']"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    列表最常用的操作有: 
    切片/slicing 
    即取子序列/一部分元素,如下:

    nums = range(5)    # 从1到5的序列
    print nums         # Prints "[0, 1, 2, 3, 4]"
    print nums[2:4]    # 下标从2到4-1的元素 prints "[2, 3]"
    print nums[2:]     # 下标从2到结尾的元素
    print nums[:2]     # 从开头到下标为2-1的元素  [0, 1]
    print nums[:]      # 恩,就是全取出来了
    print nums[:-1]    # 从开始到第-1个元素(最后的元素)
    nums[2:4] = [8, 9] # 对子序列赋值
    print nums         # Prints "[0, 1, 8, 8, 4]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    循环/loops 
    即遍历整个list,做一些操作,如下:

    animals = ['cat', 'dog', 'monkey']
    for animal in animals:
        print animal
    # 依次输出 "cat", "dog", "monkey",每个一行.
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    可以用enumerate取出元素的同时带出下标

    animals = ['cat', 'dog', 'monkey']
    for idx, animal in enumerate(animals):
        print '#%d: %s' % (idx + 1, animal)
    # 输出 "#1: cat", "#2: dog", "#3: monkey",一个一行。
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    List comprehension 
    这个相当相当相当有用,在很长的list生成过程中,效率完胜for循环:

    # for 循环
    nums = [0, 1, 2, 3, 4]
    squares = []
    for x in nums:
        squares.append(x ** 2)
    print squares   # Prints [0, 1, 4, 9, 16]
    
    # list comprehension
    nums = [0, 1, 2, 3, 4]
    squares = [x ** 2 for x in nums]
    print squares   # Prints [0, 1, 4, 9, 16]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    你猜怎么着,list comprehension也是可以加多重条件的:

    nums = [0, 1, 2, 3, 4]
    even_squares = [x ** 2 for x in nums if x % 2 == 0]
    print even_squares  # Prints "[0, 4, 16]"
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3
    • 字典/Dict 
      和Java中的Map一样的东东,用于存储key-value对:
    d = {'cat': 'cute', 'dog': 'furry'}  # 创建
    print d['cat']       # 根据key取出value
    print 'cat' in d     # 判断是否有'cat'这个key
    d['fish'] = 'wet'    # 添加元素
    print d['fish']      # Prints "wet"
    # print d['monkey']  # KeyError: 'monkey'非本字典的key
    print d.get('monkey', 'N/A')  # 有key返回value,无key返回"N/A"
    print d.get('fish', 'N/A')    # prints "wet"
    del d['fish']        # 删除某个key以及对应的value
    print d.get('fish', 'N/A') # prints "N/A"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    对应list的那些操作,你在dict里面也能找得到:

    循环/loops

    # for循环
    d = {'person': 2, 'cat': 4, 'spider': 8}
    for animal in d:
        legs = d[animal]
        print 'A %s has %d legs' % (animal, legs)
    # Prints "A person has 2 legs", "A spider has 8 legs", "A cat has 4 legs"
    
    # 通过iteritems
    d = {'person': 2, 'cat': 4, 'spider': 8}
    for animal, legs in d.iteritems():
        print 'A %s has %d legs' % (animal, legs)
    # Prints "A person has 2 legs", "A spider has 8 legs", "A cat has 4 legs"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    # Dictionary comprehension
    nums = [0, 1, 2, 3, 4]
    even_num_to_square = {x: x ** 2 for x in nums if x % 2 == 0}
    print even_num_to_square  # Prints "{0: 0, 2: 4, 4: 16}"
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4
    • 元组/turple 
      本质上说,还是一个list,只不过里面的每个元素都是一个两元组对。
    d = {(x, x + 1): x for x in range(10)}  # 创建
    t = (5, 6)       # Create a tuple
    print type(t)    # Prints "<type 'tuple'>"
    print d[t]       # Prints "5"
    print d[(1, 2)]  # Prints "1"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    2.1.3 函数

    用def可以定义一个函数:

    def sign(x):
        if x > 0:
            return 'positive'
        elif x < 0:
            return 'negative'
        else:
            return 'zero'
    
    for x in [-1, 0, 1]:
        print sign(x)
    # Prints "negative", "zero", "positive"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    def hello(name, loud=False):
        if loud:
            print 'HELLO, %s' % name.upper()
        else:
            print 'Hello, %s!' % name
    
    hello('Bob') # Prints "Hello, Bob"
    hello('Fred', loud=True)  # Prints "HELLO, FRED!"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 类/Class

    python里面的类定义非常的直接和简洁:

    class Greeter:
    
        # Constructor
        def __init__(self, name):
            self.name = name  # Create an instance variable
    
        # Instance method
        def greet(self, loud=False):
            if loud:
                print 'HELLO, %s!' % self.name.upper()
            else:
                print 'Hello, %s' % self.name
    
    g = Greeter('Fred')  # Construct an instance of the Greeter class
    g.greet()            # Call an instance method; prints "Hello, Fred"
    g.greet(loud=True)   # Call an instance method; prints "HELLO, FRED!"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.2.NumPy基础

    NumPy是Python的科学计算的一个核心库。它提供了一个高性能的多维数组(矩阵)对象,可以完成在其之上的很多操作。很多机器学习中的计算问题,把数据vectorize之后可以进行非常高效的运算。

    2.2.1 数组

    一个NumPy数组是一些类型相同的元素组成的类矩阵数据。用list或者层叠的list可以初始化:

    import numpy as np
    
    a = np.array([1, 2, 3])  # 一维Numpy数组
    print type(a)            # Prints "<type 'numpy.ndarray'>"
    print a.shape            # Prints "(3,)"
    print a[0], a[1], a[2]   # Prints "1 2 3"
    a[0] = 5                 # 重赋值
    print a                  # Prints "[5, 2, 3]"
    
    b = np.array([[1,2,3],[4,5,6]])   # 二维Numpy数组
    print b.shape                     # Prints "(2, 3)"
    print b[0, 0], b[0, 1], b[1, 0]   # Prints "1 2 4"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    生成一些特殊的Numpy数组(矩阵)时,我们有特定的函数可以调用:

    import numpy as np
    
    a = np.zeros((2,2))  # 全0的2*2 Numpy数组
    print a              # Prints "[[ 0.  0.]
                         #          [ 0.  0.]]"
    
    b = np.ones((1,2))   # 全1 Numpy数组
    print b              # Prints "[[ 1.  1.]]"
    
    c = np.full((2,2), 7) # 固定值Numpy数组
    print c               # Prints "[[ 7.  7.]
                          #          [ 7.  7.]]"
    
    d = np.eye(2)        # 2*2 对角Numpy数组
    print d              # Prints "[[ 1.  0.]
                         #          [ 0.  1.]]"
    
    e = np.random.random((2,2)) # 2*2 的随机Numpy数组
    print e                     # 随机输出
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.2.2 Numpy数组索引与取值

    可以通过像list一样的分片/slicing操作取出需要的数值部分。

    import numpy as np
    
    # 创建如下的3*4 Numpy数组
    # [[ 1  2  3  4]
    #  [ 5  6  7  8]
    #  [ 9 10 11 12]]
    a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
    
    # 通过slicing取出前两行的2到3列:
    # [[2 3]
    #  [6 7]]
    b = a[:2, 1:3]
    
    # 需要注意的是取出的b中的数据实际上和a的这部分数据是同一份数据.
    print a[0, 1]   # Prints "2"
    b[0, 0] = 77    # b[0, 0] 和 a[0, 1] 是同一份数据
    print a[0, 1]   # a也被修改了,Prints "77"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    import numpy as np
    
    a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
    
    row_r1 = a[1, :]    # a 的第二行  
    row_r2 = a[1:2, :]  # 同上
    print row_r1, row_r1.shape  # Prints "[5 6 7 8] (4,)"
    print row_r2, row_r2.shape  # Prints "[[5 6 7 8]] (1, 4)"
    
    col_r1 = a[:, 1]
    col_r2 = a[:, 1:2]
    print col_r1, col_r1.shape  # Prints "[ 2  6 10] (3,)"
    print col_r2, col_r2.shape  # Prints "[[ 2]
                                #          [ 6]
                                #          [10]] (3, 1)"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    还可以这么着取:

    import numpy as np
    
    a = np.array([[1,2], [3, 4], [5, 6]])
    
    # 取出(0,0) (1,1) (2,0)三个位置的值
    print a[[0, 1, 2], [0, 1, 0]]  # Prints "[1 4 5]"
    
    # 和上面一样
    print np.array([a[0, 0], a[1, 1], a[2, 0]])  # Prints "[1 4 5]"
    
    # 取出(0,1) (0,1) 两个位置的值
    print a[[0, 0], [1, 1]]  # Prints "[2 2]"
    
    # 同上
    print np.array([a[0, 1], a[0, 1]])  # Prints "[2 2]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    我们还可以通过条件得到bool型的Numpy数组结果,再通过这个数组取出符合条件的值,如下:

    import numpy as np
    
    a = np.array([[1,2], [3, 4], [5, 6]])
    
    bool_idx = (a > 2)  # 判定a大于2的结果矩阵
    
    print bool_idx      # Prints "[[False False]
                        #          [ True  True]
                        #          [ True  True]]"
    
    # 再通过bool_idx取出我们要的值
    print a[bool_idx]  # Prints "[3 4 5 6]"
    
    # 放在一起我们可以这么写
    print a[a > 2]     # Prints "[3 4 5 6]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Numpy数组的类型

    import numpy as np
    
    x = np.array([1, 2])  
    print x.dtype         # Prints "int64"
    
    x = np.array([1.0, 2.0]) 
    print x.dtype             # Prints "float64"
    
    x = np.array([1, 2], dtype=np.int64)  # 强制使用某个type
    print x.dtype                         # Prints "int64"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2.3 Numpy数组的运算

    矩阵的加减开方和(元素对元素)乘除如下:

    import numpy as np
    
    x = np.array([[1,2],[3,4]], dtype=np.float64)
    y = np.array([[5,6],[7,8]], dtype=np.float64)
    
    # [[ 6.0  8.0]
    #  [10.0 12.0]]
    print x + y
    print np.add(x, y)
    
    # [[-4.0 -4.0]
    #  [-4.0 -4.0]]
    print x - y
    print np.subtract(x, y)
    
    # 元素对元素,点对点的乘积
    # [[ 5.0 12.0]
    #  [21.0 32.0]]
    print x * y
    print np.multiply(x, y)
    
    # 元素对元素,点对点的除法
    # [[ 0.2         0.33333333]
    #  [ 0.42857143  0.5       ]]
    print x / y
    print np.divide(x, y)
    
    # 开方
    # [[ 1.          1.41421356]
    #  [ 1.73205081  2.        ]]
    print np.sqrt(x)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    矩阵的内积是通过下列方法计算的:

    import numpy as np
    
    x = np.array([[1,2],[3,4]])
    y = np.array([[5,6],[7,8]])
    
    v = np.array([9,10])
    w = np.array([11, 12])
    
    # 向量内积,得到 219
    print v.dot(w)
    print np.dot(v, w)
    
    # 矩阵乘法,得到 [29 67]
    print x.dot(v)
    print np.dot(x, v)
    
    # 矩阵乘法
    # [[19 22]
    #  [43 50]]
    print x.dot(y)
    print np.dot(x, y)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    特别特别有用的一个操作是,sum/求和(对某个维度):

    import numpy as np
    
    x = np.array([[1,2],[3,4]])
    
    print np.sum(x)  # 整个矩阵的和,得到 "10"
    print np.sum(x, axis=0)  # 每一列的和 得到 "[4 6]"
    print np.sum(x, axis=1)  # 每一行的和 得到 "[3 7]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    还有一个经常会用到操作是矩阵的转置,在Numpy数组里用.T实现:

    import numpy as np
    
    x = np.array([[1,2], [3,4]])
    print x    # Prints "[[1 2]
               #          [3 4]]"
    print x.T  # Prints "[[1 3]
               #          [2 4]]"
    
    # 1*n的Numpy数组,用.T之后其实啥也没做:
    v = np.array([1,2,3])
    print v    # Prints "[1 2 3]"
    print v.T  # Prints "[1 2 3]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2.4 Broadcasting

    Numpy还有一个非常牛逼的机制,你想想,如果你现在有一大一小俩矩阵,你想使用小矩阵在大矩阵上做多次操作。额,举个例子好了,假如你想将一个1*n的矩阵,加到m*n的矩阵的每一行上:

    #你如果要用for循环实现是酱紫的(下面用y的原因是,你不想改变原来的x)
    import numpy as np
    
    x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
    v = np.array([1, 0, 1])
    y = np.empty_like(x)   # 设置一个和x一样维度的Numpy数组y
    
    # 逐行相加
    for i in range(4):
        y[i, :] = x[i, :] + v
    
    # 恩,y就是你想要的了
    # [[ 2  2  4]
    #  [ 5  5  7]
    #  [ 8  8 10]
    #  [11 11 13]]
    print y
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    #上一种方法如果for的次数非常多,会很慢,于是我们改进了一下
    import numpy as np
    
    x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
    v = np.array([1, 0, 1])
    vv = np.tile(v, (4, 1))  # 变形,重复然后叠起来
    print vv                 # Prints "[[1 0 1]
                             #          [1 0 1]
                             #          [1 0 1]
                             #          [1 0 1]]"
    y = x + vv  # 相加
    print y  # Prints "[[ 2  2  4
             #          [ 5  5  7]
             #          [ 8  8 10]
             #          [11 11 13]]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    #其实因为Numpy的Broadcasting,你可以直接酱紫操作
    import numpy as np
    
    x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
    v = np.array([1, 0, 1])
    y = x + v  # 直接加!!!
    print y  # Prints "[[ 2  2  4]
             #          [ 5  5  7]
             #          [ 8  8 10]
             #          [11 11 13]]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    更多Broadcasting的例子请看下面:

    import numpy as np
    
    v = np.array([1,2,3])  # v has shape (3,)
    w = np.array([4,5])    # w has shape (2,)
    # 首先把v变成一个列向量
    # v现在的形状是(3, 1);
    # 作用在w上得到的结果形状是(3, 2),如下
    # [[ 4  5]
    #  [ 8 10]
    #  [12 15]]
    print np.reshape(v, (3, 1)) * w
    
    # 逐行相加
    x = np.array([[1,2,3], [4,5,6]])
    # 得到如下结果:
    # [[2 4 6]
    #  [5 7 9]]
    print x + v
    
    # 先逐行相加再转置,得到以下结果:
    # [[ 5  6  7]
    #  [ 9 10 11]]
    print (x.T + w).T
    # 恩,也可以这么做
    print x + np.reshape(w, (2, 1))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2.3 SciPy

    Numpy提供了一个非常方便操作和计算的高维向量对象,并提供基本的操作方法,而Scipy是在Numpy的基础上,提供很多很多的函数和方法去直接完成你需要的矩阵操作。有兴趣可以浏览Scipy方法索引查看具体的方法,函数略多,要都记下来有点困难,随用随查吧。

    向量距离计算

    需要特别拎出来说一下的是,向量之间的距离计算,这个Scipy提供了很好的接口scipy.spatial.distance.pdist

    import numpy as np
    from scipy.spatial.distance import pdist, squareform
    
    # [[0 1]
    #  [1 0]
    #  [2 0]]
    x = np.array([[0, 1], [1, 0], [2, 0]])
    print x
    
    # 计算矩阵每一行和每一行之间的欧氏距离
    # d[i, j] 是 x[i, :] 和 x[j, :] 之间的距离,
    # 结果如下:
    # [[ 0.          1.41421356  2.23606798]
    #  [ 1.41421356  0.          1.        ]
    #  [ 2.23606798  1.          0.        ]]
    d = squareform(pdist(x, 'euclidean'))
    print d
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.4 Matplotlib

    这是python中的一个作图工具包。如果你熟悉matlab的语法的话,应该会用得挺顺手。可以通过matplotlib.pyplot.plot了解更多绘图相关的设置和参数。

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 计算x和对应的sin值作为y
    x = np.arange(0, 3 * np.pi, 0.1)
    y = np.sin(x)
    
    # 用matplotlib绘出点的变化曲线
    plt.plot(x, y)
    plt.show()  # 只有调用plt.show()之后才能显示
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果如下: 
    sin图像

    # 在一个图中画出2条曲线
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 计算x对应的sin和cos值
    x = np.arange(0, 3 * np.pi, 0.1)
    y_sin = np.sin(x)
    y_cos = np.cos(x)
    
    # 用matplotlib作图
    plt.plot(x, y_sin)
    plt.plot(x, y_cos)
    plt.xlabel('x axis label')
    plt.ylabel('y axis label')
    plt.title('Sine and Cosine')
    plt.legend(['Sine', 'Cosine'])
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    sin和cos

    # 用subplot分到子图里
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 得到x对应的sin和cos值
    x = np.arange(0, 3 * np.pi, 0.1)
    y_sin = np.sin(x)
    y_cos = np.cos(x)
    
    # 2*1个子图,第一个位置.
    plt.subplot(2, 1, 1)
    
    # 画第一个子图
    plt.plot(x, y_sin)
    plt.title('Sine')
    
    # 画第2个子图
    plt.subplot(2, 1, 2)
    plt.plot(x, y_cos)
    plt.title('Cosine')
    
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    subplot

    2.5 简单图片读写

    可以使用imshow来显示图片。

    import numpy as np
    from scipy.misc import imread, imresize
    import matplotlib.pyplot as plt
    
    img = imread('/Users/HanXiaoyang/Comuter_vision/computer_vision.jpg')
    img_tinted = img * [1, 0.95, 0.9]
    
    # 显示原始图片
    plt.subplot(1, 2, 1)
    plt.imshow(img)
    
    # 显示调色后的图片
    plt.subplot(1, 2, 2)
    plt.imshow(np.uint8(img_tinted))
    
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    computer_vision

  • 相关阅读:
    js 变量命名规范
    JS
    python 处理中文十六进制的encode %E9%99%88%E8%80%81%E5%B8%88/%E5%9B%BE%E7%89%87
    Pycharm 项目上传至Gitee/Github详细步骤
    Python 类型建议符, Python 定义函数的时候有冒号:
    Python 解析 JSON
    Python 解析 JSON
    Mac 安装 WordPress
    java常用书籍下载
    Docker环境搭建Redis4.0 Cluster
  • 原文地址:https://www.cnblogs.com/weizc/p/5562934.html
Copyright © 2020-2023  润新知