• 三、机器学习基础知识:Python常用机器学习库(图像处理相关库)


    1、OpenCV

    OpenCV Python是一个用于解决计算机视觉问题的Python库,是用基于C++实现的OpenCV构成的Python包。OpenCV Python和Numpy兼容,数据都被转换成Numpy数据结构,这使得OpenCV更容易与其它库(如SciPy和Matplotlib)集成。

    1.1 窗口操作函数

    使用OpenCV可以利用里面的函数在窗口进行图像的显示,涉及到的主要函数有三种:
    (1)imshow()函数
    imshow()函数是在指定的窗口中显示图像,窗口自动调整为图像大小。语法格式为imshow(string winName, Array InputData),其中,参数winName 是窗口名称,参数
    InputData 为输入的图像。如果创建多个窗口,则各窗口需要具有不同的窗口名称。
    (2)destroyAllWindows()与DestroyWindow (string winName)
    这两个函数都可以卸载窗口,区别在于,函数destroyAllWindows()卸载全部窗口,而函数 DestroyWindow()卸载由参数winName 指定的窗口。
    (3)waitkey(int delay =0)
    函数 waitKey()等待用户按键,其参数delay是延迟的时间,单位为ms。在等待时间内如果检测到键盘动作,则返回按键的ASCII码,如果没有按下任何键,则返回-1。参数 delay 默认为0,即一直等待键盘输人。

    1.2 图像处理

    在使用OpenCV时有cv和cv2两个版本,这两个版本都提供了对图片进行读、写和显示的功能。cv对应的函数是LoadImage()、ShowImage()和SaveImage()函数;cv2对应的函数是imread()、imwrite()和imshow()函数,下面以cv2版本为例介绍其中包含的常见函数。
    (1)图像的基本读写操作
    基本图像处理的函数包括imread()、imwrite()、split()、merge()等。图像读取函数imread()能加载图像文件并返回图像矩阵,如果无法读取图像,将返回一个空矩阵,imread()函数支持bitmap位图、JEPG文件、png图形等各种常见的图形图像格式。
    imread()函数的基本格式如下:

    imread(const String &filename, int flags)
    
    • 1

    其中filename表示文件名,flgs为图像色彩模式,默认为IMREAD_COLOR(值为1,BGR图像),其他常见取值如下表所示:

    Mode值说明
    IMREAD_UNCHANGED值为-1,按原样返回读取的图像,带有alpha通道(R,G,B,A 四个通道)
    IMREAD_GRAYSCALE值为0,将图像转换成单通道灰度图
    IMREAD_COLOR值为1,将图像转换为3通道BGR彩色图像,不带alpha通道
    IMREAD_REDUCED_GRAYSCALE_2值为16,将图像转换成单通道灰度图像,并且图像尺寸减小1/2
    IMREAD_REDUCED_COLOR_2值为17,将图像转换成3通道BGR彩色图像,并且图像尺寸减小1/2
    IMREAD_LOAD_GDAL值为8,使用gdal驱动程序加载图像

    图像读取与保存实例:
    使用cv2读取图像,将图像转换为灰度图显示并保存。

    import cv2 
    img = cv2.imread('img.jpg',0)  #转变为灰度图
    cv2.imshow('image',img)
    k = cv2.waitKey(0)
    if k == 27:                 #按Esc键直接退出
        cv2.destroyAllWindows()
    elif k == ord('s'):            # 按's'键先保存灰度图,再退出
        cv2.imwrite('result.png',img)
        cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    (2)图像的通道拆分操作
    图像通常由多个通道组成,使用cv2的merge()和split()函数可以对图像的通道进行拆分与组合,例如将图像拆分为三个通道,然后将每个通道单独合成新的图像并保存。
    拆分实例:

    import numpy as np
    import cv2 
    img = cv2.imread('img.jpg')   #BGR图像模式
    cv2.imshow('image',img)
    k = cv2.waitKey(0)
    if k == 13:                #按Enter键退出
        cv2.destroyAllWindows()
    elif k == ord('s'):           #按's'键保存并退出
        b,g,r = cv2.split(img)   #图像拆分成三个通道
        zeros = np.zeros(img.shape[:2], dtype = "uint8")   #值为0的单通道数组    
        imgr=cv2.merge([zeros, zeros,r])     #合并图像
        imgg=cv2.merge([zeros, g,zeros])
        imgb=cv2.merge([b,zeros, zeros])
        #将新图像写入文件
        cv2.imwrite('r.png',imgr) 
        cv2.imwrite('g.png',imgg)
        cv2.imwrite('b.png',imgb)    
        cv2.destroyAllWindows()   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    1.3 图像捕获与人脸检测

    在进行图像处理前还可以使用OpenCV中的cv2.VideoCapture()函数进行摄像头图像的捕获,其构造函数如下:

    VideoCapture()
    VideoCapture(cam)
    VideoCapture(const string& filename)
    
    • 1
    • 2
    • 3

    其中第一个是默认无参构造函数;第二个指定要打开的摄像头设备,取值为0时表示从摄像头直接获取;第三个参数为指定路径的视频文件名称。
    此外还有read()方法和release()方法。read()方法用于读取视频的帧,返回值有两个:ret,frame,其中ret为布尔值,如果读取到正确的帧,则返回True,读取到文件结尾就返回False;frame为读取到的每帧的图像,是三维矩阵。release()方法用于释放并关闭摄像头。
    捕获摄像头图像实例:

    import cv2
    cap  = cv2.VideoCapture(0)
    while(True):
        ret, frame = cap.read()    
        cv2.imshow(u"Capture", frame)
        key = cv2.waitKey(1)
        if key & 0xff == ord('q') or key == 27:
            print(frame.shape,ret)
            break
    cap.release()
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在摄像头捕获到图像时,若需要判断是否为人脸,可使用Haar特征分类器,该分类器为一个XML文件,文件中包含了描述人体各个部位的Haar特征值,包括人脸、眼睛、嘴唇等,文件存放在OpenCV安装目录中的\data\haarcascades目录下,一般包括多个分类器,可以根据分类器的名称判断该分类器的用途,例如haarcascade_frontalface_alt.xml和haarcascade_fronttalface_alt2.xml可以作为人脸识别的Haar特征分类器。

    结合分类器文件,可以使用OpenCV中的detectMultiScale()函数进行多个人脸检测,检测出图片中包含的所有人脸,同时使用vector保存各个人脸的坐标、大小(用矩形表示)。detectMultiScale()函数格式如下:

    objects = cv2.CascadeClassifier.detectMultiScale(const Mat& image,CV_OUT vector<Rect>& objects,double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, Size minSize = Size(), Size maxSize = Size())
    
    • 1

    其中image表示待检测图片,一般为灰度图像;objects为待检测物体的矩形框向量组;scaleFactor为前后两次相继的扫描中,搜索窗口的比例系数,默认为1.1,即每次搜索窗口依次扩大10%;minNeighbors表示构成检测目标的相邻矩形的最小个数,默认为3个;flags默认值为0,该参数通常被省略,在使用低版本 OpenCV时,它可能会被设置为 CV_HAAR_DO_CANNY_PRUNING,表示使用 Canny 边缘检测器来排除边缘过多或过少的区域。
    minSize和maxSize用于限制目标区域的范围。
    摄像头范围的人脸检测:

    import cv2
    cascPath=r"haarcascade_frontalface_alt2.xml"
    faceCascade = cv2.CascadeClassifier(cascPath)
    cap  = cv2.VideoCapture(0)
    while(True):
        ret, img = cap.read()    
        
        faces = faceCascade.detectMultiScale(img, 1.2, 2, cv2.CASCADE_SCALE_IMAGE,(20, 20))    
        for (x, y, w, h) in faces:        
            img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)        
        cv2.imshow(u"Detect faces", img)
        
        key = cv2.waitKey(1)
        if key & 0xFF==ord('q') or key == 27:        
            break
    cv2.destroyAllWindows()
    cap.release()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2、PIL

    在进行图像识别时,图像的质量对识别的结果具有非常重要的影响,因此一般在识别之前会对图像进行预处理。PIL模块是Python中最常用的图像处理库,它能够完成图像处理、图像批处理归档、图像展示等任务。

    2.1 主要函数

    PIL可以处理多种文件格式的图像,具有强大而便捷的图像处理和图形处理能力,其中对图像进行的基础操作基本上都包含在PIL的Image模块当中,该模块包含的函数可以使用图像的打开、保存、转换、合成、滤波等操作。Image模块的常用函数如下:

    函数名功能
    open()打开图像
    save()保存图像
    convert()图像格式转换
    show()显示图像
    split()从图像中拆分出各个通道
    merge()将多个通道合成一个图像
    crop()裁剪指定区域
    resize()缩放图像
    blend()将两幅图混合成一幅
    filter()设置滤波器对图像进行处理
    fromarray()从NumPy的ndarray数组生成图像

    2.2 表情图像合成

    心理学定义了人类6种基本表情:分别为快乐、悲伤、愤怒、惊讶、厌恶和恐惧。有的研究者尝试将不同的表情进行比对、合成,发现表情之间存在的内在联系。表情的合成可以使用图像合成实现,PIL 的 Image 模块提供了合成函数 blend(),功能是对参教给定的两个图像及透明度alpha,插值生成一个新图像。
    函数格式如下:

    PIL.image.blend(im1,im2,alpha)
    
    • 1

    即输出满足如下公式:
    out = im1*(1-alpha)+im2*alpha
    若alpha取值为0,则合成图像与im1完全一致,若alpha取值为1,则合成图像与im2完全一致。此外在合成过程中,两张图像的尺寸和模式需要一致。
    表情图像合成实例:

    from PIL import Image
    img1 = Image.open( "1.jpg ")  
    img1 = img1.convert('RGBA')
    
    img2 = Image.open( "2.jpg ")
    img2 = img2.convert('RGBA')
    
    img = Image.blend(img1, img2, 0.4)
    img.show()
    img.save( "3.png")  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.3 手写数字转换

    数字图像在计算机内的存储方式是点阵式的,每个点存储了该像素的颜色值。图像处理的很多操作是针对图像的像素进行的,如滤波。使PIL对图像进行底层像素处理也很方便。在数字图像坐标系中,图像的起始点在左上角,为(0,0) ,整体向右下方延伸,假设纵轴以x轴表示,横轴以y轴表示,则一个像素可以使用(x,y)坐标来获取。
    例如在进行手写数字识别时,需要先将数字图像预处理为文本,即使用PIL模块读取二值图,并将图像保存到文本文件中,实现过程如下:

    from PIL import Image
    import numpy as np
    import matplotlib.pyplot as plt
    
    img=Image.open('8.jpg').convert('L')
    img=np.array(img)
    rows,cols=img.shape
    txt=""
    
    for i in range(rows):
        for j in range(cols):
            if (img[i,j]<=128):
                txt+='1'
            else:
                txt+='0'
        txt+="\n"        
    
    with open('8.txt','w') as f1: 
        f1.write(txt)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    原数字图:
    在这里插入图片描述
    识别后的文本:
    在这里插入图片描述

    2.4 滤波查找图像边缘

    图像识别可以基于颜色、轮廓、数值等模式。在预处理时,对于边缘不够鲜明的图像,可以进行图像锐化。锐化能够突出图像的边缘信息,加强图像的轮廓特征,便于人眼的观察和机器的识别。提取边缘的锐化也称为边缘检测,边缘检测和很多图像处理方法一样,一般使用卷积和滤波方法。
    PIL库的ImageFilter模块提供了对图像进行平滑、锐化、边界增强等处理的滤波器,这些滤波器主要用于Image磊的filter()方法,使用时利用该函数来调用ImageFilter模块预定义的滤波器,从而对图像进行滤波处理,常用滤波器如下所示:

    滤波器作用
    BLUR模糊
    CONTOUR提取轮廓
    DETAIL细节增强
    EDGE_ENCHANCE边缘增强
    EDGE_ENCHANCE_MORE深度边缘增强
    EMBOSS浮雕效果
    FIND_EDGES查找边缘
    SMOOTH平滑
    SMOOTH_MORE深度平滑
    SHARPEN锐化

    滤波器查找图像边缘实例:

    from PIL import Image,ImageFilter
    im = Image.open("people.jpg")
    #轮廓
    im.filter(ImageFilter.CONTOUR).save(r'FindCt.jpg')
    #找到边缘
    im.filter(ImageFilter.FIND_EDGES).save(r'FindEg.jpg')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    原图:
    在这里插入图片描述
    轮廓图:
    在这里插入图片描述
    边缘图:
    在这里插入图片描述

  • 相关阅读:
    Kotlin 协程调度切换线程是时候解开真相了
    python个人博客毕业设计开题报告
    《重构代码设计》
    7个关键组件保障小型企业安全在线
    R-CNN、Fast RCNN和Faster RCNN的详细讲解
    【模板】自适应辛普森积分
    Golang入门笔记(10)—— 闭包 closure
    基于图的路径搜索技术基础知识
    中国印象—自制烘焙系列
    【AI学习】了解OpenAI o1背后的self-play RL:开启新的智能道路
  • 原文地址:https://blog.csdn.net/weixin_42051846/article/details/133104710