zoukankan      html  css  js  c++  java
  • 数字图像处理学习笔记


    源码和数据集获取地址:
    链接:https://pan.baidu.com/s/104AGSp-4JMfENzUYv4bjhg
    提取码:4g7c


    实验一、图像的读取和运算

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    
    
    def show_img(name,image):
        cv2.imshow(name,image)
        cv2.waitKey()
        cv2.destroyAllWindows()
    
    # 读入图片
    img = cv2.imread('./image/leonard.jpg')
    # 显示图片
    show_img('leonard.jpg',img)
    
    # 保存图片
    cv2.imwrite('save.jpg',img)
    
    True
    
    # 图片运算
    img1 = cv2.imread('./image/leonard.jpg')
    img2 = cv2.imread('./image/leonard1.jpg')
    add = cv2.add(img1,img2)
    subtract = cv2.subtract(img1,img2)
    multiply = cv2.multiply(img1,img2)
    divide = cv2.divide(img1,img2)
    img1 = cv2.imread('./image/leonard.jpg')
    img2 = cv2.imread('./image/leonard1.jpg')
    add = cv2.add(img1,img2)
    subtract = cv2.subtract(img1,img2)
    multiply = cv2.multiply(img1,img2)
    divide = cv2.divide(img1,img2)
    plt.subplot(161),plt.imshow(img1),plt.title('img1')
    plt.subplot(162),plt.imshow(img2),plt.title('img2')
    plt.subplot(163),plt.imshow(add),plt.title('add')
    plt.subplot(164),plt.imshow(subtract),plt.title('subtract')
    plt.subplot(165),plt.imshow(multiply),plt.title('multiply')
    plt.subplot(166),plt.imshow(divide),plt.title('divide')
    plt.show()
    

    实验二、图像的灰度变换及直方图均衡化

    任务:

    以一幅 256×256 象素的数字图像为实验对象,观察图像的二值化效果和直方图分布。

    对图像的直方图进行均衡化。

    import cv2
    import matplotlib.pyplot as plt
    
    
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey()
        cv2.destroyAllWindows()
    
    
    # 图像二值化
    img = cv2.imread('./image/leonard_256x256.jpg')
    img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    cv_show('img_gray',img_gray)
    print(img_gray)
    print(img_gray.shape)
    
    [[125 111  84 ...  20  18  18]
     [149 127  96 ...  16  19  16]
     [155 126 100 ...  15  20  17]
     ...
     [ 49  56  62 ...  19  11   9]
     [ 43  47  64 ...  16   6   4]
     [ 33  56  61 ...  18   6   3]]
    (256, 256)
    
    # 图像直方图
    hist = cv2.calcHist([img],[0],None,[256],[0,256])
    print(hist.shape) # (256, 1)一维数组,有256个数据,分别代表每个值出现的次数
    # print(hist)
    
    # img.ravel()将二维图像转换为一维的数据
    plt.hist(img.ravel(),256)
    plt.show()
    
    (256, 1)
    

    # 均衡化处理
    import numpy as np
    
    # 直接均衡化,均衡化后图像有些地方太亮,失去了细节信息
    equ = cv2.equalizeHist(img_gray)
    
    # 自适应直方图均衡化 保留了细节
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
    res_clahe = clahe.apply(img_gray)
    
    # 直方图对比
    plt.rcParams['font.family'] = ['sans-serif']
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.figure()
    plt.subplot(311)
    plt.hist(img_gray.ravel(),256,label='原始图像')
    plt.legend(loc='upper right')
    plt.subplot(312)
    plt.hist(equ.ravel(),256,label='均衡化')
    plt.legend(loc='upper right')
    plt.subplot(313)
    plt.hist(res_clahe.ravel(),256,label='自适应均衡化')
    plt.legend(loc='upper right')
    plt.show()
    
    
    
    # 图像对比
    res = np.hstack((img_gray,equ,res_clahe))
    cv_show('res',res)
    

    实验三、图像的平衡和锐化处理

    任务:

    • 以一幅 256×256 象素的数字图像为对象
      采用中值滤波处理进行平滑处理
      和 Soble 算子图像锐化方法
    import cv2
    import numpy as np
    from IPython.display import Image
    
    # 0 表示灰度图
    img = cv2.imread('./image/leonard_256x256_Noise.jpg',0)
    
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey()
        cv2.destroyAllWindows()
    
    
    # 自定义的平均滤波
    kernel = np.ones((5,5),np.float32)/25
    print(kernel)
    
    [[0.04 0.04 0.04 0.04 0.04]
     [0.04 0.04 0.04 0.04 0.04]
     [0.04 0.04 0.04 0.04 0.04]
     [0.04 0.04 0.04 0.04 0.04]
     [0.04 0.04 0.04 0.04 0.04]]
    
    # 第二个参数为图像的深度,-1表示和原图一样
    dst = cv2.filter2D(img,-1,kernel)
    
    # 图像变得很模糊,看着有点难受的感觉
    res = np.hstack((img,dst))
    cv_show('Original&Averaging',res)
    

    均值滤波

    卷积框覆盖区域的所有像素的平均均值来代替中心元素

    blur = cv2.blur(img,(5,5))
    
    # 效果和平均滤波一样
    res = np.hstack((img,blur))
    cv_show('Original&Blur',res)
    
    Image(filename = './image/1.png', width=400)
    

    高斯滤波

    可以有效的去除高斯噪点

    (卷积核里的值符合高斯分布,中心的值最大,其余方框根据距离中心元素的距离递减,构成一个高斯小山包)

    # 第三个参数为标准差,0表示函数自行计算
    gaussianblur = cv2.GaussianBlur(img,(5,5),0)
    res = np.hstack((img,gaussianblur)) 
    cv_show('Original&GaussianBlur',res)
    
    Image(filename = './image/2.png', width=400)
    

    中值滤波(中值模糊)

    用卷积框对应像素的中值来替换中心像素的值

    常用于去除椒盐噪声

    median = cv2.medianBlur(img,5)
    res = np.hstack((img,gaussianblur))
    cv_show('Original&medianBlur',res)
    
    Image(filename='./image/3.png',width=400)
    

    双边滤波

    以保持边界清晰的情况况下有效的去除噪声

    0 领域直径 两个75是 空间高斯函数标准差 灰度值相似性高斯函数标准差

    bilatera = cv2.bilateralFilter(img,0,75,75)
    
    res = np.hstack((img,bilatera))
    cv_show('Original&bilateralFilter',res)
    
    Image(filename='./image/4.png',width=400)
    

    图像梯度

    图像更加的细节

    sobel算子

    # ddepth:图像的深度(输入输出一样-1)
    # dx和dy分别表示水平和竖直方向 dx :右边-左边,中间为0  dy:上边-下边,中间0
    # ksize是Sobel算子的大小
    sobelx= cv2.Sobel(img,-1,1,0,ksize=3)
    sobelx = cv2.convertScaleAbs(sobelx)
    sobely= cv2.Sobel(img,-1,0,1,ksize=3)
    sobely = cv2.convertScaleAbs(sobely)
    sobelxy= cv2.Sobel(img,-1,1,1,ksize=3) # 直接合并
    sobelxy1 = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) # 分开按权重合并
    res = np.hstack((img,sobelx,sobely,sobelxy,sobelxy1))
    cv_show('res',res)
    
    Image(filename='./image/5.png',width=1000)
    

    scharr算子

    # 相比sobel算子就是核(值)变大了,结果更敏感一些
    scharrx = cv2.Scharr(img,-1,1,0)
    scharry = cv2.Scharr(img,-1,0,1)
    scharrx = cv2.convertScaleAbs(scharrx)
    scharry = cv2.convertScaleAbs(scharry)
    scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
    res = np.hstack((img,scharrx,scharry,scharrxy))
    cv_show('res',res)
    
    Image(filename='./image/6.png',width=800)
    

    laplacian算子

    0 1 0

    1 -4 1

    0 1 0

    laplacian = cv2.Laplacian(img,-1)
    cv_show('laplacian',laplacian)
    
    Image(filename='./image/7.png',width=200)
    

    sobel算子效果一般,scharr效果更细节,laplacian比sobel更不明显

    实验四-图像的膨胀、腐蚀和细化

    任务:

    • 对指定图像进行腐蚀、膨胀和细化,
    • 把得到的结果图像都显示于屏幕上
    # 方便查看图片导入的包
    from IPython.display import Image
    # 导入包,和图片显示函数
    import cv2
    import numpy as np
    
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey()
        cv2.destroyAllWindows()
    
    
    # 读入图片(以灰度图形式)
    img = cv2.imread('./image/ka.png',0)
    # 定义卷积核
    kernel = np.ones((5,5),np.uint8)
    kernel
    
    array([[1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1]], dtype=uint8)
    

    腐蚀

    作用:

    • 腐蚀边缘,白色区域减小
    • 可以有效的去除白噪声,也可以用来断开两个连在一起的物体
    # iterations迭代执行次数
    erosion = cv2.erode(img,kernel,iterations=1)
    res = np.hstack((img,erosion))
    cv_show('img&erosion',res)
    
    Image(filename = './pic/1.png', width=400)
    

    腐蚀

    作用:

    • 增加白色区域
    • 一般去噪声时,先用腐蚀,再膨胀
    • 也可以用来连接两个分开的物体
    dilation = cv2.dilate(img,kernel,iterations=1)
    res = np.hstack((img,dilation))
    cv_show('img&dilation',res)
    
    Image(filename='./pic/2.png',width=400)
    

    开运算

    作用:

    • 先腐蚀再膨胀
    • 用来去除噪声
    img_Noise = cv2.imread('./image/ka_Noise.png',0)
    opening = cv2.morphologyEx(img_Noise,cv2.MORPH_OPEN,kernel)
    res = np.hstack((img_Noise,opening))
    cv_show('img_Noise&opening',res)
    
    Image(filename='./pic/3.png',width=400)
    

    闭运算

    作用:

    • 先膨胀再腐蚀
    • 常用来填充前景物体中的小洞,或小黑点
    img_Noise1 = cv2.imread('./image/ka_Noise1.png',0)
    closing = cv2.morphologyEx(img_Noise1,cv2.MORPH_CLOSE,kernel)
    res = np.hstack((img_Noise1,closing))
    cv_show('img_Noise1&closing',res)
    
    Image(filename='./pic/4.png',width=400)
    

    形态学梯度

    • 膨胀与腐蚀的区别
    • 结果看上去就像前景物体的轮廓
    • 膨胀 - 腐蚀
    gradint = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel)
    res = np.hstack((img,gradint))
    cv_show('img&gradint',res)
    
    Image(filename='./pic/5.png',width=400)
    

    礼帽

    • 原图 - 开运算
    kernel = np.ones((9,9),np.uint8)
    tophat = cv2.morphologyEx(img_Noise,cv2.MORPH_TOPHAT,kernel)
    res = np.hstack((img_Noise,tophat))
    cv_show('img_Noise&tophat',res)
    
    Image(filename='./pic/6.png',width=400)
    

    黑帽

    • 闭运算 - 原始图像
    blackhat = cv2.morphologyEx(img_Noise1,cv2.MORPH_BLACKHAT,kernel)
    res = np.hstack((img_Noise1,blackhat))
    cv_show('img_Noise1&blackhat',res)
    
    Image(filename='./pic/7.png',width=400)
    

    总结

    • 腐蚀:减小白色区域,增加黑色区域,分开连在一起并且颜色差异不大的物体
    • 膨胀: 增加白色区域,突出白色
    • 开运算:先腐蚀,在膨胀,可去除明亮的小点
    • 闭运算:先膨胀,再腐蚀,可去除明亮物体中的小黑点
    • 礼帽:顶帽运算往往用来分离比邻近点亮一些的斑块
    • 黑帽:用来分离比邻近点暗一些的斑块

    实验五、图像阈值处理与边缘检测

    任务:

    • 对指定图像进行自适应门限值分割和边缘提取
    # 方便查看图片导入的包
    from IPython.display import Image
    # 导入包,和图片显示函数
    import cv2
    import numpy as np
    
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey()
        cv2.destroyAllWindows()
    
    # 导入图片(原图)
    img = cv2.imread('./image/leonard_256x256.jpg',0)
    cv_show('img',img)
    

    图像阈值处理

    • src:表示的是图片源
    • thresh:表示的是阈值(起始值)
    • maxval:表示的是最大值
    • type:表示的是这里划分的时候使用的是什么类型的算法,常用值为0(cv2.THRESH_BINARY)
    ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
    print(ret) # ret就是最小值(起始值),th1是图像
    ret,th2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
    ret,th3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
    ret,th4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
    ret,th5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
    res = np.hstack((th1,th2,th3,th4,th5))
    cv_show('res',res)
    
    127.0
    
    Image(filename='./image/1.png')
    # 不同参数的图像,常用前两种
    # THRESH_BINARY 大于127取255,否知取0
    # THRESH_BINARY_INV 反之
    

    自适应阈值

    • 第一个原始图像
    • 第二个像素值上限
    • 第三个自适应方法Adaptive Method:
    • cv2.ADAPTIVE_THRESH_MEAN_C :领域内均值
    • cv2.ADAPTIVE_THRESH_GAUSSIAN_C :领域内像素点加权和,权 重为一个高斯窗口
    • 第四个值的赋值方法:只有cv2.THRESH_BINARY 和cv2.THRESH_BINARY_INV
    • 第五个Block size:规定领域大小(一个正方形的领域)
    • 第六个常数C,阈值等于均值或者加权值减去这个常数(为0相当于阈值 就是求得领域内均值或者加权值),这种方法理论上得到的效果更好,相当于在动态自适应的调整属于自己像素点的阈值,而不是整幅图像都用一个阈值。
    # 中值滤波
    img = cv2.medianBlur(img,5)
    ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
    th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,1)
    th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,1)
    res = np.hstack((img,th1,th2,th3))
    cv_show('res',res)
    
    Image(filename='./image/2.png')
    

    Canny边缘检测

      1. 使用高斯滤波器,以平滑图像,滤除噪声。
      1. 计算图像中每个像素点的梯度强度和方向。
      1. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
      1. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
      1. 通过抑制孤立的弱边缘最终完成边缘检测。

    canny函数参数:

    • 后两个参数minVal,maxVal
    • 梯度大于maxVal处理为边界
    • 在两者之间,连接有边界保留,否者舍弃
    • 小于minVal,舍弃
    img = cv2.imread('./image/leonard_256x256.jpg',0)
    # 高斯滤波
    aussian = cv2.GaussianBlur(img, (3, 3), 1)
    edges = cv2.Canny(aussian,100,200)
    res = np.hstack((aussian,edges))
    cv_show('res',res)
    
    Image(filename='./image/3.png',width=400)
    

    img = cv2.imread('./image/leonard_256x256.jpg',0)
    # 高斯滤波
    aussian = cv2.GaussianBlur(img, (3, 3), 1)
    edges = cv2.Canny(aussian,245,255)
    res = np.hstack((aussian,edges))
    cv_show('res',res)
    
    Image(filename='./image/4.png',width=400)
    

  • 相关阅读:
    【CF580D】Kefa and Dishes
    【poj3311】Hie with the Pie
    校外实习-7.7
    校外实习-7.6
    校外实习-7.5
    校外实习-7.4
    作业九-课程总结(补充)
    作业九-课程总结
    作业四——结对编程四则运算
    作业三
  • 原文地址:https://www.cnblogs.com/zq98/p/13028742.html
Copyright © 2011-2022 走看看