图像
import cv2 as cv
import sys
img = cv.imread("./1.jpg")
img = cv.imread(cv.samples.findFile("1.jpg"))#官方是这个方法获取图片!然后再读取
print(img)
if img is None:
sys.exit("Could not read the image.")#程序直接退出并输出该语句,里面可以没有如何语句,那么就直接结束程序
else:
print("image is ok!")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) #函数cvCvtColor实现色彩空间转换 这里是bgr转换为gray
cv.imshow("Display window", gray)#第一个参数是窗口的标题,第二个参数是将要显示的cv::Mat对象。
'''因为我们希望窗口显示直到用户按下一个键(否则程序结束得太快),所以我们使用cv::waitKey函数,
该函数的唯一参数是它应该等待用户输入(以毫秒为单位测量)多长时间。零意味着永远等待。返回值是被按下的键
cv2.waitKey(delay)参数:
1、delay≤0:一直等待按键;
2、delay取正整数:等待按键的时间,比如cv2.waitKey(25),就是等待25(milliseconds);(视频中一帧数据显示(停留)的时间)
cv2.waitKey(delay)返回值:
1、等待期间有按键:返回按键的ASCII码(比如:Esc的ASCII码为27);
2、等待期间没有按键:返回 -1'''
k = cv.waitKey(0)
if k == ord("s"):
'''最后,如果按下的键是' s '键,则将图像写入\写入文件。为此调用imwrite函数,该函数以文件路径和Mat对象为参数。'''
cv.imwrite("1.png", img)
摄像头抓取视频
import cv2 as cv
cap = cv.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
'''Cap.read ( )返回一个bool (真假)。如果帧被正确读取,它将为True。因此,您可以通过检查此返回值来检查视频的结尾。
有时,cap可能没有初始化捕获。在这种情况下,这个代码显示出一个错误。您可以检查它是否由方法cap . isOpened ( )初始化。
如果是真的,OK。否则使用cap.open ( )打开它。
您还可以使用cap . get ( propId )方法访问这个视频的一些特征,
其中propId是一个从0到18的数字。每个数字表示视频(如果它适用于该视频)的一个属性。
完整的细节可以在这里看到:: cv::VideoCapture::get().。其中一些值可以使用cap . set(propId,value)进行修改。value就是你想要的新value。
例如,我可以通过cap.get ( cv.Cap_Prop_Frame_Width)和Cap.Get(CV.CAP_PROP_FRAME_HEIGHT )。\
默认情况下它给我640x480。但是我想将其修改为320x240。只需使用ret = cap . set( cv.CAP _ PROP _ FRAME _ WIDTH , 320) and ret = cap.set(cv.CAP_PROP_FRAME_HEIGHT,240)'''
# Our operations on the frame come here
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#函数cvCvtColor实现色彩空间转换 这里是bgr转换为gray
# Display the resulting frame
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):#ord函数ord函数是Python的内置函数的一种。它可以对应一个长度为1的字符返回相对应的Unicode值或者8进制的ASCII值。严密意思上说,它是与chr函数完全相反计算的函数。平时运用中,也可以将unichr函数认为是ord函数的相反函数。
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
直接文档里的视频
'''这里我向 VideoCapture 对象传入了参数 0,表示设备索引,设备索引就是指定哪个摄像头的数字。正常情况下,一个摄像头会被连接(就像我的情况一样)。所以我简单地传0。你可以通过传递1来选择第二个相机,以此类推。
cap.isOpened() 用来判断是否捕获到视频。
cap.read() 返回布尔值(True/ False)。如果正确读取了帧,它将为True。因此,你可以通过检查此返回值来检查视频的结尾。
cv.imshow 方法用来显示视频的帧。我们播放视频的原理就是逐帧播放。
在最后,不要忘记通过 cap.release() 释放俘虏。'''
import cv2 as cv
cap = cv.VideoCapture('003.mp4')
'''从文件中播放视频与从相机中捕获视频一样,只需将相机索引改为视频文件名即可。'''
while cap.isOpened():
ret, frame = cap.read()
'''ret, frame = cap.read()返回值含义:
参数ret 为True 或者False,代表有没有读取到图片
第二个参数frame表示截取到一帧的图片'''
# if frame is read correctly ret is True
if not ret:#如果没有读取到
print("Can't receive frame (stream end?). Exiting ...")
break
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
cv.imshow('frame', frame)
# 在显示框架时,为cv.waitKey ( )使用适当的时间。如果它太少,视频将非常快,
# 如果它太高,视频将慢(那么,这就是你如何在慢动作中显示视频)。在正常情况下,25毫秒就可以了
if cv.waitKey(25) == ord('q'):#这个ord的意思是,视频在播放的时候,如果输出q,则结束
break
cap.release()
cv.destroyAllWindows()
保存视频
'''从相机读取视频,我们可以将视频保存到本地。我们捕捉一个视频,一帧一帧地处理,如果我们想要保存这个视频,非常简单,只需使用 cv.VideoWriter()。
cv.VideoWriter() 有5个参数:
参数1:输出文件名,例如: output.mp4。
参数2:FourCC 代码,FourCC 是用于指定视频编解码器的4字节代码。
参数3:帧率的数量。
参数4:帧大小。
参数5:颜色标志。如果为 True,正常颜色输出,否则就是灰色图像输出。
关于 FourCC 与视频格式的对照关系,我列举了一些常见的格式:
cv2.VideoWriter_fourcc(‘P’,‘I’,‘M’,‘1’) = MPEG-1 codec cv2.VideoWriter_fourcc(‘M’,‘J’,‘P’,‘G’) = motion-jpeg codec --> mp4v cv2.VideoWriter_fourcc(‘M’, ‘P’, ‘4’, ‘2’) = MPEG-4.2 codec cv2.VideoWriter_fourcc(‘D’, ‘I’, ‘V’, ‘3’) = MPEG-4.3 codec cv2.VideoWriter_fourcc(‘D’, ‘I’, ‘V’, ‘X’) = MPEG-4 codec --> avi cv2.VideoWriter_fourcc(‘U’, ‘2’, ‘6’, ‘3’) = H263 codec cv2.VideoWriter_fourcc(‘I’, ‘2’, ‘6’, ‘3’) = H263I codec cv2.VideoWriter_fourcc(‘F’, ‘L’, ‘V’, ‘1’) = FLV1 codec'''
import cv2 as cv
cap = cv.VideoCapture(0)
'''我们创建一个VideoWriter对象。我们应该指定输出文件名(例如:output.avi )。然后我们应该指定FourCC代码(下一段详述)。然后应该传递每秒帧数( fps )和帧大小。最后一个是isColor标志。如果为True,则编码器期望为彩色帧,否则为灰度帧。
FourCC是一个4字节的代码,用于指定视频编解码器。可用代码的列表可以在Fourcc . org中找到。它是平台依赖的。下面的编解码器对我来说很好。
window版本:Divx (更多有待测试和补充)
通过4CC编码' cv . VideoWriter _ Fourcc( ' M '、' J '、' P '、' G ')或cv.VideoWriter_fourcc( * ' Mjpg ' ) '。
下面的代码从相机中捕获,在垂直方向上翻转每一帧,并保存视频。'''
# Define the codec and create VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID')
#cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')该参数是MPEG-4编码类型,文件名后缀为.avi,可指定结果视频的大小
# 这里的*'XVID'是解包比上面写法简便一点
out = cv.VideoWriter('004output.avi', fourcc, 20.0, (640, 480),False)#该函数中分为5个参数,分别表示:储存路径及文件名称、保存视频的格式、每一帧播放速率、视频窗口画幅和颜色参数,如果颜色参数是true则正常输出,false则灰度输出
'''以上2句可改为:size = (intd'd(cap.get(cv.CAP_PROP_FRAME_WIDTH)),
int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)))
out = cv.VideoWriter('output.avi', cv.VideoWriter_fourcc(*'XVID'), 20.0, size, 1)'''
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
frame = cv.flip(frame, 1)# 0 --- 垂直方向翻转; 1----- 水平方向翻转; -1:水平、垂直方向同时翻转
# write the flipped frame
out.write(frame)
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
# Release everything if job is finished
cap.release()
out.release()
cv.destroyAllWindows()
画图工具
import numpy as np
import cv2 as cv
# Create a black image
''' numpy有np.uint8()函数,但是这个函数仅仅是对原数据和0xff相与(和最低2字节数据相与),这就容易导致如果原数据是大于255的,那么在直接使用np.uint8()后,比第八位更大的数据都被截断了,比如:
>>>a=[2000,100,2]
>>>np.uint8(a)
array([208, 100, 2], dtype=uint8)
2:用cv2.normalize函数配合cv2.NORM_MINMAX,可以设置目标数组的最大值和最小值,然后让原数组等比例的放大或缩小到目标数组,如下面的例子中是将img的所有数字等比例的放大或缩小到0–255范围的数组中,
cv2.normalize(img, out, 0, 255, cv2.NORM_MINMAX)
然后改变数据类型
np.array([out],dtype=‘uint8’)
总结:
要想将当前的数组作为图像类型来进行各种操作,就要转换到uint8类型,转换的方式推荐使用第二种,因为第一种在值大于255以后就容易丢失。
'''
img = np.zeros((512,512,3), np.uint8)#dtype='uint8'是专门用于存储各种图像的(包括RGB,灰度图像等),范围是从0–255
# Draw a diagonal blue line with thickness of 5 px
# 要画一条直线,需要通过直线的起点和终点坐标。我们将创建一个黑色图像,并在其上从左上角到右下角画一条蓝色线。
cv.line(img,(0,0),(511,511),(255,0,0),5)
cv.imshow('img',img)
cv.waitKey(0)#零意味着永远等待。返回值是被按下的键
'''cv.xxx()函数
void cvLine (
CvArr* img, 为一个图像类型的指针,指向单通道或多通道的图像
CvPoint pt1,线段的起始点
CvPoint pt2,线段的终止点
CvScalar color,线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)
int thickness,组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形
int line_type,线条的类型(见cvLine的描述)
int shift 坐标点的小数点位数
)
'''
# 要绘制矩形,您需要矩形的左上角和右下角。这一次我们将在图像的右上角绘制一个绿色矩形。
cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv.imshow('img',img)
cv.waitKey(0)
# 要画一个圆,你需要它的圆心坐标和半径。我们将在上面画的矩形内画一个圆。
cv.circle(img,(447,63), 63, (0,0,255), -1)
cv.imshow('img',img)
cv.waitKey(0)
'''要绘制椭圆,我们需要传递几个参数。一种说法是中心位置( x , y)。下一个参数是轴长(长轴长度,短轴长度)。角度是椭圆在逆时针方向的旋转角度。startAngle和endAngle表示从长轴顺时针方向测量的椭圆弧的起点和终点,即给定值0和360给出完整的椭圆。
有关更多详细信息,请查看cv.ellipse ( )的文档。下面的例子在图像的中心画了一个半椭圆。'''
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
cv.imshow('img',img)
cv.waitKey(0)
# polylines 多线段,多边形要绘制多边形,首先需要顶点的坐标。将这些点组成一个形状为ROWSx1x2的数组,其中ROWS是顶点数,它的类型应该是int32。在这里我们用黄色画了一个4个顶点的小多边形。
'''说明
如果第三个参数为False,则会得到一个折线连接所有的点,而不是一个闭合的形状。cv.polylines( )可以用来绘制多条直线。只需创建想要绘制的所有线条的列表,并传递给函数即可。所有线条将单独绘制。与为每一行调用cv . line ( )相比,绘制一组行是一种更好、更快的方法。
在图像中添加文字:
-要将文本放入图像中,需要指定以下事项。
-想要写入的文本数据
-位置坐标的地方,你想把它(即数据开始的左下角)。
-字体类型(对支持的字体检查cv . putText ( ) docs )
-字体尺(指定字体的大小)规则的东西,如颜色、粗细、线型等。为了更好看,线型= cv。建议使用line _ Aa。
我们将用白色的颜色在我们的图像上写OpenCV。'''
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))
cv.imshow('img',img)
cv.waitKey(0)
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)
cv.imshow('img',img)
cv.waitKey(0)
鼠标事件
import cv2 as cv
events = [i for i in dir(cv) if 'EVENT' in i]
print( events )#查看有哪些事件
''' CV_EVENT_MOUSEMOVE =0, //鼠标移动
CV_EVENT_LBUTTONDOWN =1, //按下左键
CV_EVENT_RBUTTONDOWN =2, //按下右键
CV_EVENT_MBUTTONDOWN =3, //按下中键
CV_EVENT_LBUTTONUP =4, //放开左键
CV_EVENT_RBUTTONUP =5, //放开右键
CV_EVENT_MBUTTONUP =6, //放开中键
CV_EVENT_LBUTTONDBLCLK =7, //左键双击
CV_EVENT_RBUTTONDBLCLK =8, //右键双击
CV_EVENT_MBUTTONDBLCLK =9, //中键双击
CV_EVENT_MOUSEWHEEL =10, //滚轮滚动
CV_EVENT_MOUSEHWHEEL =11 //横向滚轮滚动(还好我鼠标是G502可以这么干)
其中DBLCLK:double click '''
import numpy as np
def draw_circle(event,x,y,flags,param):
if event == cv.EVENT_LBUTTONDBLCLK:#双击左键
cv.circle(img,(x,y),100,(255,0,0),-1)
# Create a black image, a window and bind the function to window
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
cv.imshow('image',img)
'''-1 & 0xFF的计算过程:
-1 的原码: 1000 0001
-1 的反码: 1111 1110
-1 的补码: 1111 1111
0xFF原(补)码:1111 1111
按为取&后: 1111 1111 = 255(十进制)'''
if cv.waitKey(2) & 0xFF == 27:#ESC的ascii码是27
break
cv.destroyAllWindows()
# 更多例子
drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix,iy = -1,-1
# mouse callback function
def draw_circle(event,x,y,flags,param):
global ix,iy,drawing,mode
if event == cv.EVENT_LBUTTONDOWN:#单击鼠标左键
drawing = True
ix,iy = x,y
elif event == cv.EVENT_MOUSEMOVE:#移动鼠标
if drawing == True:
if mode == True:
cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
else:
cv.circle(img,(x,y),5,(0,0,255),-1)
elif event == cv.EVENT_LBUTTONUP:
drawing = False
if mode == True:
cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
else:
cv.circle(img,(x,y),5,(0,0,255),-1)
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
elif k == 27:#ESC的ascii码是27
break
cv.destroyAllWindows()
调色板
'''在这里,我们将创建一个简单的应用程序,显示您指定的颜色。
你有一个显示颜色的窗口和三个跟踪栏来指定B、G、R三种颜色。
您滑动跟踪栏并相应地更改窗口颜色。默认情况下,初始颜色将设置为黑色。
轨迹栏的另一个重要应用是将其用作按钮或开关。默认情况下,OpenCV没有按钮功能。因此,您可以使用轨迹栏来获得这样的功能。
在我们的应用程序中,我们创建了一个开关,只有当开关为ON时,应用程序才能工作,否则屏幕始终为黑色。'''
import numpy as np
import cv2 as cv
def nothing(x):
pass
# Create a black image, a window
img = np.zeros((300,512,3), np.uint8)
cv.namedWindow('image')
'''对于cv.createTrackbar ( )函数,第一个参数是trackbar名称
,第二个参数是它所连接的窗口名称,第三个参数是默认值,第四个参数是最大值,
第五个参数是回调函数,每次trackbar值更改时执行该函数。回调函数始终有一个默认参数,
即轨线位置。在我们的情况下,函数什么都不做,所以我们简单地通过。'''
cv.createTrackbar('R','image',0,255,nothing)
cv.createTrackbar('G','image',0,255,nothing)
cv.createTrackbar('B','image',0,255,nothing)
# create switch for ON/OFF functionality
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image',0,1,nothing)
while(1):
cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == 27:#ESC的ascii码是27
break
# get current positions of four trackbars
r = cv.getTrackbarPos('R','image')
g = cv.getTrackbarPos('G','image')
b = cv.getTrackbarPos('B','image')
s = cv.getTrackbarPos(switch,'image')
# 此函数的作用:配合createTrackbar使用,获取当前滑块的位置。
# 函数原型: getTrackbarPos( trackbarname, winname)
# trackbarname:轨迹条的名字。
# winname:轨迹条所在窗口的名字。
if s == 0:
img[:] = 0#a[:]就是全部数据的意思,2个维度都不做限制,
else:
img[:] = [b,g,r]
cv.destroyAllWindows()