计算机视觉图像处理Opencv基础知识 (附详解代码)上
-此部分内容为在学习唐宇迪老师课程中,自己微调后部分知识以及代码,想更多了解移步唐老师课程。*
计算机视觉图像处理Opencv基础知识 (附详解代码)下
基础知识
cv2.imread_color:彩色图像
cv2.imread_grayscale:灰度图像
import cv2 #读取图片格式为BGR
import matplotlib.pyplot as plt #导入plt库,显示图片
import numpy as np
img = cv2.imread('giraffe.jpg') #读取图像,显示的是矩阵形式(h,w,c)
def cv_show(name,img): #定义一个显示图像函数,以任意键结束
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.merge((b,g,r)) #合并RGB三色通道矩阵
img.shape
#只保留R
cur_img = img.copy() #浅复制一个图像
cur_img[:,:,0] = 0 #[B G R]对应索引[0,1,2]
cur_img[:,:,1] = 0
cv_show('R',cur_img)
#只保留G
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
cv_show('G',cur_img)
#只保留B
cur_img = img.copy()
cur_img[:,:,1] = 0
cur_img[:,:,2] = 0
cv_show('G',cur_img)
边界填充
top_size, bottom_size, left_size,right_size = (50,50,50,50)
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType = cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_CONSTANT,value = 0)
plt.subplot(231),plt.imshow(img, 'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate, 'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect, 'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101, 'gray'),plt.title('REFLICT_101')
plt.subplot(235),plt.imshow(wrap, 'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant, 'gray'),plt.title('CONSTANT')
plt.show()
图像融合
res = cv2.addWeighted(img_eagle, 0.6, img_giraffe,0.4, 0) #各自添加权重,0代表偏置值
图像阈值
res, dst = cv2.threshold(src, thresh, maxval, type)
src:输入图,只能输入单通道图像,通常是指灰度图
dst:输出图
thresh:阈值
maxval:当像素值超过了阈值(或小于阈值,根据type来决定),所赋予的值
type:二值化操作类型,包含以下五种类型:
cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
cv2.THRESH_BINARY_INV THRESH_BINARY 上述反转
cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
cv2.THRESH_TOZERO_INV THRESH_TOZERO 上述反转
img_gray = cv2.imread('giraffe.png')
res, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
res, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
res, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
res, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
res, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INY', 'TRUNC', 'TOZERO', 'TOZERP_INY']
images = [img_gray, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
图像平滑处理
img = cv2.imread('lenaNoise.jpg')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#均值滤波,等于是一个简单的平均卷积操作
blur = cv2.blur(img, (3,3)) #3*3是一个卷积核
cv2.imshow('blur',blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
#方框滤波, 基本步骤原理与均值滤波一样,但是增加了归一化处理
box = cv2.boxFilter(img, -1, (3,3),normalize = True)
cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()
#高斯滤波, 高斯模糊的卷积核里的数值是满足高斯分布的,相当于更重视中间内容
aussian = cv2.GaussianBlur(img, (5,5), 1)
cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
#中值滤波,用中值代替
median = cv2.medianBlur(img, 5)
cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()
腐蚀操作
img = cv2.imread('fushi.jpg')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
kernel = np.ones((5,5), np.uint8)
erosion = cv2.erode(img, kernel, iterations = 1)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
形态学膨胀操作
kernel = np.ones((5,5),np.uint8)
f_erosion = cv2.erode(img, kernel, iterations = 1)
cv2.imshow('erosion',f_erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
kernel = np.ones((5,5),np.uint8)
dilate = cv2.dilate(f_erosion, kernel, iterations = 1)
cv2.imshow('dilate',dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()
开运算与闭运算
#开:先腐蚀后膨胀
img = cv2.imread('fushi.jpg')
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()
#闭:先膨胀后腐蚀
img = cv2.imread('fushi.jpg')
kernel = np.ones((5,5),np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()
梯度运算
# 梯度 = 膨胀 - 腐蚀
pie = cv2.imread('fushi2.jpg')
kernel = np.ones((3,5), np.uint8)
dilation = cv2.dilate(pie, kernel, iterations = 3)
erosion = cv2.erode(pie, kernel, iterations =3)
res = np.hstack((dilation, erosion))
cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('gradient',gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()
礼帽与黑帽
礼帽:原始输入 - 开运算结果
黑帽:闭运算 - 原始输入
#礼帽
img = cv2.imread('fushi.jpg')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat',tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()
#黑帽
img = cv2.imread('fushi.jpg')
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat', blackhat)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像梯度:sobel算子
dst = cv2.Sobel(src, depth, dx, dy, ksize)
计算时候从右到左,从下到上
depth:深度
dx,dy: 分别表示水平和竖直方向
ksize: Sobel算子的大小
img = cv2.imread('fushi2.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def cv_show(img, name):
cv2.imshow(name, img)
cv2.waitKey()
cv2.destroyAllWindows()
sobelx = cv2.Sobel(img, cv2.CV_64F,1,0,ksize = 3)
cv_show(sobelx, 'sobelx')
#白到黑是正数,黑到白是负数,而负数会被截断成0,因此取绝对值
sobelx = cv2.Sobel(img, cv2.CV_64F,1,0,ksize = 3)
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx, 'sobelx')
res = np.hstack((sobelx1,sobelx2))
cv_show(res,'res')
sobely = cv2.Sobel(img, cv2.CV_64F,0,1,ksize = 3)
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely, 'sobely')
#分别计算x和y,然后再求和
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
img = cv2.imread('eagle.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')
img = cv2.imread('eagle.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img, cv2.CV_64F,1,0,ksize = 3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img, cv2.CV_64F,0,1,ksize = 3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
img = cv2.imread('eagle.jpg',cv2.IMREAD_GRAYSCALE)
sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy,'sobelxy')
图像梯度中的Scharr算子以及Laplacian算子
img = cv2.imread('eagle.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize = 3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize = 3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((img,sobelxy,scharrxy,laplacian))
cv_show(res,'res')