opencv - 1 - 初入门径

配置环境

1、 下载python
2、 下载pycharm
3、 利用pip安装以下库

pip install numpy
pip install matplotlib
pipinstall opencv-python-i https://pypi.tuna.tsinghua.edu.cn/simple

4、 测试环境

import cv2 as cv
print(cv.__version__)

读取/写入图像

1、只读取

import numpy as np
import cv2 as cv

#加载彩色灰度图像
img = cv.imread('img/1.png',0)
cv.imshow('First img',img)
cv.waitKey(0)
cv.destroyAllWindows()
  • waitKey()会检测按下了什么按键,如果一直不按就会一直等待直到按下再继续下面的程序,另外还可以返回按下按键的值,如esc代表27,也可以用ord('s')直接指代s按键。
  • cv.destroyAllWindows()只会破坏我们创建的所有窗口。如果要销毁任何特定的窗口,请使用函数 cv.destroyWindow()在其中传递确切的窗口名称作为参数。
    2、用matplotlib读取opencv得到的img对象
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('img/1.png',0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])  # 隐藏 x 轴和 y 轴上的刻度值
plt.show()

2、读取加写入

import numpy as np
import cv2 as cv
img = cv.imread('img/1.png',0)
cv.imshow('image',img)
k = cv.waitKey(0)
if k == 27:         # 等待ESC退出
    cv.destroyAllWindows()
elif k == ord('s'): # 等待关键字,保存和退出
    cv.imwrite('img/1.png',img)
    cv.destroyAllWindows()
  • cv.imwrite('img/1.png',img)中路径和原来一致就是覆盖,若不是就是创建一个新的图片,如cv.imwrite('img/4.png',img)

读取/写入视频

1、读取摄像头

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0) #传入数字时表示哪个摄像头,传入视频路径就是读取视频
if not cap.isOpened():
    print("Cannot open camera")
	cap.release()
    exit()
while True:
    # 逐帧捕获,ret表示是否读取到这一帧,frame表示这一帧的图像
    ret, frame = cap.read()
    # 如果正确读取帧,ret为True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
	# 上一步已经得到了帧的img,在下一步读取之前,该位置可以对图像做一定处理,如翻转,改颜色等等,此处尝试翻转
	
    cv.imshow('frame', gray)
    if cv.waitKey(1) == ord('q') or cv.waitKey(1) == 27:
        break
# 完成所有操作后,释放捕获器
cap.release()
cv.destroyAllWindows()

2、读取视频
cap = cv.VideoCapture(0) 中
cv.VideoCapture()传入数字时表示哪个摄像头,传入视频路径就是读取视频
所以只需要改成
cap = cv.VideoCapture("img/vtest.avi")
即可读取视频

3、保存视频
主要是根据需要创建特定的写入器,然后在读取到帧和显示帧之间做一个帧处理然后保存该帧图像

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
# 定义编解码器并创建VideoWriter对象
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640,  480))
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    frame = cv.flip(frame, 0)
    # 写翻转的框架
    out.write(frame)
    cv.imshow('frame', frame)
    if cv.waitKey(1) == ord('q'):
        break
# 完成工作后释放所有内容
cap.release()
out.release()
cv.destroyAllWindows()

所以我们捕捉一个视频,一帧一帧地处理,我们想要保存这个视频。对于图像,它非常简单,只需使用 cv.imwrite()。这里还需要做一些工作。

创建一个 VideoWriter 对象。我们应该指定输出文件名(例如: output.avi)。然后我们应该指定 FourCC 代码(详见下一段)。然后传递帧率的数量和帧大小。最后一个是颜色标志。如果为 True,编码器期望颜色帧,否则它与灰度帧一起工作。

FourCC:http://en.wikipedia.org/wiki/FourCC 是用于指定视频编解码器的4字节代码。可用代码列表可在fourcc.org中:http://www.fourcc.org/codecs.php 找到。它取决于平台。遵循编解码器对我来说效果很好。

在Fedora中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用XVID。MJPG会生成大尺寸的视频。X264会生成非常小的尺寸的视频)
在Windows中:DIVX(尚待测试和添加)
在OSX中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。

绘制图像

主要需要学习函数有:

  • cv.line()
  • cv.circle()
  • cv.rectangle()
  • cv.ellipse()
  • cv.putText()

常见参数有:

  • img:您要绘制形状的图像
  • color:形状的颜色。对于BGR,将其作为元组传递,例如:(255,0,0)对于蓝色。对于灰度,只需传递标量值即可(标量即就一个参数数字)。
  • 厚度:线或圆等的粗细。如果对闭合图形(如圆)传递-1 ,它将填充形状。默认厚度= 1
  • lineType:线的类型,是否为8连接线,抗锯齿线等。默认情况下,为8连接线。cv.LINE_AA给出了抗锯齿的线条,看起来非常适合曲线。

1、创建直线

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 创建黑色的图像
img = np.zeros((512,512,3), np.uint8)
# 绘制一条厚度为5的蓝色对角线
cv.line(img,(0,0),(511,250),(255,0,0),5)
cv.imwrite("img/4.png",img)
cv.imshow("img",img)
cv.waitKey(0)
cv.destroyAllWindows()
  • np.zeros()可知img对象的本质就是numpy的数组对象,现在是创建了一个512*512大小的图像,np.uint8指里面每个元素的符号类型,是一种无符号整型。
  • cv.line()参数有:被绘制图像对象、起点、终点、颜色、厚度

2、绘制圆

cv.circle(img,(447,63), 63, (0,0,255), -1)

3、画椭圆
要绘制椭圆,我们需要传递几个参数。一个参数是中心位置(x,y)。下一个参数是轴长度(长轴长度,短轴长度)。angle是椭圆沿逆时针方向旋转的角度。startAngle和endAngle表示从主轴沿顺时针方向测量的椭圆弧的开始和结束。即给出0和360给出完整的椭圆。有关更多详细信息,请参阅cv.ellipse的文档。下面的示例在图像的中心绘制一个椭圆形。

cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)

4、画多边形
要绘制多边形,首先需要顶点的坐标。将这些点组成形状为ROWSx1x2的数组,其中ROWS是顶点数,并且其类型应为int32。在这里,我们绘制了一个带有四个顶点的黄色小多边形。

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))

5、向图像添加文本
要将文本放入图像中,需要指定以下内容。 - 您要写入的文字数据 - 您要放置它的位置坐标(即数据开始的左下角)。 - 字体类型(检查cv.putText文档以获取受支持的字体) - 字体比例(指定字体大小) - 常规的内容,例如颜色,厚度,线条类型等。为了获得更好的外观,建议使用lineType = cv.LINE_AA。

我们将在白色图像上写入OpenCV

font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)

画笔绘制

本质上就是给特定窗口绑定事件返回函数,然后对事件返回函数进行特定的改造

import numpy as np
import cv2 as cv

def draw_circle(event,x,y,flags,param):
    if event == cv.EVENT_LBUTTONDOWN:
        cv.circle(img,(x,y),10,(255,0,0),-1)
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow("image")
cv.setMouseCallback("image",draw_circle)
# 该函数给某个窗口设定特定函数,这就说明我们必需按照他的要求写事件函数
while True:
    cv.imshow("image",img)
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

更好的利用返回函数

drawing = False # 如果按下鼠标,则为真
mode = True # 如果为真,绘制矩形。按 m 键可以切换到曲线
ix,iy = -1,-1
# 鼠标回调函数
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)
posted @ 2024-09-04 14:58  Coder-Wang  阅读(6)  评论(0编辑  收藏  举报