• openCV学习笔记(1)


    一开始是直接看的官方文档,然后再看的是TCCP上的openCV教程

    推荐还是先看官方文档https://docs.opencv.org/3.4.1/d6/d00/tutorial_py_root.html

    1.Getting Started with Images

    首先是如何读取一张图片

    import numpy as np
    import cv2 as cv
    # Load an color image in grayscale
    img = cv.imread('mywife.jpg',-1)
    cv.imshow('image',img)
    cv.waitKey(0)
    #需要保存的话cv.imwrite(filename,img),需要指定格式 cv.destroyAllWindows()

    imread():中可以指定,-1,0,1分别代表彩色图,灰度图,加载图片alpha通道

    waitKey(n):代表等待n毫秒,如果传递0,它将无限期地等待击键。还可以将其设置为检测特定的按键,例如是否按下了按键q或者esc。

    destroyAllWindows():销毁所有窗口

    比如说你可以这样来设置waitKey() 这样将在你按下esc(ASCLL)后关闭,按下s键后保存

    import numpy as np
    import cv2 as cv
    img = cv.imread('mywife.jpg',0)
    cv.imshow('image',img)
    k = cv.waitKey(0)
    if k == 27:         # wait for ESC key to exit
        cv.destroyAllWindows()
    elif k == ord('s'): # wait for 's' key to save and exit
        cv.imwrite('mywife.png',img)#同名但格式不同不会覆盖
        cv.destroyAllWindows()

    --用matplotlib展示图像

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img = cv.imread('mywife.jpg',1)
    plt.imshow(img)
    plt.show()

    结果会很奇怪,颜色明显有问题

     查阅后:openCV默认是BGR颜色通道,matplolib默认是RGB通道,所以需要通道转化

    img = cv.cvtColor(img,cv.COLOR_BGR2RGB)

    比如我们现在来print(img)对比一下,可以发现的确是应为通道不一致

    2.视频读取和摄像头调用

     --先来调用一下摄像头吧

    import numpy as np
    import cv2 as cv
    cap = cv.VideoCapture(0)#创建一个videoCapture对象0代表第一台设备(支持多设备)
    while(True):
        # Capture frame-by-frame
        ret, frame = cap.read()
       #cap.read()返回一个bool变量,来判断是否读取成功,可以用cap.isOpened()来判断
    # Our operations on the frame come here cv.imshow('frame',frame) #cv.imwrite('frame.jpg',frame)#保存最后的画面图片 if cv.waitKey(1) & 0xFF == ord('q'):#q键退出 break # When everything done, release the capture cap.release()#释放 cv.destroyAllWindows()

    运行后会调用电脑的摄像头,如果没有摄像头或者摄像头权限关闭的话,程序会报错

    如果要保存这一段视频的话,需要将主体代码修改为

    fourcc = cv.VideoWriter_fourcc(*'XVID')
    #fourcc:是用于指定视频编解码器的4字节代码。可用代码列表可在fourcc.org中找到。它取决于平台。遵循编解码器对视频来说效果较好。用XVID就行了 out
    = cv.VideoWriter('outvideo.avi',fourcc,30,(640,480)) while(cap.isOpened()): ret , frame = cap.read() if ret == True: #frame = cv.flip(frame,0)用于将图像翻转 out.write(frame) cv.imshow("frame",frame) if cv.waitKey(1) &0xFF == ord('q'): break else: break

    --读取一个视频

    import numpy as np
    import cv2 as cv
    cap = cv.VideoCapture('1.mp4')
    while(cap.isOpened()):
        ret, frame = cap.read()
        #gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
        cv.imshow('frame',frame)
        if cv.waitKey(1) & 0xFF == ord('q'):
            break
    cap.release()
    cv.destroyAllWindows()

    这里wiatKey(n)中n值越大视频播放的速度越慢

    提醒一下:这里如果格式或者文件名字指定错误,不会报错,而是直接运行结束

     3.图像平滑和阈值

    首先理解一下什么叫阈值:当像素值高于阈值时,我们给这个像素赋予一个新值,否则给他赋予另一个值。

    比如这样,左边是原始图像右边是进行阈值处理的,黑和白进行了反转

    这里threshold(img, threshold, maxval,type)

    img:处理的图像

    threshold:设置的阈值(下中的127)

    maxval:是当灰度值大于(或小于)阈值时将该灰度值赋成的值(下中的255)

    type:处理方法

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img = cv.imread('circle.jpg',1)
    ret , thresh= cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
    images = np.hstack((img,thresh))
    plt.imshow(images)
    plt.show()

     这只是一种方法,阈值处理一共有6种,这里全部展示出来,含义看注解和图像就可以理解

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img = cv.imread('color.jpg',1)
    ret,thres1 = cv.threshold(img,127,255,cv.THRESH_BINARY)#超过阈值的取max值,否在取0
    ret,thres2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)#BINARY的反转即超过阈值取0否在max
    ret,thres3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)#大于阈值的设置为阈值,其他不变
    ret,thres4 = cv.threshold(img,127,255,cv.THRESH_TOZERO)#大于阈值的不变,其余为0
    ret,thres5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)#反TOZERO
    title = ["original","BINARY","BINRAY_INV","TRUNC","TOZERO","TOZERO_INV"]
    images = [img,thres1,thres2,thres3,thres4,thres5]
    for i in range(6):
        plt.subplot(2,3,i+1)
        plt.title(title[i])
        plt.imshow(images[i],"gray")
        plt.axis("off")
    plt.show()

     

     接下来做图像平滑处理,原理可以看这篇文档

    http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html

    例如均值滤波的原理就是用一个3x3的卷积核去和图像相乘,然后做均值处理

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img = cv.imread('lena.jpg',1)
    img = cv.cvtColor(img,cv.COLOR_BGR2RGB)
    #均值滤波
    blur = cv.blur(img,(3,3))
    #方框滤波
    box = cv.boxFilter(img,-1,(3,3),normalize = True)
    #高斯滤波
    gaussian = cv.GaussianBlur(img,(5,5),1)
    #中值滤波
    middle = cv.medianBlur(img,5)
    res = np.hstack((img,blur,box,gaussian,middle))
    plt.imshow(res)
    plt.show()

     中值滤波是这几个里面最模糊的

    4.图像的基本操作

    。图像属性,以lena这张图为例

    img = cv.imread('lena.jpg',1)
    print(img.shape)
    print(img.size)
    print(img.dtype)

    输出结果分别为

    (263, 263, 3)
    207507
    uint8

    --shape值为(263,263,3)代表263行263列,3个通道数(BGR)

    --size代表像素点数:这个207507 = 263 * 263 * 3

    --dtype代表图像数据类型 uint8代表8位无符号整型

    官网中特意提醒到:img.dtype在调试时非常重要,因为OpenCV-Python代码中的大量错误是由无效的数据类型引起的。

    。分割和合并图像通道

    当我们仅需要某一通道颜色时使用下面的方法

    b,g,r = cv.split(img)#分别获取B,G,R
    img = cv.merge((b,g,r))
    #或者也可以这样
    b = img[:,:,0]
    g = img[:,:,1]
    r = img[:,:,2]

    #再用cv.merge()合并
    img = cv.merge((r,g,b))

    官方又给了一个warning:cv.split()是一项昂贵的操作(就时间而言)。因此,仅在需要时才这样做。否则请进行Numpy索引。

    --图像边框填充

    import cv2 as cv
    import numpy as np
    from matplotlib import pyplot as plt
    BLUE = [255,0,0]
    img1 = cv.imread('lena.jpg')
    replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
    reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
    reflect101 = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101)
    wrap = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP)
    constant= cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_CONSTANT,value=BLUE)
    plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
    plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
    plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
    plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
    plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
    plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
    plt.show()

     cv.copyMakeBorder()这个函数的参数:src,top,bottom,left,right, bordertype

    src指定图像,后面4个代表各个方向上填充的边框宽度,bordertype指定填充类型

    cv.BORDER_REFLECT-边框将是边框元素的镜像,如下所示:fedcba | abcdefgh | hgfedcb

    cv.BORDER_REFLECT_101或cv.BORDER_DEFAULT-与上述相同,但略有变化,例如:gfedcb | abcdefgh | gfedcba

    cv.BORDER_REPLICATE-最后一个元素被复制,像这样:aaaaaa | abcdefgh | hhhhhhh     相当于再重复

    cv.BORDER_WRAP-它看起来像这样: cdefgh|abcdefgh|abcdefg,     大概可以近似理解为左边界当右填充,右边界当左填充

    cv.BORDER_CONSTANT:以常量填充,就最后那个样子

  • 相关阅读:
    Python的time模块随笔。
    生成器递归解决八皇后问题(勉强理解)
    Python历史「解密」Python底层逻辑 及Python 字节码介绍(转帖)
    可迭代(Interable),迭代器(Iterator),生成器(generator)的手记(11月26日再次修改)
    __getattr__,__setattr__,__delattr__,__getattribute__,记录
    关于property的一些记录,以及描述符(descriptor)中__get__,__set__,__delete__的属性使用。
    Python魔法方法之容器部方法(__len__,__getitem__,__setitem__,__delitem__,__missing__)(更新版本)
    Mac下PyCharm快捷键大全!(每天记住几个)
    开笔了,就写一下,hasattr,getattr,setattr。
    GUI
  • 原文地址:https://www.cnblogs.com/Truedragon/p/12904257.html
Copyright © 2020-2023  润新知