3 OpenCV图像处理
OpenCV图像处理
一 几何变换
1 图像缩放
import cv2 as cv # 1. 读取图片 img1 = cv.imread("./image/dog.jpeg") # 2.图像缩放 # 2.1 绝对尺寸 rows,cols = img1.shape[:2] res = cv.resize(img1,(2*cols,2*rows),interpolation=cv.INTER_CUBIC) # 2.2 相对尺寸 res1 = cv.resize(img1,None,fx=0.5,fy=0.5) # 3 图像显示 # 3.1 使用opencv显示图像(不推荐) cv.imshow("orignal",img1) cv.imshow("enlarge",res) cv.imshow("shrink)",res1) cv.waitKey(0) # 3.2 使用matplotlib显示图像 fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(10,8),dpi=100) axes[0].imshow(res[:,:,::-1]) axes[0].set_title("绝对尺度(放大)") axes[1].imshow(img1[:,:,::-1]) axes[1].set_title("原图") axes[2].imshow(res1[:,:,::-1]) axes[2].set_title("相对尺度(缩小)") plt.show()

2图像平移
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1. 读取图像 img1 = cv.imread("./image/image2.jpg") # 2. 图像平移 rows,cols = img1.shape[:2] M = M = np.float32([[1,0,100],[0,1,50]])# 平移矩阵 dst = cv.warpAffine(img1,M,(cols,rows)) # 3. 图像显示 fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100) axes[0].imshow(img1[:,:,::-1]) axes[0].set_title("原图") axes[1].imshow(dst[:,:,::-1]) axes[1].set_title("平移后结果") plt.show()

3 图像旋转
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 读取图像 img = cv.imread("./image/image2.jpg") # 2 图像旋转 rows,cols = img.shape[:2] # 2.1 生成旋转矩阵 M = cv.getRotationMatrix2D((cols/2,rows/2),90,1) # 2.2 进行旋转变换 dst = cv.warpAffine(img,M,(cols,rows)) # 3 图像展示 fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100) axes[0].imshow(img1[:,:,::-1]) axes[0].set_title("原图") axes[1].imshow(dst[:,:,::-1]) axes[1].set_title("旋转后结果") plt.show()

4 仿射变换
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 图像读取 img = cv.imread("./image/image2.jpg") # 2 仿射变换 rows,cols = img.shape[:2] # 2.1 创建变换矩阵 pts1 = np.float32([[50,50],[200,50],[50,200]]) pts2 = np.float32([[100,100],[200,50],[100,250]]) M = cv.getAffineTransform(pts1,pts2) # 2.2 完成仿射变换 dst = cv.warpAffine(img,M,(cols,rows)) # 3 图像显示 fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100) axes[0].imshow(img[:,:,::-1]) axes[0].set_title("原图") axes[1].imshow(dst[:,:,::-1]) axes[1].set_title("仿射后结果") plt.show()

5 透射变换
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 读取图像 img = cv.imread("./image/image2.jpg") # 2 透射变换 rows,cols = img.shape[:2] # 2.1 创建变换矩阵 pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]]) pts2 = np.float32([[100,145],[300,100],[80,290],[310,300]]) T = cv.getPerspectiveTransform(pts1,pts2) # 2.2 进行变换 dst = cv.warpPerspective(img,T,(cols,rows)) # 3 图像显示 fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100) axes[0].imshow(img[:,:,::-1]) axes[0].set_title("原图") axes[1].imshow(dst[:,:,::-1]) axes[1].set_title("透射后结果") plt.show()

6 图像金字塔
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 图像读取 img = cv.imread("./image/image2.jpg") # 2 进行图像采样 up_img = cv.pyrUp(img) # 上采样操作 img_1 = cv.pyrDown(img) # 下采样操作 # 3 图像显示 cv.imshow('enlarge', up_img) cv.imshow('original', img) cv.imshow('shrink', img_1) cv.waitKey(0) cv.destroyAllWindows()

二 形态学操作
形态学操作:腐蚀,膨胀,开闭运算,礼帽和黑帽等,及其不同操作之间的关系
1 我们使用一个5*5的卷积核实现腐蚀和膨胀的运算:
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 读取图像 img = cv.imread("./image/image3.png") # 2 创建核结构 kernel = np.ones((5, 5), np.uint8) # 3 图像腐蚀和膨胀 erosion = cv.erode(img, kernel) # 腐蚀 dilate = cv.dilate(img,kernel) # 膨胀 # 4 图像展示 fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(10,8),dpi=100) axes[0].imshow(img) axes[0].set_title("原图") axes[1].imshow(erosion) axes[1].set_title("腐蚀后结果") axes[2].imshow(dilate) axes[2].set_title("膨胀后结果") plt.show()

2 开闭运算
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 读取图像 img1 = cv.imread("./image/image5.png") img2 = cv.imread("./image/image6.png") # 2 创建核结构 kernel = np.ones((10, 10), np.uint8) # 3 图像的开闭运算 cvOpen = cv.morphologyEx(img1,cv.MORPH_OPEN,kernel) # 开运算 cvClose = cv.morphologyEx(img2,cv.MORPH_CLOSE,kernel)# 闭运算 # 4 图像展示 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8)) axes[0,0].imshow(img1) axes[0,0].set_title("原图") axes[0,1].imshow(cvOpen) axes[0,1].set_title("开运算结果") axes[1,0].imshow(img2) axes[1,0].set_title("原图") axes[1,1].imshow(cvClose) axes[1,1].set_title("闭运算结果") plt.show()

3 礼帽与黑盒
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 读取图像 img1 = cv.imread("./image/image5.png") img2 = cv.imread("./image/image6.png") # 2 创建核结构 kernel = np.ones((10, 10), np.uint8) # 3 图像的礼帽和黑帽运算 cvOpen = cv.morphologyEx(img1,cv.MORPH_TOPHAT,kernel) # 礼帽运算 cvClose = cv.morphologyEx(img2,cv.MORPH_BLACKHAT,kernel)# 黑帽运算 # 4 图像显示 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8)) axes[0,0].imshow(img1) axes[0,0].set_title("原图") axes[0,1].imshow(cvOpen) axes[0,1].set_title("礼帽运算结果") axes[1,0].imshow(img2) axes[1,0].set_title("原图") axes[1,1].imshow(cvClose) axes[1,1].set_title("黑帽运算结果") plt.show()

三 图像平滑
1 均值滤波
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 图像读取 img = cv.imread('./image/dogsp.jpeg') # 2 均值滤波 blur = cv.blur(img,(5,5)) # 3 图像显示 plt.figure(figsize=(10,8),dpi=100) plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原图') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('均值滤波后结果') plt.xticks([]), plt.yticks([]) plt.show()

2 高斯滤波
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 图像读取 img = cv.imread('./image/dogGasuss.jpeg') # 2 高斯滤波 blur = cv.GaussianBlur(img,(3,3),1) # 3 图像显示 plt.figure(figsize=(10,8),dpi=100) plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原图') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('高斯滤波后结果') plt.xticks([]), plt.yticks([]) plt.show()

3 中值滤波
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 图像读取 img = cv.imread('./image/dogsp.jpeg') # 2 中值滤波 blur = cv.medianBlur(img,5) # 3 图像展示 plt.figure(figsize=(10,8),dpi=100) plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原图') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('中值滤波后结果') plt.xticks([]), plt.yticks([]) plt.show()

四 直方图
1 灰度直方图
import numpy as np import cv2 as cv from matplotlib import pyplot as plt # 1 直接以灰度图的方式读入 img = cv.imread('./image/cat.jpeg',0) # 2 统计灰度图 histr = cv.calcHist([img],[0],None,[256],[0,256]) # 3 绘制灰度图 plt.figure(figsize=(10,6),dpi=100) plt.plot(histr) plt.grid() plt.show()

2 掩膜
import numpy as np import cv2 as cv from matplotlib import pyplot as plt # 1. 直接以灰度图的方式读入 img = cv.imread('./image/cat.jpeg',0) # 2. 创建蒙版 mask = np.zeros(img.shape[:2], np.uint8) mask[400:650, 200:500] = 255 # 3.掩模 masked_img = cv.bitwise_and(img,img,mask = mask) # 4. 统计掩膜后图像的灰度图 mask_histr = cv.calcHist([img],[0],mask,[256],[1,256]) # 5. 图像展示 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8)) axes[0,0].imshow(img,cmap=plt.cm.gray) axes[0,0].set_title("原图") axes[0,1].imshow(mask,cmap=plt.cm.gray) axes[0,1].set_title("蒙版数据") axes[1,0].imshow(masked_img,cmap=plt.cm.gray) axes[1,0].set_title("掩膜后数据") axes[1,1].plot(mask_histr) axes[1,1].grid() axes[1,1].set_title("灰度直方图") plt.show()

3 直方图均衡化
import numpy as np import cv2 as cv from matplotlib import pyplot as plt # 1. 直接以灰度图的方式读入 img = cv.imread('./image/cat.jpeg',0) # 2. 均衡化处理 dst = cv.equalizeHist(img) # 3. 结果展示 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8),dpi=100) axes[0].imshow(img,cmap=plt.cm.gray) axes[0].set_title("原图") axes[1].imshow(dst,cmap=plt.cm.gray) axes[1].set_title("均衡化后结果") plt.show()

4 自适应的直方图均衡化
import numpy as np import cv2 as cv # 1. 以灰度图形式读取图像 img = cv.imread('./image/cat.jpeg',0) # 2. 创建一个自适应均衡化的对象,并应用于图像 clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) cl1 = clahe.apply(img) # 3. 图像展示 fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100) axes[0].imshow(img,cmap=plt.cm.gray) axes[0].set_title("原图") axes[1].imshow(cl1,cmap=plt.cm.gray) axes[1].set_title("自适应均衡化后的结果") plt.show()

五 边缘检测
1 sobel边缘检测
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 读取图像 img = cv.imread('./image/horse.jpg',0) # 2 计算Sobel卷积结果 x = cv.Sobel(img, cv.CV_16S, 1, 0) y = cv.Sobel(img, cv.CV_16S, 0, 1) # 3 将数据进行转换 Scale_absX = cv.convertScaleAbs(x) # convert 转换 scale 缩放 Scale_absY = cv.convertScaleAbs(y) # 4 结果合成 result = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0) # 5 图像显示 plt.figure(figsize=(10,8),dpi=100) plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(result,cmap = plt.cm.gray),plt.title('Sobel滤波后结果') plt.xticks([]), plt.yticks([]) plt.show()

将上述代码中计算sobel算子的部分中将ksize设为-1,就是利用Scharr进行边缘检测
x = cv.Sobel(img, cv.CV_16S, 1, 0, ksize = -1)
y = cv.Sobel(img, cv.CV_16S, 0, 1, ksize = -1)

2 Laplacian算子
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 读取图像 img = cv.imread('./image/horse.jpg',0) # 2 laplacian转换 result = cv.Laplacian(img,cv.CV_16S) Scale_abs = cv.convertScaleAbs(result) # 3 图像展示 plt.figure(figsize=(10,8),dpi=100) plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(Scale_abs,cmap = plt.cm.gray),plt.title('Laplacian检测后结果') plt.xticks([]), plt.yticks([]) plt.show()

3 Canny边缘检测
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 图像读取 img = cv.imread('./image/horse.jpg',0) # 2 Canny边缘检测 lowThreshold = 0 max_lowThreshold = 100 canny = cv.Canny(img, lowThreshold, max_lowThreshold) # 3 图像展示 plt.figure(figsize=(10,8),dpi=100) plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(canny,cmap = plt.cm.gray),plt.title('Canny检测后结果') plt.xticks([]), plt.yticks([]) plt.show()

六 模板匹配和霍夫变换
模板匹配
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 图像和模板读取 img = cv.imread('./image/wulin2.jpeg') template = cv.imread('./image/wulin.jpeg') h,w,l = template.shape # 2 模板匹配 # 2.1 模板匹配 res = cv.matchTemplate(img, template, cv.TM_CCORR) # 2.2 返回图像中最匹配的位置,确定左上角的坐标,并将匹配位置绘制在图像上 min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res) # 使用平方差时最小值为最佳匹配位置 # top_left = min_loc top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv.rectangle(img, top_left, bottom_right, (0,255,0), 2) # 3 图像显示 plt.imshow(img[:,:,::-1]) plt.title('匹配结果'), plt.xticks([]), plt.yticks([]) plt.show()
---> 
霍夫线检测
import numpy as np import random import cv2 as cv import matplotlib.pyplot as plt # 1.加载图片,转为二值图 img = cv.imread('./image/rili.jpg') gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) edges = cv.Canny(gray, 50, 150) # 2.霍夫直线变换 lines = cv.HoughLines(edges, 0.8, np.pi / 180, 150) # 3.将检测的线绘制在图像上(注意是极坐标噢) for line in lines: rho, theta = line[0] a = np.cos(theta) b = np.sin(theta) x0 = a * rho y0 = b * rho x1 = int(x0 + 1000 * (-b)) y1 = int(y0 + 1000 * (a)) x2 = int(x0 - 1000 * (-b)) y2 = int(y0 - 1000 * (a)) cv.line(img, (x1, y1), (x2, y2), (0, 255, 0)) # 4. 图像显示 plt.figure(figsize=(10,8),dpi=100) plt.imshow(img[:,:,::-1]),plt.title('霍夫变换线检测') plt.xticks([]), plt.yticks([]) plt.show()
--> 
霍夫圆检测
import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 1 读取图像,并转换为灰度图 planets = cv.imread("./image/star.jpeg") gay_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY) # 2 进行中值模糊,去噪点 img = cv.medianBlur(gay_img, 7) # 3 霍夫圆检测 circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 200, param1=100, param2=30, minRadius=0, maxRadius=100) # 4 将检测结果绘制在图像上 for i in circles[0, :]: # 遍历矩阵每一行的数据 # 绘制圆形 cv.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2) # 绘制圆心 cv.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3) # 5 图像显示 plt.figure(figsize=(10,8),dpi=100) plt.imshow(planets[:,:,::-1]),plt.title('霍夫变换圆检测') plt.xticks([]), plt.yticks([]) plt.show()

作者:华王
博客:https://www.cnblogs.com/huahuawang/
浙公网安备 33010602011771号