opencv怎么学?
首先你对opencv要有一个比较粗浅的认识,下方是介绍的链接;
接下来就是具体遇到一个陌生函数了,怎么了解呢?
譬如说本文的warpAffine
函数,首先是不是应该看看帮助文档,如果是在jupyter notebook中,Shift
+Tab
键就可以查看其docstring
,内容如下:
warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) -> dst
. @brief Applies an affine transformation to an image.
. The function warpAffine transforms the source image using the specified matrix:
dst ( x , y ) = src ( M 11 x + M 12 y + M 13 , M 21 x + M 22 y + M 23 ) \texttt{dst} (x,y) = \texttt{src} ( \texttt{M} _{11} x + \texttt{M} _{12} y + \texttt{M} _{13}, \texttt{M} _{21} x + \texttt{M} _{22} y + \texttt{M} _{23}) dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)
还有其他内容我就不再粘贴,最关键的参数就是变换矩阵M
,它是一个 2 × 3 2\times3 2×3的变换矩阵。那么核心问题就是你对变换矩阵有多少了解,对线性变换了解多少,对旋转矩阵有没有印象,对于放缩有没有了解,对平移操作有多少认识,最终归结于对矩阵分析
有多少认识。仿射变换
本质上就是线性变换
+平移
需要明确的是仿射变换是对坐标、位置进行变换,变换前后相应位置的像素内容是不变的,两像素之间的位置空隙是通过插值方式填充的。
接下来可以搜一些博客看看他们的描述以及我认为最为重要的是例子,下面这个链接是我觉得不错的内容,不妨看看:https://blog.csdn.net/keith_bb/article/details/56331356?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase
再看看opencv中文教程的示例:
http://www.woshicver.com/FifthSection/4_2_图像几何变换/
还有一个需要注意的参数,就是dsize
:
他决定着输出图像的尺寸大小,从变换后的图像的左上角开始计数的。不管经过仿射变换后,图像的大小是什么情况,只从左上角开始选取指定dsize
边长的图像块里的像素进行显示。仿射变换拆解开来,有一步就是平移,平移的过程中就会涉及到空白区域的填充,会用boardvalue指定的值进行填充。
举例:本例是缩放
+平移
的仿射变换
import cv2
import numpy as np
def crop_hwc(image, bbox, out_sz, padding=(0, 0, 0)):
a = (out_sz-1) / (bbox[2]-bbox[0])
b = (out_sz-1) / (bbox[3]-bbox[1])
c = -a * bbox[0] # c,d计算的是水平方向和竖直方向平移的距离
d = -b * bbox[1]
mapping = np.array([[a, 0, c], # a、b分别表示水平方向和竖直方向缩放的比例
[0, b, d]]).astype(np.float)
crop = cv2.warpAffine(image, mapping, (out_sz, out_sz),
borderMode=cv2.BORDER_CONSTANT, borderValue=padding)
return crop
def pos_s_2_bbox(pos, s):
# 计算裁切的框的左上角和右下角的坐标位置(小数)
return [pos[0]-s/2, pos[1]-s/2, pos[0]+s/2, pos[1]+s/2]
img = cv2.imread('Cambridge.jpeg')
img.shape # 本行输出为: (347, 474, 3)
avg_chans = np.mean(img, axis=(0, 1)) # 计算三通道各自的均值,为填充空白区域指定数值
target_pos = [100,100] # 选定框的中心坐标为(100,100)
s_x = 300 # 表示在原图选定边长为400的框。这里说的原图就是我们通过cv2.imread读入的原图
search_size = 400 # 表示最终的输出尺寸的边长是400
x = crop_hwc(img,pos_s_2_bbox(target_pos,s_x),search_size,avg_chans)
cv2.imshow('cropped',x)
# cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出仿射变换后的图片如下:
原图是如下: