OpenCV-python 学习笔记

图片

image_path="D:/4017b3a047be8128c90af6e96c936034.jpg" 设置图片路径

img=cv2.imread(image_path,0) 读入图片

                      

cv2.namedWindow('image', cv2.WINDOW_NORMAL) 创建窗口,名字是image

    你也可以先创建一个窗口, 之后再加载图像。这种情况下, 你可以决定窗口是否可以调整大小。使用到的函数是cv2.namedWindow()。初始设定函数标签是cv2.WINDOW_AUTOSIZE。但是如果你把标签改成cv2.WINDOW_NORMAL,你就可以调整窗口大小了。

       

cv2.imshow('image',img) image窗口中现实img图片

                            

cv2.waitKey(0)  0键即可结束程序

cv2.imwrite('messigray.png',img) 首先需要一个文件名,之后才 是你要保存的图像。

警告:如果你用的是 64 位系统,你需要将  k = cv2.waitKey(0) 这行改成 k = cv2.waitKey(0)&0xFF。        

Matplotlib

import cv2

from matplotlib import pyplot as plt

image_path="D:/4017b3a047be8128c90af6e96c936034.jpg"

img = cv2.imread(image_path)

plt.imshow(img)  Matplotlib中读入图案

plt.xticks([]), plt.yticks([]) 关闭坐标刻度

          plt.axis('off') 关闭坐标轴

plt.show() Matplotlib中显示图案

视频

cap = cv2.VideoCapture(0)  参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频,如cap = cv2.VideoCapture(“../test.avi”)

while (True):

    ret, frame = cap.read() cap.read()按帧读取视频,ret,frame是获cap.read()方法的两个返回值。其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为Falseframe就是每一帧的图像。

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow('frame',gray)

    if cv2.waitKey(1)& 0xFF == ord('q'): waitKey()方法本身表示等待键盘输入,参数是1,表示延时1ms切换到下一帧图像,对于视频而言;参数为0,如cv2.waitKey(0)只显示当前帧图像,相当于视频暂停,参数过大如cv2.waitKey(1000),会因为延时过久而卡顿感觉到卡顿。

        break

cap.release() 调用release()释放摄像头

cv2.destroyAllWindows() 调用destroyAllWindows()关闭所有图像窗口。

注意:

1.cap.isOpened(),来检查是否成功初始化摄像头设备。如果返回值是 True,那就没有问题。否则就要使用函数 cap.open()。

2.cap.get(propId) 来获得视频的一些参数信息。这里 propId 可以是 0 到 18 之间的任何整数。每一个数代表视频的一个属性。

3.cap.get(3) 和 cap.get(4) 来查看每一帧的宽和高。

ret=cap.set(3,320) 和 ret=cap.set(4,240) 来把宽和高改成 320X240。

import cv2

cap=cv2.VideoCapture("D:\[Nekomoekissaten][180293][È«¼¯][720p][x264_aac][chs][fin].mp4")

fourcc = cv2.VideoWriter_fourcc(*'XVID')

out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480)) # 创建视频流写入对象,VideoWriter_fourcc为视频编解码器,20为帧播放速率,(640480)为视频帧大小

while(cap.isOpened()):

    ret, frame = cap.read() #读取视频帧

    if ret==True:

        frame = cv2.flip(frame,0)   #flip()的作用是使图像进行翻转cv2.flip(filename, flipcode) filename:需要操作的图像flipcode:翻转方式

flipcode

1

水平翻转

0

垂直翻转

-1

水平垂直翻转

       

out.write(frame)#会将所有类型数据转换为字符,字符数组, 字符串并输出.

        cv2.imshow('frame',frame) #显示视频帧

        if cv2.waitKey(1) & 0xFF == ord('q'):

            break

    else:

        break

cap.release()

out.release()

cv2.destroyAllWindows()

#cv2.VideoWriter_fourcc('I', '4', '2', '0'),该参数是YUV编码类型,文件名后缀为.avi

#cv2.VideoWriter_fourcc('P', 'I', 'M', 'I'),该参数是MPEG-1编码类型,文件名后缀为.avi

#cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'),该参数是MPEG-4编码类型,文件名后缀为.avi

#cv2.VideoWriter_fourcc('T', 'H', 'E', 'O'),该参数是Ogg Vorbis,文件名后缀为.ogv

#cv2.VideoWriter_fourcc('F', 'L', 'V', '1'),该参数是Flash视频,文件名后缀为.flv

OpenCV 中的绘图函数

