今天初学OpenCV,目前还没学到图像识别的地方,只是停留在对图片的处理上。
下面就让我来总结一下,学了一个下午的收获有哪些吧。
图像.shape:
这是一个列表,返回至多3个数,(h,w,颜色通道数)
类型转换:
im = cv2.cvtColor(图片,cv2.COLOR_类型2类型(类型名大写,RGB/BGR/HSV))
使图片按变换矩阵变:
im = warpAffine(图像,变换矩阵,(w,h)(原图形的参数))
旋转系数矩阵:
im = cv2.getRotationMatrix2D(旋转中心((x,y)坐标),角度(以逆时针为为正),缩放倍数)
镜像:
im = cv2.flip(图像, 0(水平镜像)/1(垂直镜像))
缩放:
im = cv2.resize(图像,目标图像大小(w,h),模式 = (…))
‘模式’可选:cv2.INTER_NEAREST(最临近插值),INTER_LINEAR(双线性插值)
中值滤波:
im_medianblur = cv2.medianBlur(图像,滤波的参考范围(如 5))
均值滤波:
im_meanblur = cv2.blur(图像,滤波的参考范围(如 (3,3)))
高斯滤波:
im_gaussianblur = cv2.GaussianBlur(图像,滤波的参考范围(如 (5,5)),0)
滤波器:
im = cv2.filter2D(图像,-1,算子矩阵(一个矩阵,为np.array类型))
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 读取
im = cv2.imread(r"girl.jpg", 0) # 表示以黑白读入
im = cv2.imread(r"girl.jpg", 1) # 表示以彩色读入(默认)
# 绘制
cv2.imshow("test",im)
# 保存
cv2.imwrite('baocun.jpg',im)
#大小
print(im.shape) # 输出 (h,w,颜色通道数)高,宽,颜色通道数
cv2.waitKey() # 表示等待
cv2.destroyAllWindows()
图片的配色转换:bgr(标准), gray(灰度), rgb(红蓝互换), hsv(色调,饱和度,明度)
函数名很好记,cv2.cvtColor(图片,cv2.COLOR_类型2类型),2就是to嘛
im = cv2.imread(r"girl.jpg")
cv2.imshow("bgr", im)
img_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", img_gray)
img_rgb = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
cv2.imshow("rgb", img_rgb)
img_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSL)
cv2.imshow("hsv", img_hsv)
因为缩放了,所以中间就会产生一些空白格子,这个时候需要一些算法将其进行填充。
这里给出了两种方法:
最临近插值 INTER_NEAREST
双线性插值 INTER_LINEAR
cv2.resize(图像,目标图像大小(w,h),模式 = (…))
模式可选:cv2.INTER_NEAREST(最临近插值),INTER_LINEAR(双线性插值)
im = cv2.imread(r"girl.jpg")
cv2.imshow("ori", im)
(h, w) = im.shape[:2]
dst_size = (200, 300)
method = cv2.INTER_NEAREST # 最邻近插值
resized = cv2.resize(im, dst_size, interpolation = method)
cv2.imshow('resized1', resized)
dst_size = (800, 600)
method = cv2.INTER_LINEAR # 双线性插值
resized = cv2.resize(im, dst_size, interpolation = method)
cv2.imshow('resized2', resized)
cv2.waitKey()
cv2.destroyAllWindows()
难点在于自己设计转换矩阵,设计方法见代码
将变换矩阵变成现实图像的是函数warpAffine。
im = warpAffine(图像,变换矩阵,(w,h)(原图形的参数))
def translate(img, x, y):
(h, w) = img.shape[:2]
M = np.float32([[1, 0, x], [0, 1, y]])
shifted = cv2.warpAffine(img, M, (w,h))
return shifted
im = cv2.imread(r"girl.jpg",1)
cv2.imshow("bgr", im)
shifted = translate(im, 0, 50)
cv2.imshow("shift1", shifted)
shifted = translate(im, -100, 0)
cv2.imshow("shift2", shifte d)
shifted = translate(im, 50, 100)
cv2.imshow("shift3", shifted)
cv2.waitKey()
cv2.destroyAllWindows()
旋转跟平移类似,不过这次的变化矩阵要用一个getRotationMatrix2D函数来生成。
getRotationMatrix2D(旋转中心((x,y)坐标),角度(以逆时针为为正),缩放倍数)
def rotate(img, angle, center=None, scale=1.0):
(h, w) = img.shape[:2]
if center is None:
center = (w/2, h/2) # 不写默认以中心为轴
M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(img, M, (w,h))
return rotated
im = cv2.imread(r"girl.jpg")
cv2.imshow("bgr", im)
rotated = rotate(im, 45)
cv2.imshow('rotate1', rotated)
rotated = rotate(im, -90)
cv2.imshow('rotate2', rotated)
cv2.waitKey()
cv2.destroyAllWindow()
使用函数flip即可完成
cv2.flip(图像, 0/1)
0表示水平镜像
1表示垂直镜像
im = cv2.imread(r"girl.jpg")
cv2.imshow("org", im)
# 水平镜像
im_flip0 = cv2.flip(im, 0)
cv2.imshow('flip vet', im_flip0)
# 垂直镜像
im_flip1 = cv2.flip(im, 1)
cv2.imshow('flip hori', im_flip1)
cv2.waitKey()
cv2.destroyAllWindow()
输入一张黑白图像,使其灰度值按照某种方式进行改变。
灰度拉伸:灰度值变大,图像灰度对比更明显
灰度压缩:灰度值变小,图像灰度对比变模糊
灰度反转:类似于取负
明显看到有 k x + b kx+b kx+b的函数变换
关键函数是LUT,look up table,i.e.查表,可以将一团数字转换成一张图像?
cv2.LUT(图像,)???
def linear_trans(img, k, b=0):
trans_list = [(np.float32(x)*k+b) for x in range(256)]
trans_table = np.array(trans_list)
trans_table[trans_table>255] = 255
trans_table[trans_table<0] = 0
trans_table = np.round(trans_table).astype(np.uint8)
return cv2.LUT(img, trans_table)
im = cv2.imread(r"girl.jpg",0)
cv2.imshow("ori", im)
im_inversion = linear_trans(im, -1, 255)
cv2.imshow('inversion', im_inversion) # 灰度反转
im_stretch = linear_trans(im, 1.2)
cv2.imshow('graystretch', im_stretch) # 灰度拉伸:使得图片灰度对比更明显
im_compress = linear_trans(im, 0.8)
cv2.imshow('graycompress', im_compress) # 灰度压缩:使得图片灰度对比变模糊
cv2.waitKey()
cv2.destroyAllWindows()
换了一种灰度值计算方法罢了
def gamma_trans(img, gamma):
# 先归一化到 1,做伽马计算,再还原到[0,255]
gamma_list = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)]
gamma_table = np.round(np.array(gamma_list)).astype(np.uint8)
# 使用 OpenCV 的 look up table 函数修改图像的灰度值
return cv2.LUT(img, gamma_table)
im = cv2.imread(r"girl.jpg")
cv2.imshow("ori", im)
im_gama05 = gamma_trans(im, 0.5)
cv2.imshow('gamma0.5', im_gama05)
im_gama2 = gamma_trans(im, 2)
cv2.imshow('gamma2', im_gama2)
cv2.waitKey()
cv2.destroyAllWindows()
im = cv2.imread(r"girl.jpg", 0)
cv2.imshow("ori", im)
plt.hist(im.ravel(), 256, [0,256])
plt.show()
cv2.waitKey()
cv2.destroyAllWindows()
根据直方图的分布,使其变得均衡
im = cv2.equalizeHist(图像)
im = cv2.imread(r"girl.jpg", 0)
cv2.imshow('org', im)
im_equ1 = cv2.equalizeHist(im) # 直方图均衡化
cv2.imshow('equal', im_equ1)
plt.subplot(2,1,1)
plt.hist(im.ravel(), 256, [0,256], label='org')
plt.legend()
plt.subplot(2,1,2)
plt.hist(im_equ1.ravel(), 256, [0,256], label='equalize')
plt.legend()
plt.show()
可直接调用函数,亦可手写算子
中值滤波:
im_medianblur = cv2.medianBlur(图像,滤波的参考范围(如 5))
均值滤波:
im_meanblur = cv2.blur(图像,滤波的参考范围(如 (3,3)))
高斯滤波:
im_gaussianblur = cv2.GaussianBlur(图像,滤波的参考范围(如 (5,5)),0)
im = cv2.imread(r"girl.jpg")
cv2.imshow("ori", im)
im_medianblur = cv2.medianBlur(im, 5) # 中值滤波
cv2.imshow('medianblur', im_medianblur)
im_meanblur = cv2.blur(im, (3,3)) # 均值滤波
cv2.imshow('meanblur', im_meanblur)
im_gaussianblur = cv2.GaussianBlur(im, (5,5), 0) # 高斯滤波
cv2.imshow('gaussianblur', im_gaussianblur)
cv2.waitKey()
cv2.destroyAllWindows()
手写算子代码
(无中值滤波)
手写算子后,利用算子进行计算的函数cv2.filter2D,( 翻译 ‘filter’ 就是滤波器的意思
cv2.filter2D(图像,-1,算子矩阵(一个矩阵,为np.array类型))
# 手写mean算子
im = cv2.imread(r"girl.jpg",1)
mean_blur = np.ones([3,3], np.float32)/9
im_meanblur2 = cv2.filter2D(im, -1, mean_blur)
cv2.imshow('meanblur2', im_meanblur2)
cv2.waitKey()
cv2.destroyAllWindows()
# 手写gaussian算子
gaussian_blur = np.array([
[1,4,7,4,1],
[4,16,26,16,4],
[7,26,41,26,7],
[4,16,26,16,4],
[1,4,7,4,1]], np.float32)/273
im_gaussianblur2 = cv2.filter2D(im, -1, gaussian_blur)
cv2.imshow('gaussian2', im_gaussianblur2)
cv2.waitKey()
cv2.destroyAllWindows()
锐化会让图片变得更加棱角分明,这种算法下,每个点的颜色会受气附近点的影响而加强,产生类似边缘效应。
im = cv2.imread(r"girl.jpg")
cv2.imshow("ori", im)
sharpen_1 = np.array([
[-1,-1,-1],
[-1,9,-1],
[-1,-1,-1]
])
im_sharpen1 = cv2.filter2D(im, -1, sharpen_1)
cv2.imshow('sharpen1', im_sharpen1)
sharpen_2 = np.array([
[0,-1,0],
[-1,8,-1],
[0,-1,0]
])/4.0
im_sharpen2 = cv2.filter2D(im, -1, sharpen_2)
cv2.imshow('sharpen2', im_sharpen2)
cv2.waitKey()
cv2.destroyAllWindows()