openCV使用

一、读入图像

使用函数cv2.imread(filepath,flags)读入一副图片
filepath:要读入图片的完整路径
flags:读入图片的标志,取值->1,0,-1
cv2.IMREAD_COLOR:1->默认参数,读入一副彩色图片,忽略alpha通道
cv2.IMREAD_GRAYSCALE:0->读入灰度图片
cv2.IMREAD_UNCHANGED:-1->读入完整图片,包括alpha通道
注意

  • 通道一般为rgb存储,但是opencv中是以bgr存储的
  • 路径名不能含有中文,否则不能读出图片数据
\# img = cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE)  
\# 也可以写成下面这种形式  
img =cv2.imread('1.jpg',0)

二、 显示图像

使用函数cv2.imshow(wname,img)显示图像,第一个参数是显示图像的窗口的名字,第二个参数是要显示的图像(imread读入的图像),窗口大小自动调整为图片大小

cv2.waitKey(0)  
cv2.destroyAllWindows()  
\# cv2.destroyWindow(wname)
  • cv2.waitKey()等待键盘输入,单位为毫秒,即等待指定的毫秒数看是否有键盘输入,若在等待时间内按下任意键则返回按键的ASCII码,程序继续运行。若没有按下任何键,超时后返回-1。参数为0表示无限等待。不调用waitKey的话,窗口会一闪而逝,看不到显示的图片。
  • cv2.destroyAllWindows()销毁所有窗口
  • cv2.destroyWindow(wname)销毁指定窗口

三 、保存图像

使用函数cv2.imwrite(file,img,num)保存一个图像。第一个参数是要保存的文件名,第二个参数是要保存的图像。可选的第三个参数,它针对特定的格式:对于JPEG,其表示的是图像的质量,用0 - 100的整数表示,默认95;对于png ,第三个参数表示的是压缩级别。默认为3.

cv2.imwrite('1.png',img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])  

注意:

  • cv2.IMWRITE_JPEG_QUALITY类型为 long ,必须转换成 int
  • cv2.IMWRITE_PNG_COMPRESSION, 从0到9 压缩级别越高图像越小。

四 、图片操作

4.1 图像翻转

使用函数cv2.flip(img,flipcode)翻转图像,flipcode控制翻转效果。
flipcode = 0:沿x轴翻转
flipcode > 0:沿y轴翻转
flipcode < 0:x,y轴同时翻转

imgflip = cv2.flip(img,1)  

4.2 图像复制

imgcopy=img.copy()  

4.3 颜色空间转换

     # 彩色图像转为灰度图像  
    img2 = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)   
    # 灰度图像转为彩色图像  
    img3 = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)  
    # cv2.COLOR_X2Y,其中X,Y = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS  

4.4 实例

4.4.1 读入一副图像,按’s’键保存后退出,按’q’键则退出

img = cv2.imread('1.jpg',cv2.IMREAD_UNCHANGED)  
cv2.imshow('image',img)  
k = cv2.waitKey(0)  
if k == ord('s'): # wait for 's' key to save and exit  
    cv2.imwrite('1.png',img)  
    cv2.destroyAllWindows()  
 if k == ord('q'): 
    cv2.destroyAllWindows() 

4.4.2 读入一副图像,给图片加文本

> import cv2
 # img=cv2.imread('1.jpg',cv2.IMREAD_COLOR)  