import numpy as np
import cv2
img=np.zeros((512,512,3), np.uint8)#np.zeros()有两个参数,一个是创建的图片矩阵大小,另一个是数据类型512,512是像素(第一个512像素高,第二个是512像素宽)3BGR三种颜色uint8是用0-255表示所有颜色。
cv2.line(img,(0,0),(511,511),(255,0,0),5)#这个函数有5个参数,img是图像名称,起点坐标,终点坐标,(255,0,0)是蓝色,5是线的宽度会画一条 从左上方到右下角的蓝色线段。
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)#画矩形,左上角和右下角
cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)#画椭圆,图像名称,中心点坐标,长轴长度,短轴长度,旋转角度,图像出现的部分(长轴顺时针方向起始的角度和结束角度)0,180是下半个椭圆,颜色数组这里255是蓝色,线宽
cv2.circle(img,(447,63), 63, (0,0,255), -1)#⚪,圆心、半径
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
img = cv2.polylines(img,[pts],True,(0,255,255),3)#图像名称,顶点列表(这个多边形在array中有四个顶点),True表示闭合,(0,255,255)是黄色,3是线宽
font=cv2.FONT_HERSHEY_SIMPLEX #字体
cv2.putText(img,‘OpenCV‘,(10,500), font, 4,(255,255,255),2)
#写字。图像名称,字符串,坐标,字体,字号,(255,255,255)白色、线宽2
cv2.imshow("img",img)
cv2.waitKey(0)

把鼠标当画笔

import cv2
import numpy as np

#定义画圆事件,如果事件双击左键发生

#则以此时双击的点为原点画一个半径为100px BGR(255,255,0)粗细为3px的圆圈def draw_circle(event,x,y,flags,param):
   
if event==cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img
,(x,y),100,(255,0,0),-1)
   
# 创建图像与窗口并将窗口与回调函数绑定
img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow(
'image')
cv2.setMouseCallback(
'image',draw_circle)
while(1):
    cv2.imshow(
'image',img)
   
if cv2.waitKey(20)&0xFF==27:
       
break
cv2.destroyAllWindows()

进阶

import cv2
import numpy as np
import time
img = cv2.imread(
'D:/4017b3a047be8128c90af6e96c936034.jpg')

 

# 当鼠标按下时变为True
drawing = False
# 如果mode true 绘制矩形。按下'm' 变成绘制曲线。
mode = True
ix, iy = -1, -1
# 创建回调函数
def draw_circle(event, x, y, flags, param):
   
global ix, iy, drawing, mode
   
# 当按下左键是返回起始位置坐标
   
if event == cv2.EVENT_LBUTTONDOWN:
        drawing =
True
       
ix, iy = x, y # 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
       elif event == cv2.EVENT_MOUSEMOVE and flags== ==cv2.EVENT_FLAG_LBUTTON:
       
if drawing == True:
           
if mode == True:
                cv2.rectangle(img
, (ix, iy), (x, y), (0, 255, 0), -1)
           
else:
               
# 绘制圆圈,小圆点连在一起就成了线
               
cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
   
# 当鼠标松开停止绘画。
   
elif event == cv2.EVENT_LBUTTONUP:
        drawing =
False
cv2.namedWindow('image')
cv2.setMouseCallback(
'image', draw_circle)
while (1):
    cv2.imshow(
'image', img)
    k = cv2.waitKey(
1) & 0xFF
   
if k == ord('m'):
        mode =
not mode
   
elif k == ord('q'):
       
break

用滑动条做调色板

注意:cv2.waitKey(1)在有按键按下的时候返回按键的ASCII值,否则返回-1& 0xFF的按位与操作只取cv2.waitKey(1)返回值最后八位,因为有些系统cv2.waitKey(1)的返回值不止八位,ord(‘q’)表示qASCII

import cv2
import numpy as np
def nothing(x):
   
pass

 

# 创建一副黑色图像
img=np.zeros((300,512,3),np.uint8)
cv2.namedWindow(
'image')
cv2.createTrackbar(
'R','image',0,255,nothing)
cv2.createTrackbar(
'G','image',0,255,nothing)
cv2.createTrackbar(
'B','image',0,255,nothing)
switch=
'0:OFF\n1:ON'
cv2.createTrackbar(switch,'image',0,1,nothing)
while(1):
    cv2.imshow(
'image',img)
    k=cv2.waitKey(
1)

#&0xFF esc键的ASCII值是27,cv2.waitKey(10)& 0xFF==27就是当按下按键是esc的时候返回true。
    if k==27:
       
break
   
r=cv2.getTrackbarPos('R','image') #轨迹条的名字轨迹条依托窗口的名称                                    b=cv2.getTrackbarPos('B','image')
    s=cv2.getTrackbarPos(switch
,'image')
   
if s==0:
        img[:]=
0
   
else:
        img[:]=[b
,g,r]
cv2.destroyAllWindo

获取并修改像素值

import cv2


import numpy as np


img=cv2.imread("D:/4017b3a047be8128c90af6e96c936034.jpg")
blue=img[
50,50]# 是坐标(5050)处BGR三个通道分别的值

blue=umg[50,50]=[255,255,255]#修改BGR颜色

print img.item(10,10,2)

img.itemset((10,10,2),100)   ---进阶版
print (blue)

print (img.shape)   #img.shape 可以获取图像的形状。他的返回值是一个包含行数,列数, 通道数的元组

print img.size #可以返回图像的像素数目

print img.dtype #返回的是图像的数据类型.

图像 ROI

import cv2
import numpy as np
img=cv2.imread(
'D:/4017b3a047be8128c90af6e96c936034.jpg')
ball=img[
280:340,330:390]#圈定此处的矩形方格内的图片
img[273:333,100:160]=ball#在图片的该处坐标内插入ball 存疑
cv2.imshow('hh',img)
cv2.waitKey(
0)

图像混合

img1=cv2.imread('D:/6d94e77269970ff7bcbdaa41db997211.jpeg')
img2=cv2.imread(
'D:/6d94e77269970ff7bcbdaa41db9972f1.jpeg')
dst=cv2.addWeighted(img1
,0.7,img2,0.3,0)

#把两幅图混合在一起。第一幅图的权重是 0.7,第二幅图的权重 是 0.3
cv2.imshow('dst',dst)
cv2.waitKey(
0)
cv2.destroyAllWindow()

物体跟踪

cap=cv2.VideoCapture(0)


while(1):

# 获取每一帧

    ret,frame=cap.read()

    hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) #图像转换到 HSV

    lower_blue=np.array([110,50,50])#设置蓝色阀值的下限

    upper_blue=np.array([130,255,255])#设置蓝色阀值的上限

    mask=cv2.inRange(hsv,lower_blue,upper_blue) #hsv指的是原图lower_red指的是图像中低于这个lower_red的值,图像值变为0 upper_red指的是图像中高于这个upper_red的值,图像值变为0;而在lower_redupper_red之间的值变成255

    res=cv2.bitwise_and(frame,frame,mask=mask)

    frame = cv2.flip(frame, 1)

# 显示图像

    cv2.imshow('frame',frame)

    cv2.imshow('mask',mask)

    cv2.imshow('res',res)

    k=cv2.waitKey(5)&0xFF

    if k==27:

        break

# 关闭窗口

cv2.destroyAllWindows()

掩膜(mask)

①提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。

②屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。

③结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。

④特殊形状图像的制作。

旋转

import cv2


import numpy as np
img=cv2.imread(
'D:/6d94e77269970ff7bcbdaa41db9972f1.jpeg',0)
rows
,cols=img.shape
# 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M=cv2.getRotationMatrix2D((cols/2,rows/2),90,1.0)
# 第三个参数是输出图像的尺寸中心
dst=cv2.warpAffine(img,M,(2*cols,2*rows))
while(1):
    cv2.imshow(
'img',dst)
   
if cv2.waitKey(1)&0xFF==27:
       
break
cv2.destroyAllWindows()

仿射变换

import cv2


import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread(
'D:/6d94e77269970ff7bcbdaa41db9972f1.jpeg')
rows
,cols,ch=img.shape
print(rows,cols)
pts1=np.float32([[
5,5],[2,5],[5,20]])原图的三点坐标
pts2=np.float32([[1,10],[20,5],[10,25]])目标图的三点坐标
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(img
,M,(cols,rows))
plt.imshow(dst)
plt.show()

透视变换

import cv2


import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread(
'D:/57e8078cd89acf37de07378b9e86341c.jpeg')
rows
,cols,ch=img.shape
print(rows,cols)
pts1 = np.float32([[
646,564],[356,581],[619,301],[363,310]])
pts2 = np.float32([[
0,0],[300,0],[0,300],[300,300]])
M=cv2.getPerspectiveTransform(pts1
,pts2)
dst=cv2.warpPerspective(img
,M,(300,300))
plt.imshow(dst)
plt.show()

简单阀值

import cv2


import numpy as np
from matplotlib import pyplot as plt
from urllib3.connectionpool import xrange
img=cv2.imread(
'D:/b3db58c8856887ebe1639ab370c1731a.jpeg',0)
ret
,thresh1=cv2.threshold(img,127,255,cv2.THRESH_BINARY) ret,thresh2=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret
,thresh3=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret
,thresh4=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret
,thresh5=cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)

