【opencv】常用API总结

记录一下自己用过的opencv库函数,慢慢填坑

1、I/O

1.1 图片

1.1.1 读取图片

numpy格式存储,颜色空间为BGR

#  cv2.imread(<img_path>)
img1 = cv2.imread('example.jpg')

1.1.2 转换颜色空间类型

# cv2.cvtColor(<img>, <flag>)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)   # BGR -> 灰度图
rgb1 = cv2.cvtColor(gray1, cv2.COLOR_GRAY2BGR)   # 灰度图 -> BGR

常见/常用的是以下几种:
cv2.COLOR_BGR2GRAY:BGR到灰度
cv2.COLOR_GRAY2BGR:灰度到BGR
cv2.COLOR_BGR2RGB:BGR到RGB
cv2.COLOR_RGB2BGR:RGB到BGR
cv2.COLOR_BGR2HSV:BGR到HSV
cv2.COLOR_HSV2BGR:HSV到BGR
特别是cv2matplotlib一起使用时,需要将 BGR->RGB

1.1.3 保存图片

可以保存为任意类型的图片,如jpg、png等(其他的我还没用过)

# cv2.imwrite(<example.jpg>, <img>)
cv2.imwrite('saveimg.jpg', img1)

1.1.4 改变图片尺寸

img = cv2.resize(img, (width,height))

1.2 视频

1.2.1 读取视频并处理每一帧图片

video_path = 'XXXX.mp4' # 支持多种视频格式
cap = cv2.VideoCapture(video_path)
fps = int(cap.get(5))
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
        int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
while True:
    ret,frame = cap.read()
    if frame is None:
        break
    pred = det.detect(img)
    
    a = cv2.waitKey(int(1000/fps))
    if ord('q') == a:
        cap.release()
        break
cap.release()
cv2.destroyAllWindows()

1.2.2 保存视频

path = 'XXXX.avi'
# 输出帧率
fps = 30
# 视频中图像的大小,要与下面写入视频的图像大小一样,否则写入的视频会出错打不开
size = (weight, height)
# 视频编码器格式 mp4——('m', 'p', '4', 'v')
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
# 多通道图像isColor=True,灰度图为False
videowriter = cv2.VideoWriter(path, fourcc, fps, size, isColor=True)
while True:
	_, frame = cap.read()
	# 写入视频
	videowriter.write(frame) 
# 释放
videowriter.release()

2、画图

2.1 展示图片

2.1.1 新建窗口

cv2.namedWindow(<Window_Name>, <flag>)
cv2.namedWindow('origin',0)
cv2.resizeWindow('origin', 900,900)

2.1.2 生成带有控制条的图片

# 创建控制条
# cv2.createTrackbar(<控制条名称>,<窗口名称>,<当前值>,<最大值>)
cv2.createTrackbar('minThreshold','edge_detection',50,1000,lambda x: x)
# 通过控制条选择参数
# minThreshold=cv2.getTrackbarPos(<控制条名称>,<窗口名称>)
minThreshold=cv2.getTrackbarPos('minThreshold','edge_detection')

代码实例

import cv2
import numpy as np

cv2.namedWindow('edge_detection',0)
cv2.resizeWindow('edge_detection',500,800)
cv2.createTrackbar('minThreshold','edge_detection',50,1000,lambda x: x)
cv2.createTrackbar('maxThreshold','edge_detection',100,1000,lambda x: x)
img_path = '/home/zxc/catkin_ws/src/camera/scripts/yutong.jpg'
img=cv2.imread(img_path,cv2.IMREAD_GRAYSCALE)

mask=np.zeros_like(img) 
mask=cv2.fillPoly(mask,np.array([[[875,534],[919,534],[905,606],[855,606]]]),color=255)   
masked_edge_img=cv2.bitwise_and(img,mask)   
while True:
    minThreshold=cv2.getTrackbarPos('minThreshold','edge_detection')
    maxThreshold=cv2.getTrackbarPos('maxThreshold','edge_detection')
    edges=cv2.Canny(masked_edge_img,minThreshold,maxThreshold)
    cv2.imshow('edge_detection',edges)
    cv2.waitKey(10)

以上代码实现了通过手动调整阈值将图像二值化并提取边界特征,可以控制bar来调节阈值。
在这里插入图片描述
在这里插入图片描述

3、关键点和描述子

关键点:位置、直径大小、方向
描述子:记录关键点周围对其有贡献的像素点的一组向量值,不受仿射变换、光照变换等影响

3.1 Harris角点

具有旋转不变性,但是缩放图片会影响Harris角点检测

dst = cv2.cornerHarris(img_gray, blockSize, ksize, k)
# blocksize:角点检测窗口大小,窗口越大敏感性越高,默认值3
# ksize:sobel算子卷积核大小
# k:权重系数,经验值,一般取0.02~0.04之间,默认值0.04
img = cv2.imread('xxx.jpg')
# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = cv2.cornerHarris(gray, blockSize, ksize, k)
img[dst>0.01*dst.max()] = [0,0,255]
cv2.imshow('img',img)
cv2.waitKey(0)

3.2 Shi-Tomasi角点

是Harris的改进,不需要自己设权重系数

cv2.goodFeaturesToTrack(img_gray,maxCorners,)
# maxCorners: 角点的最大数量
# qualityLevel: 角点质量,一般在0.01~0.1之间
# minDistance:角点间最小欧式距离,小于该值会被过滤
# mask:感兴趣区域
# blockSize:检测窗口大小
# useHarrisDetector:是否使用Harris算法,默认为False
# k:Harris检测权重系数

maxCorners = 1000
ql = 0.01
minDistance = 10

corners = cv2.goodFeaturesToTrack(gray,maxCorners,ql,minDistance)
# float32 -> int64
corners = corners.astype(np.int0)

for corner in corners:
    x,y = corner.ravel()
    cv2.circle(img,(x,y),3,(0,0,255),-1)
cv2.imshow('img',img)
cv2.waitKey(0)

3.3 SIFT关键点检测和描述子计算

具有尺度不变性

# 检测关键点
# sift.detect(img_gray,mask)
sift = cv2.SIFT_create()
kp = sift.detect(gray,None)
sift.drawKeypoints(gray, kp, img)
cv2.imshow('img',img)

# 计算描述子
kp, des = sift.compute(img, kp)

# 同时计算关键点和描述子
kp, des = sift.detectAndCompute(img_gray, mask)

3.4 SURF

加速的SIFT

surf = cv2.xfeatures2d.SURF _create()
# 同时计算关键点和描述子
kp, des = surf.detectAndCompute(img_gray, mask)

3.5 ORB

Oriented FAST and Rotated BRIEF
FAST:特征点的实时检测,但没有方向
BRIEF:一种快速计算的描述子,但对图像旋转不友好

orb = cv2.ORB_create()
# 同时计算关键点和描述子
kp, des = orb.detectAndCompute(img_gray, mask)
# 画关键点
cv2.drawKeypoints(gray, kp, img)

# 先用FAST计算关键点,再计算ORB描述子
fast = cv2.FastFeatureDetector_create()
kp = fast.detect(img_gray, mask)
kp, des = orb.compute(img_gray, kp)

3.6 BFMatcher 暴力匹配

# 创建匹配器
bf = BFMatcher(normType, crossCheck)
# normType:匹配项,NORM_L1,NORM_L2,NORM_HAMMING(ORB用这个)
# crossCheck:交叉验证,图1->图2,图2->图1,比较是否是同一对点,默认为False
# 特征匹配
matches = bf.match(des1,des2)
# 绘制匹配点
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches, None)

3.7 FLANN 匹配

匹配速度快,但使用邻近近似值,所以精度比暴力匹配差

# 创建匹配器
index_params = dict(algorithm=FLANN_INDEX_KDTREE,trees=5)
# 匹配算法:KDTREE(SIFT用),LSH(ORB用)
search_params = dict(checks=50) # 一般是trees的10倍
flann = cv2.FlannBasedMatcher(index_params, search_params)
# 特征匹配
matches = flann.match(des1,des2)
# 绘制匹配点
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches, None)

# K邻近匹配,BF也可以用该方法
matches = flann.knnMatch(des1, des2, k) # k邻近匹配,一般选2,之后需要进行筛选
good = []
for i, (m,n) in enumerate(matches):
    if m.distance < 0.7*n.distance:
        good.append(m)
# 绘制匹配点
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, [good], None)

关键点的属性统一写在这里:
kp: <class KeyPoint>,包括以下属性:
KeyPoint.pt 坐标(*最常用的)
KeyPoint.size 直径大小
KeyPoint.angle 方向
KeyPoint.response 响应强度
KeyPoint.octave 金字塔组和层数
KeyPoint.class_id 类别标识

匹配对的属性统一写在这里:
match:<class DMatch>
DMatch.queryIdx 第一幅图像中特征点的索引
DMatch.trainIdx 第二幅图像中特征点的索引
DMatch.distance 两个特征点的距离
如果是KNN匹配,则matches是一个包含k个<class DMatch>的列表

4、坐标变换

4.1、变换矩阵

# 计算多个二维点对或者图像之间的最优仿射变换矩阵2*3
# H是src图像向dst图像变换的矩阵
# 注意这里的pts是包含点坐标的列表,如果是提取的关键点,需要用.pt获取坐标
H, _ = cv2.estimateAffinePartial2D(src_pts,dst_pts, cv2.RANSAC)
# 计算3对二维点对之间的仿射变换矩阵2*3
H = getAffineTransform(src_pts,dst_pts)
# 计算多个二维点对或者图像之间的最优透射变换矩阵3*3
H, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC)
# 计算4对二维点对之间的透射变换矩阵3*3
H = getPerspectiveTransform()

5、特殊功能

5.1 鼠标点击响应

# cv2.setMouseCallback(<windows_name>, <function_name>)
cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN)
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
	if event == cv2.EVENT_LBUTTONDOWN: 
	# 左键点击功能
	elif event == cv2.EVENT_RBUTTONDOWN: 
	#右键点击功能
	elif event == cv2.EVENT_MBUTTONDOWN:  
	#滚轮点击功能
	

猜你喜欢

转载自blog.csdn.net/LoveJSH/article/details/129542123