Python 3中的OpenCV(cv2):图像处理的强大工具

诸神缄默不语-个人CSDN博文目录

大家好!今天我们来探索Python 3中的一个非常强大的计算机视觉库——OpenCV(通过cv2包)。OpenCV提供了大量的图像处理和计算机视觉算法,适用于从简单的图像操作到复杂的机器学习任务。如果你是Python的新手,或者对图像处理感到困惑,那么这篇文章将为你带来全新的视角和便捷的操作方式。

文章目录

  • 安装cv2包
  • cvtColor方法:颜色空间转换
  • imshow方法:显示图像
  • waitKey方法:等待按键事件
  • destroyAllWindows方法:关闭所有窗口
  • imwrite方法:保存图像
  • 综合示例
  • threshold方法:根据像素阈值对图像进行二值化处理
  • findContours + drawContours方法:轮廓检测
  • approxPolyDP方法:轮廓线的多边形逼近
  • 总结
  • 本文撰写过程中参考的网络资料
  • 安装cv2包

    首先,你需要安装cv2包。你可以使用pip来安装:

    pip install opencv-python
    

    cvtColor方法:颜色空间转换

    cvtColor方法用于在不同的颜色空间之间转换图像。最常用的转换如将彩色图像转换为灰度图像:

    import cv2
    
    # 读取图像
    image = cv2.imread('example.jpg')
    
    # 将彩色图像转换为灰度图像
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # 显示图像
    cv2.imshow('Gray Image', gray_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    在这个例子中,cv2.COLOR_BGR2GRAY表示将BGR颜色空间转换为灰度颜色空间。
    BGR格式是OpenCV默认格式。

    cv2.cvtColor函数通常只接受uint8格式的ndarray作为输入,所以如果张量值为浮点变量时,会报如下bug;如果张量维度不对,也会报如下bug:

    cv2.error: OpenCV(4.7.0) d:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\color.simd_helpers.hpp:94: error: (-2:Unspecified error) in function '__cdecl cv::impl::`anonymous-namespace'::CvtHelper<struct cv::impl::`anonymous namespace'::Set<3,4,-1>,struct cv::impl::A0x981fb336::Set<3,4,-1>,struct cv::impl::A0x981fb336::Set<0,2,5>,2>::CvtHelper(const class cv::_InputArray &,const class cv::_OutputArray &,int)'
    > Unsupported depth of input image:
    >     'VDepth::contains(depth)'
    > where
    >     'depth' is 6 (CV_64F)
    

    这个错误信息表明在尝试使用cv2.cvtColor函数时,输入图像的深度(即数据类型)不受支持。错误中提到的depth is 6 (CV_64F)意味着输入图像的数据类型是64位浮点数(float64),而cv2.cvtColor函数通常只接受8位无符号整数(uint8)作为输入。
    要解决这个问题,需要确保输入到cv2.cvtColor函数的图像数据类型是uint8。如果图像数据是float64类型,你可能需要将其转换为uint8。这通常涉及到缩放像素值到0-255的范围,并确保它们是整数。
    下面是一个示例代码,展示了如何将float64类型的图像数据转换为uint8类型,并进行颜色空间转换:

    import numpy as np
    import cv2
    
    # 假设 image_array_reshaped 是你的 float64 类型的图像数组
    # 首先,确保像素值在 0-255 的范围内
    image_array_reshaped = np.clip(image_array_reshaped, 0, 255)
    
    # 然后,将数据类型转换为 uint8
    image_array_reshaped = image_array_reshaped.astype(np.uint8)
    
    # 现在你可以安全地使用 cv2.cvtColor 进行颜色空间转换
    image_bgr = cv2.cvtColor(image_array_reshaped, cv2.COLOR_RGB2BGR)
    

    请注意,如果你的图像数据包含浮点数,并且这些数值不是在0-255范围内的像素值,那么在转换之前你可能需要进行适当的缩放或归一化处理。
    如果你的图像数据原本就是8位无符号整数(uint8),那么错误可能是因为其他原因导致的,比如输入数组的形状不正确或者cv2.cvtColor函数的参数不正确。在这种情况下,你需要检查输入数组的形状和类型,确保它们符合cv2.cvtColor函数的要求。

    imshow方法:显示图像

    imshow方法用于在窗口中显示图像。你需要提供一个窗口名称和一个图像数组:

    cv2.imshow('Image', image)
    

    waitKey方法:等待按键事件

    waitKey方法用于等待按键事件。它的参数是以毫秒为单位的延迟时间。如果在延迟时间内按下任意键,waitKey会返回按键的ASCII码:

    cv2.waitKey(0)  # 等待任意键按下
    

    destroyAllWindows方法:关闭所有窗口

    destroyAllWindows方法用于关闭所有由OpenCV创建的窗口:

    cv2.destroyAllWindows()
    

    waitKey + destroyAllWindows 就相当于等待用户按键后,关闭所有窗口。

    imwrite方法:保存图像

    imwrite方法用于将图像保存到文件:

    cv2.imwrite('output.jpg', image)
    

    综合示例

    下面是一个综合示例,展示了如何读取图像、转换颜色空间、显示图像、等待按键事件以及保存图像:

    import cv2
    
    # 读取图像
    image = cv2.imread('example.jpg')
    
    # 将彩色图像转换为灰度图像
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # 显示原始图像和灰度图像
    cv2.imshow('Original Image', image)
    cv2.imshow('Gray Image', gray_image)
    
    # 等待按键事件
    cv2.waitKey(0)
    
    # 关闭所有窗口
    cv2.destroyAllWindows()
    
    # 保存灰度图像
    cv2.imwrite('gray_output.jpg', gray_image)
    

    threshold方法:根据像素阈值对图像进行二值化处理

    cv2.threshold (src, thresh, maxval, type)

  • src:源图片,必须是单通道
  • thresh:阈值,取值范围0~255
  • maxval:填充色,取值范围0~255
  • type:阈值类型,具体见下表

  • cv2.THRESH_BINARY → 0
    cv2.THRESH_BINARY_INV → 1
    cv2.THRESH_TRUNC → 2
    cv2.THRESH_TOZERO → 3
    cv2.THRESH_TOZERO_INV → 4
    cv2.THRESH_OTSU → 8:使用大津算法自动计算最佳阈值,使得两类的类间方差最大

    返回值是(ret,threshold)
    ret是实际使用的阈值
    threshold是进行阈值处理后的图像

    示例代码:

    # coding=utf-8
    
    origin_pic = r'trys\try_cv2_1.png'
    
    # 读取待处理图片,并转换成单通道图片
    import cv2
    img = cv2.imread(origin_pic)
    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 以阈值0为示例进行阈值处理:
    import numpy as np
    _, thresh = cv2.threshold(src=imgray, thresh=150, maxval=255, type=0)
    concat_pic = np.concatenate([imgray, thresh], axis=1)
    cv2.imwrite(r'trys\try_cv2_2.png'.format(type), concat_pic)
    

    原图:

    处理后的图片(左边是灰度图,右边是处理后的结果):

    findContours + drawContours方法:轮廓检测

    cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])

    image是一个黑白图,所以建议与threshold方法结合使用。
    method为轮廓的近似办法

    返回值是一组(contours, hierarchy)
    一个是轮廓本身,还有一个是每条轮廓对应的属性

    cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])

    其他的我没看懂,懒得查了,以后有空了再研究吧

    原图还是threshold那节用的那个原图,代码是:

    import cv2
     
    img = cv2.imread(r'trys\try_cv2_1.png')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, binary = cv2.threshold(gray,150,255,cv2.THRESH_BINARY)
     
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(img,contours,-1,(0,0,255),3)
     
    cv2.imwrite(r'trys\try_cv2_3.png',img)
    

    输出图像是:

    approxPolyDP方法:轮廓线的多边形逼近

    这个其实没太看懂,以后需要用了再仔细研究吧。

    总结

    OpenCV(通过cv2包)是一个功能强大的计算机视觉库,提供了丰富的图像处理和计算机视觉算法。通过简单的几行代码,你可以实现图像的读取、颜色空间转换、显示、保存等操作。

    希望这篇文章能帮助你更好地理解和使用OpenCV。如果你有任何问题或者想要分享更多的使用心得,欢迎在评论区留言交流!

    祝大家编程愉快!

    本文撰写过程中参考的网络资料

    1. opencv: 阈值处理(cv2.threshold) 探究(图示+源码)_thresholdapi-CSDN博客
    2. OpenCV中的图像阈值化操作详解(代码实现)_图像阈值化 代码实现-CSDN博客
    3. 深入理解 OpenCV 中的二值化:cv2.THRESH_BINARY 与 cv2.THRESH_OTSU 的组合运用_permute cv2二值化-CSDN博客
    4. OpenCV-Python教程(11、轮廓检测)_opencv矩形轮廓检测python-CSDN博客:有的部分我还没看懂,以后再研究
    5. https://www.cs.unc.edu/Research/stc/FAQs/OpenCV/OpenCVReferenceManual.pdf:还没看,以后看

    作者:诸神缄默不语

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python 3中的OpenCV(cv2):图像处理的强大工具

    发表回复