赞
踩
最后两个例子是利用opencv进行轮廓检测和相似度匹配检测,可以达到实时跟踪画面中的物体
""" opencv实例 """ import cv2 # opencv读取的是BGR格式 import matplotlib.pyplot as plt import numpy as np # 读取图片,保存图片 def cv_test01(): img1 = cv2.imread('./images/1.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 print(img1) print(img1.shape) # 图像的形状 img2 = cv2.imread('./images/1.jpg', cv2.IMREAD_GRAYSCALE) # 读取灰度图片 print(img2.shape) cv2.imwrite('./images/1_hui.png', img2) # 保存图片 # 显示图像 cv2.imshow('image1', img1) # 将图片显示在窗口 cv2.imshow('image2', img2) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 读取视频保存视频 def cv_test02(): cap2 = cv2.VideoCapture('./images/1.mp4') # 读取文件 cap = cv2.VideoCapture(0) # 读取摄像头图像 # 定义编解码器并创建VideoWriter对象,用于保存图像 fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('./images/output.avi', fourcc, 20.0, (640, 480)) if not cap.isOpened(): print("Cannot open camera") exit() while True: # 逐帧捕获 ret, frame = cap.read() # 如果正确读取帧,ret为True if not ret: print("Can't receive frame (stream end?). Exiting ...") break # 我们在框架上的操作到这里 out.write(frame) # 保存图像 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 读取为灰度图像 # 显示结果帧数 cv2.imshow('frame', gray) if cv2.waitKey(100) == ord('q'): # 里面的数字表示等待多长时间 break # 完成所有操作后,释放捕获器 cap.release() cv2.destroyAllWindows() # 图像分割 def cv_test03(): img1 = cv2.imread('./images/1.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 print(img1.shape) # 图片裁剪 img2 = img1[20:img1.shape[0]-20, 20:img1.shape[1]-20] print(img2.shape) # 显示图像 cv2.imshow('image1', img1) # 将图片显示在窗口 cv2.imshow('image2', img2) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 图像通道读取 def cv_test04(): img1 = cv2.imread('./images/1.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 b, g, r = cv2.split(img1) # 分别读出每个通道的数据 print(b.shape) print(g.shape) print(r.shape) img2 = cv2.merge((b, g, r)) print(img2.shape) img3 = img2.copy() img3[:, :, 0] = 0 # 将蓝色通道变成0 img3[:, :, 1] = 0 # 将绿色通道变成0 print(img3) cv2.imshow('image3', img3) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 为图像设置边框(填充) def cv_test05(): img1 = cv2.imread('./images/1.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 # 定义上下填充宽度 top_size, bottom_size, left_size, right_size = [50, 50, 50, 50] img2 = cv2.copyMakeBorder(img1, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE) img3 = cv2.copyMakeBorder(img1, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_CONSTANT, value=0) img4 = cv2.copyMakeBorder(img1, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT) img5 = cv2.copyMakeBorder(img1, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101) img6 = cv2.copyMakeBorder(img1, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_WRAP) plt.subplot(231), plt.imshow(img1, 'gray'), plt.title('1') plt.subplot(232), plt.imshow(img2, 'gray'), plt.title('2') plt.subplot(233), plt.imshow(img3, 'gray'), plt.title('3') plt.subplot(234), plt.imshow(img4, 'gray'), plt.title('4') plt.subplot(235), plt.imshow(img5, 'gray'), plt.title('5') plt.subplot(236), plt.imshow(img6, 'gray'), plt.title('6') plt.show() # 图像的基本计算 def cv_test06(): img1 = cv2.imread('./images/1.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 print(img1[0:5, 0:5, 0]) img2 = img1 + 10 # 加常数 print(img2[0:5, 0:5, 0]) img3 = img2 + img1 # 两个相同大小的图片相加,大于255取超出的部分 print(img3[0:5, 0:5, 0]) img4 = cv2.add(img1, img2) # 两个相同大小的图片相加,大于256取255 print(img4[0:5, 0:5, 0]) # 图像融合 def cv_test07(): img1 = cv2.imread('./images/1.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 img2 = cv2.imread('./images/2.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 print(img1.shape) print(img2.shape) # 图像变化 img3 = cv2.resize(img2, (192, 108)) # 指定具体数值变化 print(img3.shape) img4 = cv2.resize(img2, (0, 0), fx=1, fy=3) # 指定比例变化 print(img4.shape) # 图像融合 img5 = cv2.addWeighted(img1, 0.4, img3, 0.6, 0) cv2.imshow('image4', img5) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 腐蚀操作,用于去除毛刺,但是会使得线条变窄,可以再使用膨胀操作,使主要的图像变大。 # 不做演示需要的时候再去查看 # 开运算:先进行腐蚀,再进行膨胀 两个步骤合在一起 # 闭运算:先进行膨胀,再进行腐蚀 两个步骤合在一起 # 梯度运算 def cv_test08(): img1 = cv2.imread('./images/yuan.png', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 kernel = np.ones((3, 3), np.uint8) # 全1矩阵 dilate = cv2.dilate(img1, kernel, iterations=5) erosion = cv2.erode(img1, kernel, iterations=5) print(dilate.shape) print(erosion.shape) res = np.hstack((dilate, erosion)) print(res.shape) # 梯度运算函数,用于获取物体边界 gradient = cv2.morphologyEx(img1, cv2.MORPH_GRADIENT, kernel) cv2.imshow('image5', gradient) # 将图片显示在窗口 cv2.imshow('image4', res) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 礼帽和黑帽 def cv_test09(): img1 = cv2.imread('./images/yuan2.png', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 kernel = np.ones((5, 5), np.uint8) # 全1矩阵 gradient = cv2.morphologyEx(img1, cv2.MORPH_TOPHAT, kernel) blackhat = cv2.morphologyEx(img1, cv2.MORPH_BLACKHAT, kernel) cv2.imshow('gradient', gradient) # 将图片显示在窗口 cv2.imshow('blackhat', blackhat) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # Sobel算子,用于寻找梯度,找边界,复杂图像也可以(重要) # Gx = [[-1, 0, 1], [-3, 0, 3], [-1, 0, 1]] def cv_test10(): img1 = cv2.imread('./images/yuan.png', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 sobel = cv2.Sobel(img1, cv2.CV_64F, 1, 0, ksize=3) # ksize=5卷积核大小,1,0只算水平方向,0,1只算竖直方向 sobelx = cv2.convertScaleAbs(sobel) # 取绝对值,不然一边会消失 sobel = cv2.Sobel(img1, cv2.CV_64F, 0, 1, ksize=3) # ksize=5卷积核大小,1,0只算水平方向,0,1只算竖直方向 sobely = cv2.convertScaleAbs(sobel) # 取绝对值,不然一边会消失 sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # 将竖直方向和水平方向进行叠加,直接用1,1效果不好 cv2.imshow('blackhat', sobelxy) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # Scharr算子 更敏感 # Gx = [-3, 0, 3], [-10, 0, 10], [-3, 0, 3]] # laplacian算子, 更不敏感 # G = [[0, 1, 0], [1, -4, 1], [0, 1, 0]] # 图像的平滑处理(卷积)(已经不能使用) def cv_test11(): img1 = cv2.imread('./images/2.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 # 均值滤波 blur = cv2.blur(img1, (3, 3)) cv2.imshow('blackhat', blur) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 高斯与中值滤波 (已经不能使用) def cv_test12(): img1 = cv2.imread('./images/2.jpg', cv2.IMREAD_COLOR) # 读取彩色图片,默认就是 #aussian = cv2.GaussianBlur(img1, (5, 5), 0) #高斯滤波 报错 medim = cv2.medianBlur(img1, 5) cv2.imshow('blackhat', medim) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 阈值操作(重要) def cv_test13(): img1 = cv2.imread('./images/2.jpg', cv2.IMREAD_GRAYSCALE) # 读取彩色图片,默认就是 ret, thresh1 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY) # 彩色图像会对三个通道分别处理再叠加,灰度图像 ret, thresh2 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY_INV) # 对上面的图像进行反转 ret, thresh3 = cv2.threshold(img1, 127, 255, cv2.THRESH_TRUNC) # 最大值只能到127,小于不变 ret, thresh4 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO) # 大于127的不变,小于127的全为0 ret, thresh5 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO_INV) # 跟上面哪一个相反 titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV'] images = [img1, 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() # Canny边缘检测(重要) # 1.滤波,高斯滤波器 # 2.计算每个像素点的梯度强度和方向 # 3.应用非极大值抑制,,以消除除边沿检测带来的杂散响应。 # 4.应用双阀值检测来确定真实和潜在的边缘 # 5.通过抑制孤立的弱边缘最终完成边缘检测 def cv_test14(): img1 = cv2.imread('./images/canny.jpg', cv2.IMREAD_GRAYSCALE) # 读取彩色图片,默认就是 #b, g, r = cv2.split(img1) # 分别读出每个通道的数据 #print(b) edges = cv2.Canny(img1, 50, 200) plt.subplot(121), plt.imshow(img1, cmap='gray') plt.title('Original Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(edges, cmap='gray') plt.title('Edge Image'), plt.xticks([]), plt.yticks([]) plt.show() # 轮廓检测 def cv_test15(): img1 = cv2.imread('./images/canny.jpg') gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) # 读取为灰度图像 # 二值化处理 ret, thresh1 = cv2.threshold(gray, 175, 255, cv2.THRESH_BINARY) # 提取轮廓 contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 绘制轮廓 img2 = img1.copy() res = cv2.drawContours(img2, contours, 27, (0, 0, 255), 5) # 展示图像 cv2.imshow('blackhat', res) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 轮扣近似,找出最大轮廓进行显示 def cv_test16(): img1 = cv2.imread('./images/canny.jpg') gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) # 读取为灰度图像 # 二值化处理 ret, thresh1 = cv2.threshold(gray, 175, 255, cv2.THRESH_BINARY) # 提取轮廓 contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # i = 0 # for cnt in contours: # epsilon = 0.001*cv2.arcLength(cnt, True) # approx = cv2.approxPolyDP(cnt, epsilon, True) # # img2 = img1.copy() # res = cv2.drawContours(img2, [approx], -1, (0, 0, 255), 4) # # cv2.imshow('blackhat', res) # 将图片显示在窗口 # cv2.waitKey(0) # 按任意建退出 # cv2.destroyAllWindows() # print(i) # i = i + 1 # 循环计算每一个轮廓的面积,选出最大的进行显示 area = [0] * len(contours) i = 0 for cnt in contours: area[i] = cv2.contourArea(cnt) i = i + 1 a = area.index(max(area)) # 找出列表中最大值的位置 # 近似处理(前面乘的数越大,轮廓近似越多) epsilon = 0.004*cv2.arcLength(contours[a], True) approx = cv2.approxPolyDP(contours[a], epsilon, True) # 绘制轮廓 img2 = img1.copy() res = cv2.drawContours(img2, [approx], -1, (0, 0, 255), 2) # 绘制矩形外轮廓 x, y, w, h = cv2.boundingRect(contours[27]) ju_xing = cv2.rectangle(res, (x, y), (x+w, y+h), (0, 255, 0), 2) # 展示图像 cv2.imshow('blackhat', ju_xing) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 相似度匹配(和上面轮廓查找的效果类似),也可以进行多模板匹配 def cv_test17(): img1 = cv2.imread('./images/canny.jpg') img2 = cv2.imread('./images/canny_mu.jpg') # 获取图像的宽和高 h, w = img2.shape[:2] gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) # 读取为灰度图像 gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # 读取为灰度图像 # 相似匹配 # 列表中所有的6种比较方法 methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR', 'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED'] res = cv2.matchTemplate(gray1, gray2, cv2.TM_SQDIFF_NORMED) print(res.shape) # 获取最匹配的位置信息 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 绘制矩形 img3 = img1.copy() ju_xing = cv2.rectangle(img3, min_loc, (min_loc[0]+w, min_loc[1]+h), (0, 255, 0), 2) # 展示图像 cv2.imshow('blackhat', ju_xing) # 将图片显示在窗口 cv2.waitKey(0) # 按任意建退出 cv2.destroyAllWindows() # 按间距中的绿色按钮以运行脚本。 if __name__ == '__main__': cv_test17()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。