二、图像预处理
1、图像翻转
cv2.flip(src, flipCode) :flipCode :0
:沿 X 轴翻转(垂直翻转);1:沿 Y 轴翻转(水平翻转),-1
:沿 X 轴和 Y 轴翻转(同时水平和垂直翻转)。
2、仿射变换
一种线性变换,它保持了点之间的相对距离不变,即平行线在变换后仍然保持平行。
img = cv2.imread("images/car2.png")
# 当前面 0 垂直翻转,1水平翻转,-1 水平锤子翻转
f0_img = cv2.flip(img, 0)
f1_img = cv2.flip(img, 1)
f2_img = cv2.flip(img, -1)
cv2.imshow("old", img)
cv2.imshow("new0", f0_img)
cv2.imshow("new1", f1_img)
cv2.imshow("new2", f2_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.1、图像旋转
cv2.getRotationMatrix2D(center, angle, 1) ,设置旋转矩阵(参数1确定中心点,参数2为变化角度,参数3是图片缩放比例)
cv2.warpAffine(image, M, (w, h)) ,设置图片使用特定方式进行旋转(参数2为旋转矩阵,参数3为图片尺寸)
使用 (h, w) = image.shape[:2] 获取图片尺寸。
img = cv2.imread("images/car.png")
# 获取图片像素
(h, w) = img.shape[:2]
# 获取旋转的点
center = (100, 120)
# 获取度数
du = 30
# 获取图像矩阵 参数一为旋转中心点,参数二旋转度数,参数三为缩放比例
m = cv2.getRotationMatrix2D(center, du, 1)
# 图片旋转
w_img = cv2.warpAffine(img, m, (w, h))
cv2.imshow("img", img)
cv2.imshow("w_img", w_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.2、图像平移
np.float32([[1, 0, tx], [0, 1, ty]]) ;使用numpy库的float32创建一个平移矩阵。在使用 cv2.warpAffine 函数处理。
将旋转矩阵参数变更平移矩阵。
img = cv2.imread("images/car.png")
# 获取图片像素
(h, w) = img.shape[:2]
# 获取旋转的点
center = (100, 120)
# 创建平移矩阵
tx, ty = 100, 50
# np.float32([[1, 0, tx], [0, 1, 0]])
# 参数为 [1, 0, tx] 分别表示 x轴保持原本比例,y轴不旋转(也就是原点和右下角点位于同一个x点位), tx 表示x移动位置
# 参数为 [0, 1, 0] 分别表示 x轴不旋转,y轴保持原本比列, ty 表示y移动位置
t = np.float32([[1, 0, tx], [0, 1, ty]])
# 图片旋转
w_img = cv2.warpAffine(img, t, (w, h))
cv2.imshow("img", img)
cv2.imshow("w_img", w_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.3、图像缩放
与平移一致,变更参数。
# 参数为 [1, 0, tx] 分别表示 x轴保持原本比例,y轴不旋转(也就是原点和右下角点位于同一个x点位), tx 表示x移动位置
# 参数为 [0, 1, ty] 分别表示 x轴不旋转,y轴保持原本比列, ty 表示y移动位置np.float32([[1.5, 0, 1], [0, 1.5, 0]])
2.4、图像变形
与平移一致,变更参数。
# 参数为 [1, 0, tx] 分别表示 x轴保持原本比例,y轴不旋转(也就是原点和右下角点位于同一个x点位), tx 表示x移动位置
# 参数为 [0, 1, ty] 分别表示 x轴不旋转,y轴保持原本比列, ty 表示y移动位置np.float32([[1, 0.2, 1], [0.2, 1, 0]])
3、图像色彩空间转换
将图像从一种颜色表示形式转换为另一种颜色表示形式的过程。常见的颜色空间包括RGB、HSV、YUV等。
cv2.cvtColor(src, code):code 为cv2下的指定名称,一般是为A2B,从A形式转移到B形式。
3.1、BGR 转 HSV
code = cv2.COLOR_BGR2HSV
img = cv2.imread("images/car.png")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow("img", img)
cv2.imshow("gav_img", hsv_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
3.2、BGR 转 GRAY
code = cv2.COLOR_BGR2GRAY
img = cv2.imread("images/car.png")
gay_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("img", img)
cv2.imshow("gav_img", gay_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
3.3、HSV、GRAY转BGR
code = cv2.COLOR_GRAY2BGR
code = cv2.COLOR_HSV2BGR
4、图像二值化处理
通过阈值将图像分为两层(前景与背景).
cv2.threshold(src, thresh, maxval, type) : thresh :设定阈值,决定分割界限;maxval:像素值超过阈值时,赋予的最大值(一般设置255);
type:阈值复制类型:
cv2.THRESH_BINARY
: 超过阈值的像素设为最大值,其余设为0
cv2.THRESH_BINARY_INV
: 超过阈值的像素设为0,其余设为最大值
cv2.THRESH_TRUNC
: 超过阈值的像素设为阈值,其余不变
cv2.THRESH_TOZERO
: 超过阈值的像素不变,其余设为0
cv2.THRESH_TOZERO_INV
: 超过阈值的像素设为0,其余不变
threshold 返回值:
retval: 实际使用的阈值(可能与输入值不同)
dst: 输出的二值图像
img = cv2.imread("images/car.png")
ret, dst = cv2.threshold(img, 196, 255, cv2.THRESH_BINARY)
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
5、图像掩模
常用于从图像中提取特定颜色的区域
cv2.inRange(src, lowerb, upperb):lowerb: 颜色范围的下界(数组或元组),指定了要提取的颜色的最小值;upperb: 颜色范围的上界(数组或元组),指定了要提取的颜色的最大值。
一般使用HSV形式图像,返回一个二值图像,白色部分表示在指定颜色范围内的区域,黑色部分表示不在范围内的区域。
img = cv2.imread("images/car.png")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# 确定蓝色区域
mask = cv2.inRange(hsv_img, np.array([100, 100, 100]), np.array([140, 255, 255]))
cv2.imshow("img", img)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
6、图像检测轮廓
contours, hierarchy = cv2.findContours(image, mode, method):image需要为二值图像;mode 为轮廓检索方式;method 为轮廓逼近方法。
mode:
cv2.RETR_EXTERNAL
: 只检索外部轮廓
cv2.RETR_LIST
: 检索所有轮廓,并将其放入列表中
cv2.RETR_TREE
: 检索所有轮廓,并建立层级关系
method:
cv2.CHAIN_APPROX_SIMPLE
: 压缩轮廓,仅保留端点
cv2.CHAIN_APPROX_NONE
: 保留所有轮廓点
返回值
contours: 一个 Python 列表,其中每个元素是一个轮廓(即一组点),轮廓的点以 NumPy 数组的形式存储。
hierarchy: 轮廓的层级信息,包含轮廓之间的关系。
img = cv2.imread("images/car.png")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_img, np.array([100, 100, 100]), np.array([140, 255, 255]))
contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
x, y, w, h = cv2.boundingRect(c)# 根据轮廓信息在原图片上画矩形
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow("img", img)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
7、图像位与操作
用于对两个图像进行按位与操作,像素均为255,则输出255,否则输出0。
cv2.bitwise_and(src1, src2, mask=None),mask
: 可选参数,用于指定一个掩模。
img = cv2.imread("images/car.png")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_img, np.array([100, 100, 100]), np.array([140, 255, 255]))
bst = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow("img", img)
cv2.imshow("bst", bst)
cv2.waitKey(0)
cv2.destroyAllWindows()
8、文字识别
import paddlehub as hub
ocr = hub.Module(name="chinese_ocr_db_crnn_server")
results = ocr.recognize_text(images=[img])
results 是一个列表与字典多层嵌套的结果。
img = cv2.imread("images/wenzi01.jpeg")
ocr = hub.Module(name="chinese_ocr_db_crnn_server")
results = ocr.recognize_text(images=[img])
print(results[0]['data'][0]['text']) # 遗憾的事情太多(识别一行)