美文网首页
opencv笔记

opencv笔记

作者: v587的毅哥 | 来源:发表于2022-04-18 21:59 被阅读0次

    数据图像格式

    cv2.IMREAD_COLOR: 彩色图像
    cv2.IMREAD_GRAYSCALE: 灰度图像

    读取图像方法

    img = cv2.imread('cat.jpg')

    输出图像

    img

    [out]:
    #[h,w,c]
    array([
    [[100,100,100],[200,200,200],[300,300,300]…,[900,900,900]],
    [[111,111,111],[222,222,222],[333,333,333]…,[999,999,999]],
    [[123,123,123],[234,234,234],[345,345,345]…,[789,789,789]]
    ],dtype=unit8)
    

    显示图像

    cv2.imshow('image_name',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    图像数据大小与格式

    img.shape

    [out]:
    (414,500,3)
    #也就是上面的[h,w,c],c就是代表BGR
    

    读取为灰度图

    img = cv2.imread('cat.jpg',cv2.IMREAD_GRAYSCALE)
    img

    [out]:
    array([
    [100,200,300,…,900],
    [111,222,333,…,999],
    …
    [123,456,789,…,012]
    ],dtype=unit8)
    

    保存图像

    cv2.imwrite('mycat.png',img)

    查看图像的格式

    type(img)

    [out]:numpy.ndarray
    

    查看图像的大小

    img.size

    [out]:
    207000
    

    查看图像的dtype

    img.dtype

    [out]:
    dype('unit8')
    

    读取视频

    cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0,1。
    如果是视频文件,直接指定好路径即可。

    vc = cv2.VideoCapture('test.mp4')
    # 检查是否打开正确
    if vc.isOpened(): 
        open, frame = vc.read()
    else:
        open = False
    #%%
    while open:
        ret, frame = vc.read()
        if frame is None:
            break
        if ret == True:
            gray = cv2.cvtColor(frame,  cv2.COLOR_BGR2GRAY)
            cv2.imshow('result', gray)
            if cv2.waitKey(100) & 0xFF == 27:
                break
    vc.release()
    cv2.destroyAllWindows()
    

    截取部分图像数据

    img = cv2.imread('cat.jpg`)
    cat = img[0:200,0:200]
    cv_show('cat',cat)
    

    颜色通道提取

    b,g,r = cv2.split(img)
    b

    [out]:
    array([[160, 164, 169, ..., 185, 184, 183],
           [126, 131, 136, ..., 184, 183, 182],
           [127, 131, 137, ..., 183, 182, 181],
           ...,
           [198, 193, 178, ..., 206, 195, 174],
           [176, 183, 175, ..., 188, 144, 125],
           [190, 190, 157, ..., 200, 145, 144]], dtype=uint8)
    

    颜色的合并

    img = cv2.merge((b,g,r))

    只保留R(其余通道置为0)

    cur_img = img.copy()
    cur_img[:,:,0] = 0
    cur_img[:,:,1] = 0
    cv_show('R',cur_img)

    边界填充(周围扩大一圈)

    # 先定义一下填充的大小
    top_size,bottom_size,left_size,right_size = (50,50,50,50)
    # 不同的填充方法
    replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
    reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
    reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
    wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
    constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)
    

    <img src="http://img.yibogame.com/uPic/2022-04-18-21-54-56-1650290096178-2022-04-18-18-58-55-1650279535945-output.png" alt="image-20220418205212143" />
    BORDER_REPLICATE:复制法,也就是复制最边缘像素。
    BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
    BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
    BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
    BORDER_CONSTANT:常量法,常数值填充。

    数值计算

    img_cat = cv2.imread('cat.jpg')
    img_dog = cv2.imread('dog.jpg')
    
    img_cat[:5,:,0]
    
    [out]:
    array([[142, 146, 151, ..., 156, 155, 154],
           [107, 112, 117, ..., 155, 154, 153],
           [108, 112, 118, ..., 154, 153, 152],
           [139, 143, 148, ..., 156, 155, 154],
           [153, 158, 163, ..., 160, 159, 158]], dtype=uint8)
    
    img_cat2= img_cat +10 
    img_cat[:5,:,0]
    
    [out]:
    array([[152, 156, 161, ..., 166, 165, 164],
           [117, 122, 127, ..., 165, 164, 163],
           [118, 122, 128, ..., 164, 163, 162],
           [149, 153, 158, ..., 166, 165, 164],
           [163, 168, 173, ..., 170, 169, 168]], dtype=uint8)
    
    #相当于 %(取余) 256
    (img_cat + img_cat2)[:5,:,0] 
    
    [out]:
    array([[ 38,  46,  56, ...,  66,  64,  62],
           [224, 234, 244, ...,  64,  62,  60],
           [226, 234, 246, ...,  62,  60,  58],
           [ 32,  40,  50, ...,  66,  64,  62],
           [ 60,  70,  80, ...,  74,  72,  70]], dtype=uint8)
    
    cv2.add(img_cat,img_cat2)[:5,:,0]
    
    [out]:
    array([[255, 255, 255, ..., 255, 255, 255],
           [224, 234, 244, ..., 255, 255, 255],
           [226, 234, 246, ..., 255, 255, 255],
           [255, 255, 255, ..., 255, 255, 255],
           [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
    

    图像融合

    img_cat + img_dog

    [out]:
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-111-ffa3cdc5d6b8> in <module>()
    ----> 1 img_cat + img_dog
    
    ValueError: operands could not be broadcast together with shapes (414,500,3) (429,499,3)
    

    因为两个大小不一样,报错了!那先看看img_cat的大小:
    img_cat.shape

    [out]:
    (414, 500, 3)
    

    把狗变为猫那么大:

    img_dog = cv2.resize(img_dog, (500, 414))
    img_dog.shape
    
    [out]:
    (414, 500, 3)
    
    # Result = αx1 + βx2 + b(x1:猫,x2:狗,b:偏移量,α、β:权重)
    res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)
    plt.imshow(res)
    

    <img src="http://img.yibogame.com/uPic/2022-04-18-18-58-49-1650279529590-output1.png" alt="image-20220418205212143" />

    图像阈值处理

    ret, dst = cv2.threshold(src, thresh, maxval, type)
    src: 输入图,只能输入单通道图像,通常来说为灰度图
    dst: 输出图
    thresh: 阈值
    maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
    type:二值化操作的类型,包含以下5种类型:

    cv2.THRESH_TOZERO_INV
    cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
    cv2.THRESH_BINARY_INVTHRESH_BINARY的反转
    cv2.THRESH_TRUNC大于阈值部分设为阈值,否则不变
    cv2.THRESH_TOZERO大于阈值部分不改变,否则设为0
    cv2.THRESH_TOZERO_INVTHRESH_TOZERO的反转

    ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
    ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
    ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
    ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
    ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
    
    titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
    images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
    
    for i in range(6):
        plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
        plt.title(titles[i])
        plt.xticks([]), plt.yticks([])
    plt.show()
    

    <img src="http://img.yibogame.com/uPic/2022-04-18-18-58-44-1650279524214-output3.png" alt="image-20220418205212143" />

    图像平滑处理

    <img src="http://img.yibogame.com/uPic/2022-04-18-18-58-37-1650279517969-input1.png" alt="input1" style="zoom:50%;" />

    img = cv2.imread('lenaNoise.png')
    

    原始带噪点图像:
    <img src="http://img.yibogame.com/uPic/2022-04-18-20-49-04-1650286144073-lenaNoise.png" alt="lenaNoise" style="zoom:50%;" />

    # 均值滤波(121+75+78+……+235)/9
    # 简单的平均卷积操作
    blur = cv2.blur(img, (3, 3))
    cv2.imshow('blur', blur)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    均值滤波输出的结果:
    <img src="http://img.yibogame.com/uPic/2022-04-18-20-52-12-1650286332261-image-20220418205212143.png" alt="image-20220418205212143" style="zoom: 25%;" />

    # 方框滤波
    # 基本和均值一样,可以选择归一化(与上图一样)
    box = cv2.boxFilter(img,-1,(3,3), normalize=True)  
    cv2.imshow('box', box)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    方框滤波输出的结果(归一化):
    <img src="http://img.yibogame.com/uPic/2022-04-18-20-52-12-1650286332261-image-20220418205212143.png" alt="image-20220418205212143" style="zoom: 25%;" />

    # 方框滤波
    # 基本和均值一样,可以选择归一化,容易越界(超过255。当超过255后就是255)
    box = cv2.boxFilter(img,-1,(3,3), normalize=False)  
    cv2.imshow('box', box)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    方框滤波输出的结果(不归一化):
    <img src="http://img.yibogame.com/uPic/2022-04-18-20-55-19-1650286519100-image-20220418205518999.png" alt="image-20220418205518999" style="zoom: 25%;" />

    # 高斯滤波
    # 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
    aussian = cv2.GaussianBlur(img, (5, 5), 1)  
    
    cv2.imshow('aussian', aussian)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    高斯滤波的函数图像:
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-04-07-1650287047640-image-20220418210407535.png" alt="image-20220418210407535" style="zoom:50%;" />

    高斯滤波的卷积核大概类似于这样(越中间影响越大):
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-01-58-1650286918084-image-20220418210157986.png" alt="image-20220418210157986" style="zoom:50%;" />

    高斯滤波输出的结果:
    <img src="http://img.yibogame.com/uPic/2022-04-18-20-59-36-1650286776559-image-20220418205936456.png" alt="image-20220418205936456" style="zoom:25%;" />

    # 中值滤波(把121,75,78,……,235按数值大小排序,再取中间的那个值)
    # 相当于用中值代替
    median = cv2.medianBlur(img, 5)  # 中值滤波
    
    cv2.imshow('median', median)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    中值滤波输出的结果:
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-09-00-1650287340845-image-20220418210900722.png" alt="image-20220418210900722" style="zoom:25%;" />

    # 展示所有的
    res = np.hstack((blur,aussian,median))
    # 垂直展示也行:
    # res = np.vstack((blur,aussian,median))
    cv2.imshow('median vs average', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    hstack方式输出结果:

    <img src="http://img.yibogame.com/uPic/2022-04-18-21-16-04-1650287764298-image-20220418211604185.png" alt="image-20220418211604185" style="zoom:25%;" />

    形态学----腐蚀(erode)

    img = cv2.imread('res/dige.png')
    
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    原始图像:
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-25-15-1650288315808-image-20220418212515704.png" alt="image-20220418212515704" style="zoom:35%;" />

    #3*3的卷积核
    kernel = np.ones((3, 3), np.uint8)
    erosion = cv2.erode(img, kernel, iterations=1)
    
    cv2.imshow('erosion', erosion)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    腐蚀后的图像:
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-25-37-1650288337151-image-20220418212537049.png" alt="image-20220418212537049" style="zoom:35%;" />

    pie = cv2.imread('res/pie.png')
    
    cv2.imshow('pie', pie)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    腐蚀卷积核:
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-38-46-1650289126077-image-20220418213845958.png" alt="image-20220418213845958" style="zoom:35%;" />

    #30*30的卷积核
    kernel = np.ones((30, 30), np.uint8)
    #腐蚀1、2、3次
    erosion_1 = cv2.erode(pie, kernel, iterations=1)
    erosion_2 = cv2.erode(pie, kernel, iterations=2)
    erosion_3 = cv2.erode(pie, kernel, iterations=3)
    res = np.hstack((erosion_1, erosion_2, erosion_3))
    cv2.imshow('res', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    腐蚀1、2、3次的结果图:
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-39-49-1650289189888-image-20220418213949773.png" alt="image-20220418213949773" style="zoom:35%;" />

    形态学----膨胀(dilate)

    img = cv2.imread('res/dige.png')
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    原始图像:
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-25-15-1650288315808-image-20220418212515704.png" alt="image-20220418212515704" style="zoom:35%;" />

    # 先腐蚀一次
    kernel = np.ones((3, 3), np.uint8)
    dige_erosion = cv2.erode(img, kernel, iterations=1)
    
    cv2.imshow('dige_erosion', dige_erosion)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    腐蚀后输出图像(减肥):
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-25-37-1650288337151-image-20220418212537049.png" alt="image-20220418212537049" style="zoom:35%;" />

    # 再膨胀一次
    kernel = np.ones((3, 3), np.uint8)
    dige_dilate = cv2.dilate(dige_erosion, kernel, iterations=1)
    
    cv2.imshow('dilate', dige_dilate)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    膨胀后输出图像(增肥):
    <img src="http://img.yibogame.com/uPic/2022-04-18-21-49-44-1650289784890-image-20220418214944784.png" alt="image-20220418214944784" style="zoom:35%;" />

    # 原图就不展示了,就是上面那个圆
    pie = cv2.imread('res/pie.png')
    
    kernel = np.ones((30, 30), np.uint8)
    dilate_1 = cv2.dilate(pie, kernel, iterations=1)
    dilate_2 = cv2.dilate(pie, kernel, iterations=2)
    dilate_3 = cv2.dilate(pie, kernel, iterations=3)
    res = np.hstack((dilate_1, dilate_2, dilate_3))
    cv2.imshow('res', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    <img src="http://img.yibogame.com/uPic/2022-04-18-21-52-02-1650289922866-image-20220418215202759.png" alt="image-20220418215202759" style="zoom:50%;" />

    相关文章

      网友评论

          本文标题:opencv笔记

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