• python-OpenCV-对图片进行操作


    anaconda https://www.anaconda.com/download/

    OpenCV拥有丰富的常用图像处理函数库

    主要应用领域有计算机视觉领域:如物体识别、图像分割、人脸识别、动作识别及运动追踪

    安装模块

    pip install opencv-python
    pip install opencv-contrib-python
    
    • 1
    • 2

    一、cv2的基本方法和属性

    import cv2 as cv
    import numpy as np
    from matplotlib import pyplot as plt
    %matplotlib inline	# 不用使用plt.show()就可以直接在页面展示出来
    
    • 1
    • 2
    • 3
    • 4

    cv.imread(文件名,属性) 读入图像 - - - 属性值有IMREAD_COLOR(读入彩色)和IMERAD_GRAYSCALE(读入灰度图像)
    文件名中不能有中文,会报错 - - - 将图片以array格式读出来 - - - 0~255,0最暗,255最亮 - - - 彩色是三维数组,灰度是二维数组

    cv.imread('youling.png')
    
    • 1

    在这里插入图片描述
    cv.imshow(窗口名,图像文件) 显示图像 - - - 彩色图像是BGR格式,使用matplotlib显示时需要转换为RGB格式

    cv.waitKey() 等待时间 - - - 毫秒级,0表示任意键终止
    键盘绑定函数,参数=0(或<0的数):一直显示窗口直到在键盘上按下一个键为止,并`返回按键对应的ASCII值``;参数>0:设置显示的时间单位为毫秒,超过这个指定的时间则返回-1

    cv.destroyAllWindows(窗口名) 删除建立的窗口

    cv.namedWindow(窗口名,属性) 创建一个窗口 - - - 属性值有WINDOW_AUTOSIZE(根据图像的尺寸自动创建),WINDOW_NORMAL(窗口大小可调整) - - - eg:cv.namedWindow(‘img’,cv.WINDOW_NORMAL)

    img = cv.imread('youling.png',cv.IMREAD_COLOR)
    cv.imshow('img',img)
    cv.waitKey(0)
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4

    cv.imwrite(filename, imgdata) 保存图像

    cv.imwrite('asd.jpg',img)
    # True	# 将img保存为名为asd.jpg的图片
    
    • 1
    • 2

    img.shape 图像的尺寸
    彩色图片的返回值是(高, 宽, 3) - - - 灰度图片是(高, 宽)

    img.shape
    # (864, 1392, 3)	# 高 宽 3代表BGR
    
    • 1
    • 2

    img.size 图像的大小

    img.size
    # 3608064	# 图片的高×宽×3  864*1392*3=3608064
    
    • 1
    • 2

    可以通过k=cv.waitKey(0) 关闭图片或保存

    img = cv.imread('youling.png',cv.IMREAD_COLOR)
    cv.imshow('img',img)
    k = cv.waitKey(0)
    if k == 27:		# 如果按的是Esc键,退出
        cv.destroyAllWindows()
    elif k == ord('s'):		# 按s键保存图片
        cv.imwrite('img.jpg',img)
        cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    将文字输入到照片中

    cv.putText(图片名,文字,坐标,字体,字体大小,字体颜色,字体粗细)
    字体的坐标是文字左下角的位置
    字体可以选cv.FONT_HERSHEY_COMPLEX,cv.FONT_HERSHEY_COMPLEX_SMALL,cv.FONT_HERSHEY_DUPLEX,cv.FONT_HERSHEY_PLAIN等等

    cv.putText(img,'hello world',(200,500),cv.FONT_HERSHEY_SIMPLEX, 15,(0,255,0),5)
    cv.imshow('img',img)
    k = cv.waitKey(0)
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4

    二、cv2的图片处理

    对图片进行缩放旋转仿射变换二值化

    1.图片缩放 cv.resize()

    cv.resize(图片,尺寸,插值算法) 支持多种插值算法,默认使用cv.INTER_LINEAR,缩小最适合cv.INTER_AREA,放大cv.INTER_CUBIC或cv.INTER_LINEAR

    import cv2 as cv
    import numpy as np
    from matplotlib import pyplot as plt
    %matplotlib inline
    
    img = cv.imread('youling.png',cv.IMREAD_COLOR)
    height,width,channel = img.shape
    b,g,r = cv.split(img)		# 将img的三维数组变成GBR的二位数组
    src = cv.merge([r,g,b])		# 在matplotlib里面展示需要变成rgb,但保存图片不用,现在保存图片R和B会互换
    res = cv.resize(src,(2*width, 2*height),interpolation=cv.INTER_CUBIC)	# 这里是宽高
    plt.subplot(121)		# 1行2列 第1张图
    plt.imshow(src)			# 将数据显示为图像,即在二维正则光栅上显示
    # plt.axis('off')		# 隐藏坐标轴
    plt.subplot(122)
    plt.imshow(res)
    # plt.axis('off')
    cv.imwrite('asd.jpg',res)	# 照片名字不能有中文 - - - 有中文不会报错,但保存不了照片
    cv.waitKey(0)
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    2.图片旋转 cv.getRotationMatrix2D()

    需要构造一个旋转矩阵,可以通过cv.getRotationMatrix2D获得

    M = cv.getRotationMatrix2D((cols/2, rows/2),45,0.6)
    arg1:旋转中心 - - - arg2:旋转角度 - - - arg3:旋转后的缩放因子

    img = cv.imread('youling.png',cv.IMREAD_COLOR)
    rows,cols,ch = img.shape
    b,g,r = cv.split(img)
    src = cv.merge([r,g,b])
    M = cv.getRotationMatrix2D((cols/2, rows/2),45,0.6)	# 旋转45度,并缩小为0.6倍
    dst = cv.warpAffine(src,M,(cols,rows))	# 对图像应用仿射变换# DST输出阵列
    plt.subplot(211)	# 2行1列 第1张图
    plt.imshow(src)
    plt.subplot(212)
    plt.imshow(dst)
    cv.waitKey(0)
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    3.图片仿射变换 cv.getAffineTransform()

    在图像仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建偏移矩阵,需要在原图中找到3个点以及它们在输出图像中的位置

    移动这3个点到其他位置

    opencv中提供了cv.getAffineTransform() 创建2x3的矩阵,将矩阵传给参数cv.warpAffine()

    img = cv.imread('youling.png',cv.IMREAD_COLOR)
    rows,cols,ch = img.shape
    b,g,r = cv.split(img)
    src= cv.merge([r,g,b])
    pts1 = np.float32([[100,100],[1000,0],[10,800]])
    pts2 = np.float32([[100,100],[1000,100],[200,800]])
    # 将图片(1000,0)的位置移动到(1000,100)的位置
    M = cv.getAffineTransform(pts1,pts2)
    dst = cv.warpAffine(src,M,(cols,rows))
    plt.subplot(121),plt.imshow(src),plt.title('Input')
    plt.subplot(122),plt.imshow(dst),plt.title('Output')
    # cv.waitKey(0)
    # cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    4.图片二值化 cv.Threshold()

    图片二值化是将图片上的像素点的灰度设置为0或255 - - - 将整个图片呈现出明显的黑白效果

    有利于图片的进一步处理,数据量减小,能凸显出感兴趣目标的轮廓

    cv.threshold(src,dst,threshold,maxValue,thresholdType) 实现对灰度图片进行阈值操作得到二值图像
    src:原始数组 - - - dst:输出数组,必须与src的类型一致 - - - threshold:指定的分割阈值 - - - maxValue:使用CV_THRESH_BINARY和CV_THRESH_BINARY_INV的最大值

    # 可以修改img_path的路径 - - - 将图片变成 灰度图片 和 黑白图片
    img_path = 'youling.png'
    img = cv.imread(img_path,cv.IMREAD_COLOR)
    # cv.cvtColor()函数将图像转换为灰度,arg2:常量cv.COLOR_BGR2GRAY
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)	# 二维数组
    cv.imshow('input',gray)	# 显示灰度图片,黑白灰
    h,w = gray.shape[:2]
    m = np.reshape(gray,[1,w*h])	# 将二维数组变成一维数组# array([[100,  98,  97, ...,  97, 100,  97]], dtype=uint8)
    mean = m.sum() / (w*h)
    print("mean:",mean)		# mean: 110.34934496727331
    ret,binary = cv.threshold(gray,mean,255,cv.THRESH_BINARY)
    cv.imshow('Binary',binary)	# 显示黑白图片
    cv.waitKey(0)
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    三、应用尺度不变特征变换

    尺度不变特征变换(Scale-invariant Feature Transform,SIFT)是用于图像处理领域的一种局部特征检测算法

    SIFT算法:

    输入:原始图片
    输出:图像的SIFT特征点
    方法:
       1.使用高斯模糊滤波器以不同的比例模糊图片
       2.将模糊图像按滤波器的标准差加倍进行分组并差分它们
       3.在差分图像的标度上找到局部极值
       4.将与局部极值相关的每个像素与相同尺度和相邻尺度的相邻像素比较
       5.从比较中选择最大或最小值
       6.排除低对比度点
       7.插入候选关键点(图像特征)以获得原始图像上的位置

    # 修改img_path的内容 - - - 找到图片的特征点
    img_path = 'youling.png'
    img = cv.imread(img_path,cv.IMREAD_COLOR)
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    sift = cv.xfeatures2d.SIFT_create()	# < cv2.SIFT 0000028440FF1910>	# cv2.SIFT
    kp = sift.detect(gray,None)			# 找出关键点	# tuple
    ret = cv.drawKeypoints(gray,kp,img)	# 三维数组,dtype=uint8	# numpy.ndarray
    cv.imshow('SIFTKeyPiont',ret)
    cv.waitKey(0)
    cv.destroyAllWindows()
    kp,des = sift.compute(gray,kp)		# 使用关键点找出sift特征向量
    # des是二维数组,dtype=float32
    print("特征点个数",np.shape(kp))
    print("特征向量纬度",np.shape(des))
    print("第一个关键点向量:\n",des[0])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    特征点个数 (136,)
    特征向量纬度 (136, 128)
    第一个关键点向量:
     [ 17.   0.   0.   3.  12.   0.   0.   3. 187.   0.   0.   0.   0.   0.
       0.  75. 164.   1.   0.   0.   0.   0.   0.  40.   4.   1.   0.   0.
       0.   0.   0.   1.  38.   0.   0.   3.  12.   0.   0.   3. 187.   1.
       0.   0.   0.   0.   0.  46. 176.   4.   0.   0.   0.   0.   0.  16.
       5.   2.   0.   0.   0.   0.   0.   0.  44.   3.   0.   1.  12.   0.
       0.   1. 187.  21.   0.   0.   0.   0.   0.   8. 166.  10.   0.   0.
       0.   0.   0.   3.   4.   4.   1.   0.   0.   0.   0.   0.  27.   3.
       0.   1.  12.   1.   0.   0. 187.  44.   0.   0.   0.   0.   0.   0.
     137.  23.   0.   0.   0.   0.   0.   0.   4.   3.   0.   0.   0.   0.
       0.   0.]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    四、使用加速鲁棒特征检测

    五、图像降噪

    噪声是数据和图像中的常见现象,减少数字图像中噪声的过程被称为图像降噪或图像去噪

    平均小窗口中的像素值,即用像素周围邻域像素的平均值代替该像素值

    opencv有一些去噪的函数,通常需要指定滤波器的强度、搜索窗口的大小和为检测相似性定义的窗口的大小

    # 修改img_path的内容 - - - 图片降噪
    img_path = 'youling.png'
    img = cv.imread(img_path,cv.IMREAD_COLOR)
    z = img.reshape((-1,3))# z是二维数组
    np.random.seed(59)
    noise = np.random.random(z.shape)<0.99
    noisy = (z*noise).reshape((img.shape))# 为图片增加噪声
    cv.imshow('noise',noisy)
    cleaned = cv.fastNlMeansDenoisingColored(noisy,None,10,7,7,21)# 图片降噪
    cv.imshow('denoised',cleaned)
    cv.waitKey(0)
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    ASP.NET Core 6框架揭秘实例演示[09]:将配置绑定为对象
    MySQL的MHA
    【luogu CF487E】Tourists(圆方树)(树链剖分)(线段树)
    【LeetCode】Day169-子数组的最小值之和
    JS 数组的排序 sort方法详解
    shein测试开发会问些啥?
    边缘计算盒子与云计算:谁更适合您的业务需求?
    Docker | 使用dockerfile生成镜像,清理docker空间
    【面试普通人VS高手系列】请说一下你对分布式锁的理解,以及分布式锁的实现
    【IC刷卡数据专题】IC刷卡数据分析的技术要点
  • 原文地址:https://blog.csdn.net/weixin_64729620/article/details/132899631