• 基于python的OpenCV图像处理学习笔记


    基于python的OpenCV图像处理学习笔记

    打开.ipynb文件

    • 打开anaconda prompt
    • 输入jupyter notebook
    • 找到文件打开即可

    1. 图像简介与图像的基本操作

    • 图像由很多的小方格组成(像素)
    • 彩色图像每个像素有三个通道RGB,每个通道对应一个值(0-255)
    import cv2 #opencv读取的格式是BGR
    import matplotlib.pyplot as plt
    import numpy as np
    
    
    # 读取数据
    img = cv2.imread('./image/cat.jpg')
    # print(img)
    
    # 图像的显示,也可以创建多个窗口
    # cv2.imshow('image', img)
    # # 等待时间,毫秒级,0表示任意键终止
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    # 图形的大小(像素)和通道
    # print(img.shape)
    
    # 灰度处理
    # img=cv2.imread('./image/cat.jpg', cv2.IMREAD_GRAYSCALE)
    # cv2.imshow('cat',img)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    # print(img.shape)
    #
    # # 图像保存
    # cv2.imwrite('./image/gray_cat.jpg', img)
    #
    # # 图像信息
    # print(type(img)) # <class 'numpy.ndarray'>
    # print(img.size) # (398, 600) = 238800
    # print(img.dtype) # uint8
    
    # 读取视频
    # vc = cv2.VideoCapture('./image/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: # 每隔0.1s刷新一次(越小播放越快) 退出键Esc退出
    #             break
    # # 释放资源
    # vc.release()
    # cv2.destroyAllWindows()
    
    # 截取部分图像数据
    # 声明图形显示方法
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    # 只取到了50*200的图像部分
    # cat=img[0:50,0:200]
    # cv_show('cat',cat)
    
    # 颜色通道提取
    # b,g,r=cv2.split(img)
    # print(b)
    # print(b.shape)
    
    # 合并图像
    # img=cv2.merge((b,g,r))
    # print(img.shape)
    
    # 只保留R
    # cur_img = img.copy()
    # print(img)
    #
    # # bgr分别对应0,1,2 cur_img[:,:,0]的意思为任意行,任意行内的任意像素点(列),的第一个值(B)为0
    # cur_img[:,:,0] = 0 #B
    # cur_img[:,:,1] = 0 #G
    # print(cur_img)
    # cv_show('R',cur_img)
    #
    # # 只保留G
    # cur_img = img.copy()
    # cur_img[:,:,0] = 0
    # cur_img[:,:,2] = 0
    # cv_show('G',cur_img)
    #
    # # 只保留B
    # cur_img = img.copy()
    # cur_img[:,:,1] = 0
    # cur_img[:,:,2] = 0
    # cv_show('B',cur_img)
    
    
    # 边界填充
    
    # BORDER_REPLICATE:复制法,也就是复制最边缘像素。
    # BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
    # BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
    # BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
    # BORDER_CONSTANT:常量法,常数值填充。
    
    # 设置填充的值
    # 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_cat=cv2.imread('./image/cat.jpg')
    # img_dog=cv2.imread('./image/dog.jpg')
    #
    # img_cat2= img_cat +10
    # print(img_cat[:5,:,0]) # 只显示5行,和B的值
    # print(img_cat2[:5,:,0])
    #
    # # 0-255越界,相当于% 256
    # print((img_cat + img_cat2)[:5,:,0] )
    #
    # # add则不会越界,最大就为255
    # print(cv2.add(img_cat,img_cat2)[:5,:,0])
    
    # 图像融合
    # 融合的前提 两张图像的shape要一致
    # img_cat=cv2.imread('./image/cat.jpg')
    # img_dog=cv2.imread('./image/dog.jpg')
    # print(img_cat.shape)
    # print(img_dog.shape)
    #
    # # 修改shape
    # img_dog = cv2.resize(img_dog, (600, 398))
    # print(img_dog.shape)
    #
    # # 按照权重融合(权重越大越明显)
    # res = cv2.addWeighted(img_cat, 0.2, img_dog, 0.8, 0)
    # cv_show('res',res)
    
    
    # 设置图像宽高比例
    # 正方形(默认总高或宽为2000)
    res = cv2.resize(img, (0, 0), fx=4, fy=4)
    cv_show('res',res)# 2000*2000
    
    res = cv2.resize(img, (0, 0), fx=2, fy=1)
    cv_show('res',res) # 1000*500
    
    res = cv2.resize(img, (500, 250), fx=2, fy=1)
    cv_show('res',res) # 500*250
    

    2.图像处理

    # 图像处理
    import cv2
    import numpy as np
    
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    
    # 灰度图
    img= cv2.imread('./image/cat.jpg')
    img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    # print(img_gray.shape)
    # cv_show('img_gray',img_gray)
    #
    # #HSV
    # # H - 色调(主波长)
    # # S - 饱和度(纯度/颜色的阴影)。
    # # V值(强度)
    #
    # hsv = cv2.cvtColor(img,cv2.COLOR_RGB2HSV)
    # cv_show('hsv',hsv)
    
    # 图像阈值
    # ret, dst = cv2.threshold(src, thresh, maxval, type)
    # src: 输入图,只能输入单通道图像,通常来说为灰度图
    # dst: 输出图
    # thresh: 阈值
    # maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
    # type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
    # cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
    # cv2.THRESH_BINARY_INV THRESH_BINARY的反转
    # cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
    # cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
    # cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
    # 0为黑,255为白
    
    # ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
    # cv_show('thresh1',thresh1)
    # ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
    # cv_show('thresh2',thresh2)
    # ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
    # cv_show('thresh3',thresh3)
    # ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
    # cv_show('thresh4',thresh4)
    # ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
    # cv_show('thresh5',thresh5)
    
    # 图像滤波(平滑处理)
    # 去除噪声
    img = cv2.imread('./image/lenaNoise.png')
    cv_show('noise',img)
    # img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    #
    # # 均值滤波
    # # 矩阵全部相加除以个数,求平均
    # print(img)
    blur = cv2.blur(img,(3,3))
    # cv_show('blur',blur)
    # print('===============')
    # print(blur)
    
    
    # 方框滤波
    # 基本和均值一样,可以选择归一化, -1 得到的结果和原始通道数表示一致,normalize归一化(求平均)
    # box = cv2.boxFilter(img,-1,(3,3), normalize=True)
    # cv_show('box',box)
    #
    #
    # # 不求平均,全部加起来,越界值如果大于255,就设置为255
    # box = cv2.boxFilter(img,-1,(3,3), normalize=False)
    # cv_show('box',box)
    
    # 高斯滤波
    # 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的(更重视相邻的(上下左右)),乘以权重
    aussian = cv2.GaussianBlur(img, (3, 3), 1)
    # cv_show('aussian',aussian)
    
    
    # 中值滤波
    # 相当于用中值代替
    # 排序后取中间值,作为结果 5表示5*5
    # 去噪声效果最好
    median = cv2.medianBlur(img, 5)  # 中值滤波
    # cv_show('median', median)
    
    
    # 展示所有的
    # np.hstack横向显示,np.stack纵向显示
    res = np.hstack((blur,aussian,median))
    #print (res)
    cv_show('median vs average', res)
    
    
    

    3. 形态学基本操作

    import cv2
    import numpy as np
    
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    # 形态学-腐蚀操作
    # 腐蚀就是将白的边缘变黑一点,kernel数组越大,腐蚀面积越大
    img = cv2.imread('./image/dige.png')
    # cv_show('dige',img)
    #
    # kernel = np.ones((3,3), np.uint8) # ones返回一个全1的n维数组,这里返回3*3,np.uint8为数据类型
    # erosion = cv2.erode(img,kernel,iterations = 1) # iterations = 1表示迭代一次
    # cv_show('erosion',erosion)
    #
    #
    pie = cv2.imread('./image/pie.png')
    # cv_show('pie',pie)
    # # 验证迭代次数,迭代次数越多,白色的圆圈越小,并且不在是园形了
    # kernel = np.ones((30,30),np.uint8)
    # 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))
    # cv_show('res',res)
    
    
    # 形态学-膨胀操作
    # kernel = np.ones((3,3), np.uint8)
    # dige_erosion = cv2.erode(img,kernel,iterations = 1)
    # cv_show('dige_erosion',dige_erosion)
    # # 膨胀则为将白色边缘扩大
    # kernel = np.ones((3,3),np.uint8)
    # dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)
    # cv_show('dilate', dige_dilate)
    #
    # 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))
    # cv_show('res', res)
    
    # 开运算
    # 先进行腐蚀,再进行膨胀
    # kernel = np.ones((3,3),np.uint8)
    # opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
    # cv_show('opening', opening)
    #
    # # 闭运算
    # # 先进行膨胀,再进行腐蚀
    # kernel = np.ones((3,3),np.uint8)
    # closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
    # cv_show('closing', closing)
    
    # 梯度运算
    # 梯度 = 膨胀 - 腐蚀
    # kernel = np.ones((7,7),np.uint8)
    # dilate = cv2.dilate(pie,kernel,iterations = 5)
    # erosion = cv2.erode(pie,kernel,iterations = 5)
    # res = np.hstack((dilate,erosion))
    # cv_show('res', res)
    # # 剩下膨胀出来的部分
    # gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
    # cv_show('gradient', gradient)
    
    
    # 礼帽和黑帽
    # 礼帽 = 顶帽 = 原始输入-开运算结果
    kernel = np.ones((7,7),np.uint8)
    tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
    cv_show('tophat', tophat)
    
    # 黑帽 = 闭运算-原始输入
    blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
    cv_show('blackhat', blackhat)
    
    
    

    4. 梯度处理

    import cv2
    import numpy as np
    
    
    def cv_show(name, img):
        cv2.imshow(name, img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    
    # 图像梯度-Sobel算子
    # dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
    # ddepth:图像的深度(输入输出一样)
    # dx和dy分别表示水平和竖直方向 dx :右边-左边,中间为0  dy:上边-下边,中间0
    # ksize是Sobel算子的大小
    
    
    # img = cv2.imread('./image/pie.png')
    # cv_show('pie',img)
    #
    # sobelx = cv2.Sobel(img,cv2.CV_64F,1,0, ksize=3)
    # sobelx = cv2.convertScaleAbs(sobelx)
    # cv_show('sobelx',sobelx)
    #
    # sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
    # cv_show('sobely',sobely)
    #
    # sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
    # cv_show('sobelxy',sobelxy)
    
    # 分开计算合并
    # img = cv2.imread('./image/lena.jpg',cv2.IMREAD_GRAYSCALE)
    # sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
    # # 绝对值
    # sobelx = cv2.convertScaleAbs(sobelx)
    # sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
    # sobely = cv2.convertScaleAbs(sobely)
    # sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
    # cv_show('sobelxy',sobelxy)
    #
    # # 直接计算效果更差
    # sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
    # sobelxy = cv2.convertScaleAbs(sobelxy)
    # cv_show('sobelxy',sobelxy)
    
    # scharr算子
    # 核变大了,结果更敏感一些
    
    
    # laplacian算子
    #0 1 0
    #1 -4 1
    #0 1 0
    
    # 中间点与中间的的四周
    
    
    #不同算子的差异
    img = cv2.imread('./image/lena.jpg',cv2.IMREAD_GRAYSCALE)
    
    # 边界
    sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
    sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
    sobelx = cv2.convertScaleAbs(sobelx)
    sobely = cv2.convertScaleAbs(sobely)
    sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
    
    # 更加敏感,更细致
    scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
    scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
    scharrx = cv2.convertScaleAbs(scharrx)
    scharry = cv2.convertScaleAbs(scharry)
    scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
    
    
    # 效果较差
    laplacian = cv2.Laplacian(img,cv2.CV_64F)
    laplacian = cv2.convertScaleAbs(laplacian)
    
    res = np.hstack((sobelxy,scharrxy,laplacian))
    cv_show('res',res)
    
    版权声明:本文为博主原创文章,转载请附上博文链接!
  • 相关阅读:
    redis数据同步之redis-shake
    spring拦截机制中Filter(过滤器)、interceptor(拦截器)和Aspect(切面)的使用及区别
    MySQL之MVCC与幻读
    Notepad
    mac环境,python+selenium环境搭建,解决chromedriver报错问题
    大规模抓取的抓取效率和抓取技巧问题
    安卓逆向8,解决app抓包抓不到的问题
    [loj6033]棋盘游戏
    [ccBB]Billboards
    [loj6051]PATH
  • 原文地址:https://www.cnblogs.com/zq98/p/15028004.html
Copyright © 2020-2023  润新知