Python 3中的OpenCV(cv2):图像处理的强大工具 本文介绍cv2包
大家好!今天我们来探索Python 3中的一个非常强大的计算机视觉库——OpenCV(通过cv2
包)。OpenCV提供了大量的图像处理和计算机视觉算法,适用于从简单的图像操作到复杂的机器学习任务。如果你是Python的新手,或者对图像处理感到困惑,那么这篇文章将为你带来全新的视角和便捷的操作方式。
文章目录
安装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 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。如果你有任何问题或者想要分享更多的使用心得,欢迎在评论区留言交流!
祝大家编程愉快!
本文撰写过程中参考的网络资料
- opencv: 阈值处理(cv2.threshold) 探究(图示+源码)_thresholdapi-CSDN博客
- OpenCV中的图像阈值化操作详解(代码实现)_图像阈值化 代码实现-CSDN博客
- 深入理解 OpenCV 中的二值化:cv2.THRESH_BINARY 与 cv2.THRESH_OTSU 的组合运用_permute cv2二值化-CSDN博客
- OpenCV-Python教程(11、轮廓检测)_opencv矩形轮廓检测python-CSDN博客:有的部分我还没看懂,以后再研究
- https://www.cs.unc.edu/Research/stc/FAQs/OpenCV/OpenCVReferenceManual.pdf:还没看,以后看