媒介
- 通过本日的学习,我把握了OpenCV中有关图像翻转,图像仿射变更的原理和使用以及部门OpenCV中的插值方法
一、图像翻转
- 使用flip方法对图像举行翻转
- cv.flip(img,flipcode)
- img:指要举行翻转使用的图像名
- flipcode:指图像翻转的方式
- img = cv.imread(r"img\cat.png")
- flip1 = cv.flip(img,0) #垂直翻转
- flip2 = cv.flip(img,1) #水平翻转
- flip3 = cv.flip(img,-1) #垂直结合水平翻转
复制代码 二、图像的仿射变更
1.仿射变更的原理
- 仿射变更实际上是一种线性变更
- 仿射变更紧张包罗:旋转,平移,缩放以及剪切
- 实现仿射变更实际上是在做矩阵乘法
- 在上图所示的式子中,a,b,c,d代表线性变革的系数,而t参数代表平移部门的参数,输入点是齐次坐标情势
2.仿射变更函数
- 在OpenCV中,我们先使用warpAffine函数接收仿射变更矩阵从而返回一个图像数组
- cv2.warpAffine(img,M,dsize)
- 因此,我们须要先得到仿射变更矩阵,才能得到图像数组
- 我们使用Numpy数组中的float32方法举行构造
3.图像旋转
- cv2.getRotationMatrix2D(center,angle,scale)
- center:指旋转中心。通常是图像的几何中心
- angle:指旋转角度
- scale:指返回图像的缩放比例
- img = cv.imread(r"img\cat1.png")
- h,w,_ = img.shape
- center = (w//2,h//2)
- M = cv.getRotationMatrix2D(center,90,0.6)
- img1 = cv.warpAffine(img,M,(w,h))
- cv.imshow('img1',img1)
- cv.waitKey(0)
- cv.destroyAllWindows()
复制代码 4.图像平移
- 平移只改变图像的相对位置,角度不发生变革
- 可用以下矩阵乘法体现:
- img = cv.imread(r"img\cat1.png")
- h,w,_ = img.shape
- x,y = 200,100
- M = np.float32([[1,0,x],[0,1,y]]) #构造平移仿射矩阵
- img2 = cv.warpAffine(img,M,(w,h))
- cv.imshow('img',img)
- cv.imshow('img2',img2)
- cv.waitKey(0)
- cv.destroyAllWindows()
复制代码 5.图像缩放
- 缩放改变图像的巨细,相对位置未便,即不发一生移使用
- 可用以下矩阵乘法体现:
- img = cv.imread(r"img\cat1.png")
- h,w,_ = img.shape
- sx,sy = 0.5,0.8
- w1,h1 = int(w*sx),int(h*sy)
- M = np.float32([[sx,0,0],[0,sy,0]])
- img3 = cv.warpAffine(img,M,(w,h)) #输出图像是原图的尺寸
- img4 = cv.warpAffine(img,M,(w1,h1)) #输出图像是缩放后的尺寸
- cv.imshow('img',img)
- cv.imshow('img3',img3)
- cv.imshow('img4',img4)
- cv.waitKey(0)
- cv.destroyAllWindows()
复制代码 6.图像剪切
- 剪切区别于切片,可以改变图像的形状,但保持图像面积未便
- 可用以下矩阵乘法体现:
- img = cv.imread(r"img\cat1.png")
- img_r = cv.resize(img,(300,300))
- shx,shy = 0.2,0.2
- M = np.float32([[1,shy,0],[shx,1,0]])
- img5 = cv.warpAffine(img_r,M,(360,360))
- cv.imshow('img_r',img_r)
- cv.imshow('img5',img5)
- cv.waitKey(0)
- cv.destroyAllWindows()
复制代码 三、插值方法
- 在上一节提到了图像的仿射变更,而这里的插值方法就是为相识决图像缩放大概旋转等使用时,由于像素之间的隔断不一致而导致的信息丢失和图像质量下降的标题
- 插值算法的作用是根据已知的像素值来推测未知的像素值
1.近来领插值
s r c X = d s t X ∗ s r c W i d t h d s t W i d t h s r c X=d s t X*{\frac{s r c Width}{d s t Width}} srcX=dstX∗dstWidthsrcWidth
s r c Y = d s t Y ∗ s r c H e i g h t d s t H e i g h t s r cY=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}} srcY=dstY∗dstHeightsrcHeight
- dst:代表目标图像
- src:代表目标图像中某点对应原图
tips:如果结果得到了小数,则使用四舍五入举行盘算
2.双线性插值法
- 当图像颠末缩放、旋转等变更后,目标图像的像素位置大概对应原图的非整数坐标。直接使用近来邻插值(取近来的整数坐标像素)会导致锯齿状边缘,而双线性插值通过四周像素的加权平均,天生更平滑的过渡
- 本质上是分别在程度方向和垂直方向上做线性插值
- 如上图,四个Q点是原图中间隔P点近来的四个点,起首将P投影到程度方向上,对两个R点分别举行一次程度线性插值,再在竖直方向上对两个R点举行线性插值得到P点的像素值
3.双三次插值
- 与双线性插值法雷同,该方法也是通过映射,在映射点的邻域内通过加权来得到放大图像中的像素值。不同的是,双三次插值法须要原图像中近邻的16个点来加权,也就是4x4的网格。
4.代码展示
- img = cv.imread(r"img\cat1.png")
- h,w = img.shape[:2]
- M = cv.getRotationMatrix2D((w//2,h//2),0,0.6)
- # img1 = cv.warpAffine(img,M,(w,h),flags=cv.INTER_NEAREST) #最近邻插值
- # img1 = cv.warpAffine(img,M,(w,h),flags=cv.INTER_LINEAR) #双线性插值
- # img1 = cv.warpAffine(img,M,(w,h),flags=cv.INTER_AREA) #像素区域插值
- # img1 = cv.warpAffine(img,M,(w,h),flags=cv.INTER_CUBIC) #双三次插值
- img1 = cv.warpAffine(img,M,(w,h),flags=cv.INTER_LANCZOS4) #Lanczos插值
- cv.imshow('img1',img1)
- cv.waitKey(0)
- cv.destroyAllWindows()
复制代码 THE END
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|