Python 3中的OpenCV(cv2):图像处理的强大工具 本文介绍cv2包

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

大家好!今天我们来探索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。如果你有任何问题或者想要分享更多的使用心得,欢迎在评论区留言交流!

祝大家编程愉快!

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

  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:还没看,以后看
作者:诸神缄默不语原文地址:https://blog.csdn.net/PolarisRisingWar/article/details/143799257

%s 个评论

要回复文章请先登录注册