img=cv2.imread('1.png',cv2.IMREAD_COLOR)    # 打开文件  
font = cv2.FONT_HERSHEY_DUPLEX  # 设置字体  
\# 图片对象、文本、像素位置、字体、字体大小、颜色、字体粗细   
imgzi = cv2.putText(img, "0000", (200, 100), font, 5.5, (0, 0, 0), 2,)  
cv2.imshow('1',img)     
cv2.imwrite('2.png',img)    # 写磁盘  
cv2.destroyAllWindows()     # 毁掉所有窗口  
cv2.destroyWindow(wname)    # 销毁指定窗口  
### 4.4.3 画图
```import numpy as np  
import cv2  
 \# 创建一个宽512高512的黑色画布,RGB(0,0,0)即黑色  
 img=np.zeros((512,512,3),np.uint8)    
 
\# 画直线,图片对象,起始坐标(x轴,y轴),结束坐标,颜色,宽度    
cv2.line(img,(0,0),(311,511),(255,0,0),10)    

\# 画矩形,图片对象,左上角坐标,右下角坐标,颜色,宽度  
cv2.rectangle(img,(30,166),(130,266),(0,255,0),3) 

\# 画圆形,图片对象,中心点坐标,半径大小,颜色,宽度  
cv2.circle(img,(222,222),50,(255.111,111),-1)  

\# 画椭圆形,图片对象,中心点坐标,长短轴,顺时针旋转度数,开始角度(右长轴表0度,上短轴表270度),颜色,宽度   
cv2.ellipse(img,(333,333),(50,20),0,0,150,(255,222,222),-1)    

\# 写字,字体选择    
font=cv2.FONT_HERSHEY_SCRIPT_COMPLEX    

\# 图片对象,要写的内容,左边距,字的底部到画布上端的距离,字体,大小,颜色,粗细  
cv2.putText(img,"OpenCV",(10,400),font,3.5,(255,255,255),2)  
a=cv2.imwrite("picture.jpg",img)  
cv2.imshow("picture",img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

五 、基本图像处理

5.1存取图片

 读图像用cv2.imread(),可以按照不同模式读取,一般最常用到的是读取单通道灰度图,或者直接默认读取多通道。存图像用cv2.imwrite(),注意存的时候是没有单通道这一说的,根据保存文件名的后缀和当前的array维度,OpenCV自动判断存的通道,另外压缩格式还可以指定存储质量,来看代码例子:

import cv2
# 读取一张400x600分辨率的图像
color_img = cv2.imread(‘test_400x600.jpg’)
print(color_img.shape)
# 直接读取单通道
gray_img = cv2.imread(‘test_400x600.jpg’, cv2.IMREAD_GRAYSCALE)
print(gray_img.shape)
# 把单通道图片保存后,再读取,仍然是3通道,相当于把单通道值复制到3个通道保存
cv2.imwrite(‘test_grayscale.jpg’, gray_img)
reload_grayscale = cv2.imread(‘test_grayscale.jpg’)
print(reload_grayscale.shape)
# cv2.IMWRITE_JPEG_QUALITY指定jpg质量,范围0到100,默认95,越高画质越好,文件越大
cv2.imwrite(‘test_imwrite.jpg’, color_img, (cv2.IMWRITE_JPEG_QUALITY, 80))
# cv2.IMWRITE_PNG_COMPRESSION:指定png质量,范围0到9,默认3,越高文件越小,画质越差
cv2.imwrite(‘test_imwrite.png’, color_img, (cv2.IMWRITE_PNG_COMPRESSION, 5))

5.2 缩放、裁剪、补边

 缩放通过cv2.resize()实现,裁剪则是利用array自身的下标截取实现,此外OpenCV还可以给图像补边,这样能对一幅图像的形状和感兴趣区域实现各种操作。下面的例子中读取一幅400×600分辨率的图片,并执行一些基础的操作:

import cv2
# 读取图片
img = cv2.imread(‘tiger_tibet_village.jpg’)
# 缩放成200x200的方形图像
img_200x200 = cv2.resize(img, (200, 200))
# 不直接指定缩放后大小,通过fx和fy指定缩放比例,0.5则长宽都为原来一半
# 等效于img_200x300 = cv2.resize(img, (300, 200)),注意指定大小的格式是(宽度,高度)
# 插值方法默认是cv2.INTER_LINEAR,这里指定为最近邻插值
img_200x300 = cv2.resize(img, (0, 0), fx=0.5, fy=0.5,
interpolation=cv2.INTER_NEAREST)
# 在上张图片的基础上,上下各贴50像素的黑边,生成300x300的图像
img_300x300 = cv2.copyMakeBorder(img, 50, 50, 0, 0,
cv2.BORDER_CONSTANT,
value=(0, 0, 0))
# 对图片进行剪裁
crop = img[20:150, -180:-50]
cv2.imwrite(‘crop.jpg’, crop)
cv2.imwrite(‘resized_200x200.jpg’, img_200x200)
cv2.imwrite(‘resized_200x300.jpg’, img_200x300)
cv2.imwrite(‘bordered_300x300.jpg’, img_300x300)

5.3 色调、明暗

  除了区域,图像本身的属性操作也非常多,比如可以通过HSV空间对色调和明暗进行调节。HSV空间是由美国的图形学专家A. R. Smith提出的一种颜色空间,HSV分别是色调(Hue),饱和度(Saturation)和明度(Value)。在HSV空间中进行调节就避免了直接在RGB空间中调节是还需要考虑三个通道的相关性。OpenCV中H的取值是[0, 180),其他两个通道的取值都是[0, 256),下面例子接着上面例子代码,通过HSV空间对图像进行调整:

\ # 通过cv2.cvtColor把图像从BGR转换到HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# H空间中,绿色比黄色的值高一点,所以给每个像素+15,黄色的树叶就会变绿
turn_green_hsv = img_hsv.copy()
turn_green_hsv[:, :, 0] = (turn_green_hsv[:, :, 0]+15) % 180
turn_green_img = cv2.cvtColor(turn_green_hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite(‘turn_green.jpg’, turn_green_img)
# 减小饱和度会让图像损失鲜艳,变得更灰
colorless_hsv = img_hsv.copy()
colorless_hsv[:, :, 1] = 0.5 * colorless_hsv[:, :, 1]
colorless_img = cv2.cvtColor(colorless_hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite(‘colorless.jpg’, colorless_img)
# 减小明度为原来一半
darker_hsv = img_hsv.copy()
darker_hsv[:, :, 2] = 0.5 * darker_hsv[:, :, 2]
darker_img = cv2.cvtColor(darker_hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite(‘darker.jpg’, darker_img)

5.4 图像的仿射变换

 图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,在此简单回顾一下。仿射变换具体到图像中的应用,主要是对图像的缩放,旋转,剪切,翻转和平移的组合。在OpenCV中,仿射变换的矩阵是一个2×3的矩阵,其中左边的2×2子矩阵是线性变换矩阵,右边的2×1的两项是平移项:

M = [ A B ] = [ a 11 a 12 b 1 a 21 a 22 b 2 ] M=[AB]=\begin{bmatrix} a_{11} & a_{12} & b_{1} \\ a_{21} & a_{22} & b_{2} \end{bmatrix} M=[AB]=[a11a21a12a22b1b2]
对于图像上的任一位置(x,y),仿射变换执行的是如下的操作:

X Y n e w = A [ x y ] + B = M [ x y 1 ] XY_{new}= A\begin{bmatrix} x \\ y \end{bmatrix}+B=M\begin{bmatrix} x \\ y \\1 \end{bmatrix} XYnew=A[xy]+B=Mxy1

import numpy as np
import cv2
# 定义一个3维数组,相当于是画布,大小H*W,,初始化白色
canvas=np.zeros((400,600,3),dtype=np.uint8)+255

# 画一条纵向的正中央的黑色分界线
cv2.line(canvas, pt1=(300, 0), pt2=(300, 399), color=(0, 0, 0), thickness=1)

# 画一条右半部份画面以150为界的横向分界线
cv2.line(canvas, pt1=(300, 149), pt2=(599, 149), color=(0, 0, 0), thickness=2)

# 左半部分的右下角画个红色的圆
cv2.circle(canvas, center=(200, 300), radius=75, color=(0, 0, 255), thickness=5)


# 定义两个三角形,并执行内部填充
triangles = np.array([[(200, 240), (145, 333), (255, 333)],[(60, 180), (20, 237), (100, 237)]])
cv2.fillPoly(canvas, triangles, (255, 0,255))
cv2.polylines(canvas, triangles, isClosed=True, color=(255, 0,0),thickness=2)

# 画一个黄色五角星
# 第一步通过旋转角度的办法求出五个顶点  
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),thickness=3)

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, radius=1, color=pt_color, thickness=2)

# 在左半部分最上方打印文字
text="Python-OpenCV Drawing Example"
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(canvas,text,(5, 15),font,0.5,(0, 0, 0),1)

# 调整窗口
cv2.namedWindow('EXAMPLE',cv2.WINDOW_NORMAL)
cv2.imshow('EXAMPLE', canvas)
cv2.waitKey()

六、 视频功能

 视频中最常用的就是从视频设备采集图片或者视频,或者读取视频文件并从中采样。所以比较重要的也是两个模块,一个是VideoCapture,用于获取相机设备并捕获图像和视频,或是从文件中捕获。还有一个VideoWriter,用于生成视频。还是来看例子理解这两个功能的用法。

6.1 摄像头录制视频

import cv2
import time


# 用摄像头录取视频 
class CapVideo(object):
    def __init__(self, out_fps=24, size=(640, 480)):
        self.fps = out_fps
        self.size = size

    def cap_video(self, filename):
        # 输出文件的帧率
        out_fps = self.fps
        # 表示打开默认的相机
        cap = cv2.VideoCapture(0)
        # 获取捕获图像的分辨率
        size = self.size
        # 编码格式
        fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', '2')
        # 设置视频的编码,分辨率和帧率
        video = cv2.VideoWriter(filename, fourcc, out_fps, size)
        while cap.isOpened():
            ret, frame = cap.read()
            if ret:
                cv2.imshow('frame', frame)
                video.write(frame)
                # 这个函数接收一个整型值,如果这个值是零,那么函数不会有返回值,
                # 如果delay大于0,那么超过delayms后,如果没有按键,那么会返回 - 1,如果按键那么会返回键盘值
                if cv2.waitKey(1) & 0xFF == 27:
                    break
            else:
                break

        video.release()
        cap.release()
        cv2.destroyAllWindows()

6.2从视频中截取图片

# 从视频文件中获取图片
class CapFrame(object):
    def __init__(self, filename, fps=24):
        self.filename = filename
        self.fps = fps

    def cap_frame(self):
        import os
        # 要提取视频
        filename = self.filename
        timestamp = 0
        # 提取视频的频率,
        fps = self.fps
        # 输出图片到当前目录images文件夹下
        out_put_dir = 'images/'
        if not os.path.exists(out_put_dir):
            # 如果文件目录不存在则创建目录
            os.makedirs(out_put_dir)
        cap = cv2.VideoCapture(filename)
        while True:
            timestamp += 1
            res, image = cap.read()
            if not res:
                print('not res , not image')
                break
            # 每24帧提取一张
            if timestamp % fps == 0:
                cv2.imwrite(out_put_dir + str(timestamp) + '.jpg', image)
                print(out_put_dir + str(timestamp) + '.jpg')
        print('图片提取结束')
        cap.release()
        
if __name__=="__main__":
    video=CapVideo()
    video.cap_video('test_video.avi')
    frame=CapFrame('test_video.avi')
    frame.cap_frame()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值