#原图像,对像素值进行分类的阈值,当像素值高于(有时是小于)阈值时应该被赋予的新的像素值,OpenCV提供的多种不同的阈值方法。
 

titles=['Original’,Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']

images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in xrange(6):

    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') #subplot() 第一位数将作为 nrows 参数;第二位数将作为 ncols 参数;第三位数将作为 index 参数.

    plt.title(titles[i])

    plt.xticks([]),plt.yticks([])

plt.show()

自适应阀值

import cv2


import numpy as np
from matplotlib import pyplot as plt
from urllib3.connectionpool import xrange

img = cv2.imread(
'D:/57e8078cd89acf37de07378b9e86341c.jpeg',0)
img = cv2.medianBlur(img,5) # 中值滤波,常用来去除椒盐噪声
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#11 Block size, 2 C
th2=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
th3=cv2.adaptiveThreshold(img
,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
titles = [
'Original Image', 'Global Thresholding (v = 127)','Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img
, th1, th2, th3]
for i in xrange(4):
    plt.subplot(
2,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([])
,plt.yticks([])
plt.show()

cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)

src:灰度化的图片

maxValue:满足条件的像素点需要设置的灰度值

adaptiveMethod:自适应方法。有2种:ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C

thresholdType:二值化方法,可以设置为THRESH_BINARY或者THRESH_BINARY_INV

blockSize:分割计算的区域大小,取奇数

C:常数,每个区域计算出的阈值的基础上在减去这个常数作为这个区域的最终阈值,可以为负数

dst:输出图像,可选

图像平滑

2D卷积

import cv2


import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread(
'D:/57e8078cd89acf37de07378b9e86341c.jpeg')
kernel = np.ones((
5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)
plt.subplot(
121),plt.imshow(img),plt.title('Original')
plt.xticks([])
, plt.yticks([])
plt.subplot(
122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([])
, plt.yticks([])
plt.show()

np.ones((5,5),np.float32) shape:代表数据形状,是个元组。

dctype:数据类型,可选,数组所需的数据类型,

order{'C''F'},可选是否以内存中的CFortran连续(行或列)顺序存储多维数据。

高斯模糊

import cv2


import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread(
'D:/57e8078cd89acf37de07378b9e86341c.jpeg')
blur = cv2.GaussianBlur(img
,(5,5),0)
plt.subplot(
121),plt.imshow(img),plt.title('Original')
plt.xticks([])
, plt.yticks([])
plt.subplot(
122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([])
, plt.yticks([])
plt.show()

穿插内容

添加椒盐噪声,原理:通过随机获取像素点并设置为高亮度点和低灰度点来实现的,简单说就是随机的将图像某些像素值改为0或255

def sp_noise(image,prob):

    '''

    添加椒盐噪声

    prob:噪声比例

    '''

    output = np.zeros(image.shape,np.uint8)

    thres = 1 - prob

    for i in range(image.shape[0]):

        for j in range(image.shape[1]):

            rdn = random.random()

            if rdn < prob:

                output[i][j] = 0

            elif rdn > thres:

                output[i][j] = 255

            else:

                output[i][j] = image[i][j]

return output

先添加椒盐噪音再用中值模糊

import cv2


import numpy as np
from matplotlib import pyplot as plt
import random
def sp_noise(image,prob):
   
'''
   
添加椒盐噪声
    prob:噪声比例
    '''
   
output = np.zeros(image.shape,np.uint8)
    thres =
1 - prob
   
for i in range(image.shape[0]):
       
for j in range(image.shape[1]):
            rdn = random.random()
           
if rdn < prob:
                output[i][j] =
0
           
elif rdn > thres:
                output[i][j] =
255
           
else:
                output[i][j] = image[i][j]
   
return output

img = cv2.imread(
'D:/57e8078cd89acf37de07378b9e86341c.jpeg')
img = sp_noise(img
,0.1)
blur = cv2.medianBlur(img
,5)
plt.subplot(
121),plt.imshow(img),plt.title('Original')
plt.xticks([])
, plt.yticks([])
plt.subplot(
122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([])
, plt.yticks([])
plt.show()

双边滤波blur = cv2.bilateralFilter(img,9,75,75)

中值模糊median = cv2.medianBlur(img,5)

高斯模糊blur = cv2.GaussianBlur(img,(5,5),0)

平均blur = cv2.blur(img,(5,5))

2D卷积kernel = np.ones((5,5),np.float32)  dst = cv2.filter2D(img,-1,kernel)

你可能感兴趣的:(opencv)