赞
踩
分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开
全栈工程师开发手册 (作者:栾鹏)
python教程全解
pip install --upgrade setuptools
pip install numpy Matplotlib
pip install opencv-python
和Python一样,当前的OpenCV也有两个大版本,OpenCV2和OpenCV3。相比OpenCV2,OpenCV3提供了更强的功能和更多方便的特性。不过考虑到和深度学习框架的兼容性,以及上手安装的难度,这部分先以2为主进行介绍。
根据功能和需求的不同,OpenCV中的函数接口大体可以分为如下部分:
core:核心模块,主要包含了OpenCV中最基本的结构(矩阵,点线和形状等),以及相关的基础运算/操作。
imgproc:图像处理模块,包含和图像相关的基础功能(滤波,梯度,改变大小等),以及一些衍生的高级功能(图像分割,直方图,形态分析和边缘/直线提取等)。
highgui:提供了用户界面和文件读取的基本函数,比如图像显示窗口的生成和控制,图像/视频文件的IO等。
如果不考虑视频应用,以上三个就是最核心和常用的模块了。针对视频和一些特别的视觉应用,OpenCV也提供了强劲的支持:
video:用于视频分析的常用功能,比如光流法(Optical Flow)和目标跟踪等。
calib3d:三维重建,立体视觉和相机标定等的相关功能。
features2d:二维特征相关的功能,主要是一些不受专利保护的,商业友好的特征点检测和匹配等功能,比如ORB特征。
object:目标检测模块,包含级联分类和Latent SVM
ml:机器学习算法模块,包含一些视觉中最常用的传统机器学习算法。
flann:最近邻算法库,Fast Library for Approximate Nearest Neighbors,用于在多维空间进行聚类和检索,经常和关键点匹配搭配使用。
gpu:包含了一些gpu加速的接口,底层的加速是CUDA实现。
photo:计算摄像学(Computational Photography)相关的接口,当然这只是个名字,其实只有图像修复和降噪而已。
stitching:图像拼接模块,有了它可以自己生成全景照片。
nonfree:受到专利保护的一些算法,其实就是SIFT和SURF。
contrib:一些实验性质的算法,考虑在未来版本中加入的。
legacy:字面是遗产,意思就是废弃的一些接口,保留是考虑到向下兼容。
ocl:利用OpenCL并行加速的一些接口。
superres:超分辨率模块,其实就是BTV-L1(Biliteral Total Variation – L1 regularization)算法
viz:基础的3D渲染模块,其实底层就是著名的3D工具包VTK(Visualization Toolkit)。
从使用的角度来看,和OpenCV2相比,OpenCV3的主要变化是更多的功能和更细化的模块划分。
github地址:
存取图像
主要包含图像的读取、存储、图片模式的转换、格式的转换。
#导入cv模块 import cv2 as cv # 读取一张400x600分辨率的图像 color_img = cv.imread('img/src_1000x1000.jpg') print(color_img.shape) # 直接读取单通道灰度图 gray_img = cv.imread('img/src_1000x1000.jpg', cv.IMREAD_GRAYSCALE) print(gray_img.shape) # 把单通道图片保存后,再读取,仍然是3通道,相当于把单通道值复制到3个通道保存 cv.imwrite('img/test_grayscale.jpg', gray_img) reload_grayscale = cv.imread('img/test_grayscale.jpg') print(reload_grayscale.shape) # cv2.IMWRITE_JPEG_QUALITY指定jpg质量,范围0到100,默认95,越高画质越好,文件越大 cv.imwrite('img/test_imwrite.jpg', color_img, (cv.IMWRITE_JPEG_QUALITY, 80)) # cv2.IMWRITE_PNG_COMPRESSION指定png质量,范围0到9,默认3,越高文件越小,画质越差 cv.imwrite('img/test_imwrite.png', color_img, (cv.IMWRITE_PNG_COMPRESSION, 5))
缩放,裁剪和补边
主要包括图片大小缩放(比例缩放、按指定值缩放)、局部裁剪、周边补色
#导入cv模块 import cv2 as cv # 读取一张原始图片 img = cv.imread('img/src_1000x1000.jpg') # 缩放成200x200的方形图像 img_200x200 = cv.resize(img, (200, 200)) # 不直接指定缩放后大小,通过fx和fy指定缩放比例,0.5则长宽都为原来一半 # 等效于img_100x100 = cv2.resize(img, (100, 100)),注意指定大小的格式是(宽度,高度) # 插值方法默认是cv2.INTER_LINEAR,这里指定为最近邻插值 img_100x100 = cv.resize(img_200x200, (0, 0), fx=0.5, fy=0.5,interpolation=cv.INTER_NEAREST) # 在上张图片的基础上,上下各贴50像素的黑边,生成300x300的图像 img_200x100 = cv.copyMakeBorder(img_100x100, 50, 50, 0, 0,cv.BORDER_CONSTANT,value=(0, 0, 0)) # 对照片中局部进行剪裁 patch_img = img[220:550, -180:-50] cv.imwrite('img/cropped_img.jpg', patch_img) cv.imwrite('img/resized_200x200.jpg', img_200x200) cv.imwrite('img/resized_100x100.jpg', img_100x100) cv.imwrite('img/bordered_200x100.jpg', img_200x100)
色调,明暗,直方图和Gamma曲线
主要包含色度、饱和度、明暗的条件。
import cv2 as cv img = cv.imread('img/src_1000x1000.jpg') # 通过cv2.cvtColor把图像从BGR转换到HSV img_hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) # H空间中,绿色比黄色的值高一点,所以给每个像素+15,黄色的树叶就会变绿 turn_green_hsv = img_hsv.copy() turn_green_hsv[:, :, 0] = (turn_green_hsv[:, :, 0]+15) % 180 turn_green_img = cv.cvtColor(turn_green_hsv, cv.COLOR_HSV2BGR) cv.imwrite('img/turn_green.jpg', turn_green_img) # 减小饱和度会让图像损失鲜艳,变得更灰 colorless_hsv = img_hsv.copy() colorless_hsv[:, :, 1] = 0.5 * colorless_hsv[:, :, 1] colorless_img = cv.cvtColor(colorless_hsv, cv.COLOR_HSV2BGR) cv.imwrite('img/colorless.jpg', colorless_img) # 减小明度为原来一半 darker_hsv = img_hsv.copy() darker_hsv[:, :, 2] = 0.5 * darker_hsv[:, :, 2] darker_img = cv.cvtColor(darker_hsv, cv.COLOR_HSV2BGR) cv.imwrite('img/darker.jpg', darker_img)
图像的仿射变换
主要包括缩放、旋转、剪切、翻转、平移,以及他们之间的组合
#导入cv模块 import cv2 as cv import numpy as np # =====================图像的仿射变换=============================== # 仿射变换具体到图像中的应用,主要是对图像的缩放,旋转,剪切,翻转和平移的组合。 # 读取一张原始照片 img = cv.imread('img/src_400x600.jpg') # 沿着横纵轴放大1.6倍,然后平移(-150,-240),最后沿原图大小截取,等效于裁剪并放大 M_crop_elephant = np.array([ [1.6, 0, -150], [0, 1.6, -240] ], dtype=np.float32) img_elephant = cv.warpAffine(img, M_crop_elephant, (400, 600)) cv.imwrite('img/lanka_elephant.jpg', img_elephant) # x轴的剪切变换,角度15° theta = 15 * np.pi / 180 M_shear = np.array([ [1, np.tan(theta), 0], [0, 1, 0] ], dtype=np.float32) img_sheared = cv.warpAffine(img, M_shear, (400, 600)) cv.imwrite('img/lanka_safari_sheared.jpg', img_sheared) # 顺时针旋转,角度15° M_rotate = np.array([ [np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0] ], dtype=np.float32) img_rotated = cv.warpAffine(img, M_rotate, (400, 600)) cv.imwrite('img/lanka_safari_rotated.jpg', img_rotated) # 某种变换,具体旋转+缩放+旋转组合可以通过SVD分解理解 M = np.array([ [1, 1.5, -400], [0.5, 2, -100] ], dtype=np.float32) img_transformed = cv.warpAffine(img, M, (400, 600)) cv.imwrite('img/lanka_safari_transformed.jpg', img_transformed)
基本绘图
可以在画面上绘制线段,圆,矩形和多边形等,还可以在图像上指定位置打印文字
#导入cv模块 import cv2 as cv import numpy as np # 可以在画面上绘制线段,圆,矩形和多边形等,还可以在图像上指定位置打印文字 import numpy as np import cv2 # 定义一块宽600,高400的画布,初始化为白色 canvas = np.zeros((400, 600, 3), dtype=np.uint8) + 255 # 画一条纵向的正中央的黑色分界线 cv2.line(canvas, (300, 0), (300, 399), (0, 0, 0), 2) # 画一条右半部份画面以150为界的横向分界线 cv2.line(canvas, (300, 149), (599, 149), (0, 0, 0), 2) # 左半部分的右下角画个红色的圆 cv2.circle(canvas, (200, 300), 75, (0, 0, 255), 5) # 左半部分的左下角画个蓝色的矩形 cv2.rectangle(canvas, (20, 240), (100, 360), (255, 0, 0), thickness=3) # 定义两个三角形,并执行内部绿色填充 triangles = np.array([ [(200, 240), (145, 333), (255, 333)], [(60, 180), (20, 237), (100, 237)]]) cv2.fillPoly(canvas, triangles, (0, 255, 0)) # 画一个黄色五角星 # 第一步通过旋转角度的办法求出五个顶点 phi = 4 * np.pi / 5 rotations = [[[np.cos(i * phi), -np.sin(i * phi)], [i * np.sin(phi), np.cos(i * phi)]] for i in range(1, 5)] pentagram = np.array([[[[0, -1]] + [np.dot(m, (0, -1)) for m in rotations]]], dtype=np.float) # 定义缩放倍数和平移向量把五角星画在左半部分画面的上方 pentagram = np.round(pentagram * 80 + np.array([160, 120])).astype(np.int) # 将5个顶点作为多边形顶点连线,得到五角星 cv2.polylines(canvas, pentagram, True, (0, 255, 255), 9) # 按像素为间隔从左至右在画面右半部份的上方画出HSV空间的色调连续变化 for x in range(302, 600): color_pixel = np.array([[[round(180*float(x-302)/298), 255, 255]]], dtype=np.uint8) line_color = [int(c) for c in cv2.cvtColor(color_pixel, cv2.COLOR_HSV2BGR)[0][0]] cv2.line(canvas, (x, 0), (x, 147), line_color) # 如果定义圆的线宽大于半斤,则等效于画圆点,随机在画面右下角的框内生成坐标 np.random.seed(42) n_pts = 30 pts_x = np.random.randint(310, 590, n_pts) pts_y = np.random.randint(160, 390, n_pts) pts = zip(pts_x, pts_y) # 画出每个点,颜色随机 for pt in pts: pt_color = [int(c) for c in np.random.randint(0, 255, 3)] cv2.circle(canvas, pt, 3, pt_color, 5) # 在左半部分最上方打印文字 cv2.putText(canvas, '打印的文字just english', (5, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) cv2.imshow('窗口名称', canvas) cv2.waitKey()
相机功能
一个是VideoCapture,用于获取相机设备并捕获图像和视频,或是从文件中捕获。还有一个VideoWriter,用于生成视频。
下面的代码会根据电脑摄像头捕捉到的信息,在img文件夹下生成一个save.avi的视频文件。
#导入cv模块 import time import cv2 import os import sys interval = 1 # 捕获图像的间隔,单位:秒 num_frames = 50 # 捕获图像的总帧数 out_fps = 24 # 输出文件的帧率 # VideoCapture(0)表示打开默认的相机 cap = cv2.VideoCapture(0) # 获取捕获的分辨率 size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) # 设置要保存视频的编码,分辨率和帧率 video = cv2.VideoWriter( "img/save.avi", cv2.VideoWriter_fourcc('M', 'P', '4', '2'), # 视频编码格式参考 http://www.fourcc.org/codecs.php out_fps, size ) # 对于一些低画质的摄像头,前面的帧可能不稳定,略过 for i in range(42): cap.read() # 开始捕获,通过read()函数获取捕获的帧 try: for i in range(num_frames): _, frame = cap.read() video.write(frame) # 如果希望把每一帧也存成文件,比如制作GIF,则允许下面的代码运行 # filename = '{:0>6d}.png'.format(i) # cv2.imwrite(filename, frame) print('Frame {} is captured.'.format(i)) time.sleep(interval) except KeyboardInterrupt: # 捕获提前停止。方便后面使已经捕获好的部分视频可以顺利生成 print('Stopped! {}/{} frames captured!'.format(i, num_frames)) # 释放资源并写入视频文件 video.release() cap.release()
视频文件功能
间隔读取视频文件中的每帧的图片。
frame_path="img/frames" # 存放视频截图的文件夹路径 # 第二个输入参数是设定每隔多少帧截取一帧 frame_interval = 1 if not os.path.exists(frame_path): os.mkdir(frame_path) # 初始化一个VideoCapture对象 cap = cv2.VideoCapture() filepath = "img/save.avi" # VideoCapture::open函数可以从文件获取视频 cap.open(filepath) # 获取视频帧数 n_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) print(n_frames) # 同样为了避免视频头几帧质量低下,黑屏或者无关等 for i in range(2): cap.read() for i in range(2,n_frames): # 读取后面的帧数据 ret, frame = cap.read() # 每隔frame_interval帧进行一次截屏操作 if i % frame_interval == 0: imagepath = frame_path+'/video_test'+ str(i)+".jpg" print('导出 {}!'.format(imagepath)) cv2.imwrite(imagepath, frame) # 执行结束释放资源 cap.release()
交互——播放图片
窗口播放图片、循环播放图片
#导入cv模块 import time import cv2 import os import sys from itertools import cycle # =====================OpenCV窗口显示=============================== img = cv2.imread('img/src_1000x1000.jpg') cv2.imshow('窗口标题', img) cv2.waitKey() # =====================OpenCV窗口循环=============================== frame_path="img/frames" # 图片的文件夹路径 # 列出frames文件夹下的所有图片 filenames = os.listdir(frame_path) # 通过itertools.cycle生成一个无限循环的迭代器,每次迭代都输出下一张图像对象 img_iter = cycle([cv2.imread(os.sep.join([frame_path, x])) for x in filenames]) key = 0 while key & 0xFF != 27: cv2.imshow('window title', next(img_iter)) key = cv2.waitKey(500) # cv2.waitKey()参数不为零的时候则可以和循环结合产生动态画面
交互——鼠标事件
主要包括为窗口绑定鼠标事件的处理。
#导入cv模块 import time import cv2 import os import sys from itertools import cycle # 定义鼠标事件回调函数 def on_mouse(event, x, y, flags, param): # 鼠标左键按下,抬起,双击 if event == cv2.EVENT_LBUTTONDOWN: print('左键按下 ({}, {})'.format(x, y)) elif event == cv2.EVENT_LBUTTONUP: print('左键弹起 ({}, {})'.format(x, y)) elif event == cv2.EVENT_LBUTTONDBLCLK: print('左键双击 ({}, {})'.format(x, y)) # 鼠标右键按下,抬起,双击 elif event == cv2.EVENT_RBUTTONDOWN: print('右键按下 ({}, {})'.format(x, y)) elif event == cv2.EVENT_RBUTTONUP: print('右键弹起 ({}, {})'.format(x, y)) elif event == cv2.EVENT_RBUTTONDBLCLK: print('右键双击 ({}, {})'.format(x, y)) # 鼠标中/滚轮键(如果有的话)按下,抬起,双击 elif event == cv2.EVENT_MBUTTONDOWN: print('中间键按下 ({}, {})'.format(x, y)) elif event == cv2.EVENT_MBUTTONUP: print('中间键弹起 ({}, {})'.format(x, y)) elif event == cv2.EVENT_MBUTTONDBLCLK: print('中间键双击 ({}, {})'.format(x, y)) # 鼠标移动 elif event == cv2.EVENT_MOUSEMOVE: print('移动到 ({}, {})'.format(x, y)) # 为指定的窗口绑定自定义的回调函数 cv2.namedWindow('window title') cv2.setMouseCallback('window title', on_mouse) # 第一个参数为要绑定的窗口名称,第二个参数为要绑定的鼠标事件 cv2.waitKey()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。