opencv 变换,opencv 图像变换
几何变换几何变换是指将一幅图像映射成另一幅图像的操作。
使用缩放功能cv2.resize()缩放图像。
DST=CV2.resize (src,dsize [,fx [,fy [,interpolation]]) DST表示输出目标图像,与src类型相同,大小为dsize(值不为零时),也可以通过src.size(),fx,fy计算。Src表示要缩放的原始图像,dsize表示输出图像大小。Fx代表水平比例。Fy代表垂直比例。
在cv2.resize()函数中,目标图像的大小可以通过“参数dsize”或“参数fx和fy”之一来指定,如下所述。
1:由参数dsize指定。
如果指定了参数dsize的值,则无论是否指定了参数fx和fy的值,目标图像的大小都由参数dsize确定。
dsize中的第一个参数对应于缩放图像的宽度(宽度,即列cols的数量,与参数fx相关),第二个参数对应于缩放图像的高度(高度,即行,与参数fy相关)
当指定参数dsize的值时,X方向上的缩放大小(参数fx)是:(双倍)dsize.width/src.cols.同时,Y方向上的缩放大小(参数fy)是:
(double)dsize.height/src.rows情况2:由参数fx和fy指定
如果参数dsize的值为None,则目标图像的大小由参数fx和fy确定。此时,目标图像的大小为:
dsize=Size(round(fx*src.cols),round(fy*src.rows))
目标图像dst的最终大小和类型由src、dsize、fx和fy指定。
插值代表插值方法
插值是指在对图像进行几何处理时,将值赋给无法直接通过映射得到值的像素。
目标图像中的这个像素点无法对应到原始图像中的某个特定位置,所以需要对这些像素进行插值来完成映射。缩小图像时,INTER_AREA插值可以得到最好的效果。在放大图像时,三次样条插值(INTER_CUBIC)和双线性插值(INTER_LINEAR)都能达到很好的效果。三次样条插值比较慢,双线性插值比较快,效果也不逊色。
例子
使用函数cv2.resize()简单地缩放数组。
导入cv2
将numpy作为np导入
img=np.ones([2,4,3],dtype=np.uint8)
size=img.shape[:2]
rst=cv2.resize(img,size)
print(img.shape=\n ,img.shape)
print(img=\n ,img)
print(rst.shape=\n ,rst.shape)
打印( rst=\n ,rst)注释
目标图像中的行数是原始图像中的列数。目标图像中的列数就是原始图像中的行数。函数cv2.resize()中的dsize参数与图像形状属性在行和列的顺序上不一致。
在shape属性中,第一个值对应于行数,第二个值对应于列数。在dsize参数中,第一个值对应于列数,第二个值对应于行数。使用cv2.resize()函数时,要特别注意参数dsize的属性顺序。
例子
使用函数cv2.resize()完成简单的图像缩放。导入cv2
img=cv2.imread(lena.jpg )
rows,cols=img.shape[:2]
size=(int(cols*0.9),int(rows*0.5))
rst=cv2.resize(img,size)
print(img.shape=,img.shape)
Print(rst.shape=,rst.shape)控制函数cv2.resize()的fx和fy参数,完成图像缩放导入cv2。
img=cv2.imread(lena.jpg )
rst=cv2.resize(img,None,fx=2,fy=0.5)
print(img.shape=,img.shape)
打印( rst。shape=,rst。shape) FX水平缩放,fy垂直缩放。图像的翻转由函数cv2.flip()实现
该功能可以实现水平方向、垂直方向以及同时两个方向的图像翻转。
Dst=cv2.flip( src,flipCode )dst表示与原始图像大小和类型相同的目标图像。Src表示要处理的原始图像。flipCode表示旋转类型。
在这个函数中,目标像素和原始像素之间的关系可以表示为一个例子。
使用函数cv2.flip()翻转图像。
导入cv2
img=cv2.imread(lena.jpg )
x=cv2.flip(img,0)
y=cv2.flip(img,1)
xy=cv2.flip(img,-1)
cv2.imshow(img ,img)
cv2.imshow(x ,x)
cv2.imshow(y ,y)
cv2.imshow(xy ,xy)
cv2.waitKey()
2.cv2.destroyAllWindows()仿射仿射变换是指一幅图像可以通过一系列的几何变换进行平移、旋转等操作。
这种变换可以保持图像的平坦度和平行度。
直线性是指图像经过仿射变换后,直线仍然是直线;平行性是指图像的仿射变换完成后,平行线仍然是平行线。
OpenCV中的仿射函数是cv2.warpAffine(),通过变换矩阵(映射矩阵)M进行变换,具体为:
Dst (x,y)=src (M11x M12YM13,M21x M22YM23)通过变换矩阵m将原图像O变换为仿射图像R。
仿射函数cv2.warpAffine()用于变换图像。该函数的语法格式如下:
DST=CV2。Warpaffine (src,m,dsize [,flags [,border mode [,border value]]) DST表示仿射输出图像,与原始图像具有相同的类型。Dsize决定了输出图像的实际大小。Src将原始图像表示为仿射的。m表示一个23的变换矩阵。不同的仿射变换可以通过使用不同的变换矩阵来实现。Dsize表示输出图像的大小。Flags代表插值方法,默认为INTER_LINEAR。当值为WARP_INVERSE_MAP时,表示M为逆变换类型,实现了从目标图像dst到原始图像src的逆变换。BorderMode表示边缘类型,默认值为BORDER_CONSTANT。当值为BORDER_TRANSPARENT时,表示目标图像中的值没有变化,这些值对应的是原始图像中的异常值。BorderValue表示边界值,默认情况下为0。利用OpenCV中的函数cv2.warpAffine()实现仿射变换。忽略其可选参数后的语法格式为:
Dst=cv2.warpAffine( src,M,dsize ),其通过转换矩阵M:
Dst (x,y)=src (M11x M12M2YM13,M21x M22YM23)仿射变换完全依赖于变换矩阵m。
将翻译后的原图像src向右移动100像素,向下移动200像素,对应关系为:
Dst (x,y)=src (x 100,y 200)完成上述表达式,即:
Dst (x,y)=src (1 x 0 y 100,0 x 1 y 200)可以确定对应变换矩阵M中每个元素的值如下:
例子
图像翻译
导入cv2
将numpy作为np导入
img=cv2.imread(lena.jpg )
高度,宽度=img.shape[:2]
x=100
y=200
M=np.float32([[1,0,x],[0,1,y]])
move=cv2.warpAffine(img,M,(width,height))
cv2.imshow(原始,img)
cv2.imshow(move ,move)
cv2.waitKey()
2.cv2.getRotationMatrix2D()可用于通过旋转destructionWindows()函数来获取变换矩阵。该函数的语法格式为:
retval=cv2 . getrotationmatrix 2d(Center,angle,scale) Center是旋转的中心点。Angle是旋转角度,正数表示逆时针旋转,负数表示顺时针旋转。Scale是变换比例(缩放大小)。如果要将图像的中心作为一个点,逆时针旋转45,将目标图像缩小到原图像的0.6倍,调用函数cv2.getRotationMatrix2D()生成变换矩阵M时使用的语句是:
m=cv2 . getrotationmatrix 2d((width/2,height/2),45,0.6)示例
图像旋转
导入cv2
img=cv2.imread(lena.jpg )
高度,宽度=img.shape[:2]
M=cv2.getRotationMatrix2D((宽度/2,高度/2),45,0.6)
rotate=cv2.warpAffine(img,M,(width,height))
cv2.imshow(原始,img)
cv2.imshow(rotation ,rotate)
cv2.waitKey()
2.cv2.destroyAllWindows()的更复杂的仿射变换。对于更复杂的仿射变换,OpenCV提供了函数cv2.getAffineTransform()来生成仿射函数cv2.warpAffine()使用的变换矩阵M。
该函数的语法格式为:
retval=cv2 . getaffinettransform(src,dst) src表示输入图像三点的坐标。Dst表示输出图像的三个点的坐标。值src和dst是包含三个二维数组(x,y)点的数组。
指原始图像和目标图像中平行四边形的三个顶点(左上角、右上角和左下角)。
以上参数通过函数cv2.getAffineTransform()定义了两个平行四边形。
而src和dst中的三个点分别对应平行四边形的左上角、右上角和左下角。
函数cv2.warpAffine()采用由函数cv2.getAffineTransform()获得的变换矩阵M
函数cv2.getAffineTransform()完成指定点的映射后,根据指定点的关系计算确定所有其他点的映射关系。
导入cv2
将numpy作为np导入
img=cv2.imread(lena.bmp )
rows,cols,ch=img.shape
p1=np.float32([[0,0],[列-1,0],[0,行-1]])
p2=np.float32([[0,行*0.33],[列*0.85,行*0.25],[列*0.15,行*0.7]])
M=cv2.getAffineTransform(p1,p2)
dst=cv2.warpAffine(img,M,(cols,rows))
cv2 . im show( original ,img)
cv2.imshow(result ,dst)
cv2.waitKey()
CV2。破坏性地Windows()透视仿射变换可以将矩形映射到任何平行四边形透视变换,而它可以将矩形映射到任何四边形透视变换。透视变换是通过函数cv2.warpPerspective()实现的
DST=CV2.warp perspective (src,m,dsize [,flags [,border mode [,border value]]) DST表示透视处理后的输出图像,与原图像类型相同。Dsize决定了输出图像的实际大小。Src表示要透视的图像。m表示一个33的变换矩阵。Dsize表示输出图像的大小。Flags代表插值方法,默认为INTER_LINEAR。当该值为WARP_INVERSE_MAP时,表示M为逆变换类型,可以实现从目标图像dst到原始图像src的逆变换。BorderMode表示边缘类型,默认值为BORDER_CONSTANT。当值为BORDER_TRANSPARENT时,表示目标图像中的值没有变化,这些值对应的是原始图像中的异常值。BorderValue表示边界值,默认情况下为0。与仿射变换一样,您也可以使用函数来生成函数cv2.warpPerspective()使用的变换矩阵。
该函数为cv2.getPerspectiveTransform(),其语法格式为:
Retval=CV2。GetPerspectiveTransform (src,dst) src表示输入图像的四个顶点的坐标。Dst表示输出图像的四个顶点的坐标。src参数和dst参数是包含四个点的数组,与仿射变换函数cv2.getAffineTransform()中的三个点不同。
图像透视
导入cv2
将numpy作为np导入
img=cv2.imread(demo.bmp )
rows,cols=img.shape[:2]
pts1=np.float32([[150,50]、[400,50]、[60,450]、[310,450]])
pts2=np.float32([[50,50],[行-50,50],[50,列-50],[行-50,列-50]])
m=cv2 . getperspective transform(pt S1,pts2)
dst=cv2.warpPerspective(img,M,(cols,rows))
cv2.imshow(img ,img)
cv2.imshow(dst ,dst)
cv2.waitKey()
2.cv2.destroyAllWindows()重映射将一个图像中的像素放置到另一个图像中的指定位置。这个过程称为重新映射。
OpenCV中的重映射函数cv2.remap()具有以下语法格式:
DST=CV2.remap (src,map1,map2,interpolation [,border mode [,border value]]) DST表示目标图像,其大小和类型与src相同。Src代表原始图像。1 map参数有两个可能的值:代表(x,y)点的map。CV_16SC2,CV_32FC1,CV_32FC2类型的点的x值(x,y)。map参数2也有两个可能的值:当map1表示(x,y)时,值为空。当map1表示(x,y)点的x值时,就是CV_16UC1,CV_32FC1型(x,y)点的y值。
Map1、map2不仅可以表示一个点,还可以表示多个点。
Interpolation代表插值方法,这里不支持INTER_AREA方法。
BorderMode代表边框模式。当值为BORDER_TRANSPARENT时,表示目标图像和相应源图像中异常值的像素将不会被修改。BorderValue表示边界值,默认为0。了解映射参数
重新映射通过修改像素的位置来获得新的图像。
在构造新图像时,需要确定新图像中每个像素在原始图像中的位置。因此,映射函数的作用是寻找新图像像素在原图像中的位置,这是将新图像像素映射到原图像的过程,所以称为逆映射。
参数map1和参数map2用于解释反向映射x,map2指坐标x,map2指坐标Y.map1和map2的值是浮点数。因此,目标图像可以被映射回非整数值,这意味着目标图像可以被“反向映射”到原始图像中两个像素之间的位置(这里没有像素值)。可以用不同的方法实现插值,函数中的插值参数可以控制插值方法。
由于参数map1和参数map2的值都是浮点数,函数cv2 . re map()可以实现的映射关系变得更加任意,可以通过自定义映射参数实现不同形式的映射。
函数cv2.remap()中的参数map1是指像素所在的列号,参数map2是指像素所在的行号。
例如,如果要将目标图像(映射结果图像)中的A点映射到原始图像中的像素点B,需要将A点对应的参数map1的值设置为3,将参数map2的值设置为0。所以一般来说,map1写成mapx,map2写成mapy。
如果要将目标图像(映射结果图像)中的所有像素映射到原始图像中的像素B,需要将参数map1中的所有值设置为3,将参数map2中的所有值设置为0。
如果要将目标图像(映射结果图像)中的所有像素映射到原始图像中的像素B,需要将参数map1中的所有值设置为3,将参数map2中的所有值设置为0。
例子
将目标阵列中的所有像素映射到原始图像的第0行和第3列中的像素,
您可以确定:
用于指定列的参数map1(mapx)中的值都是3。用于指定行的参数map2(mapy)中的值都是0。导入cv2
将numpy作为np导入
img=np.random.randint(0,256,size=[4,5],dtype=np.uint8)
rows,cols=img.shape
mapx=np.ones(img.shape,np.float32)*3
mapy=np.ones(img.shape,np.float32)*0
rst=cv2.remap(img,mapx,mapy,cv2。INTER _线性)
print(img=\n ,img)
print(mapx=\n ,mapx)
print(mapy=\n ,mapy)
print(rst=\n ,rst)
#目标图像(数组)dst中的所有值都是从原始图像的第0行第3列中的像素值252导出的。复制此功能可复制图像。
映射时,按如下方式处理参数:
将map1的值设置为相应位置的x轴坐标值。将map2的值设置为相应位置的y轴坐标值。导入cv2
导入cv2
将numpy作为np导入
img=cv2.imread(img\\lena.jpg )
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
对于范围内的I(行):
对于范围内的j(列):
mapx.itemset((i,j),j)
mapy.itemset((i,j),I)
rst=cv2.remap(img,mapx,mapy,cv2。INTER _线性)
cv2.imshow(原始,img)
cv2.imshow(result ,rst)
cv2.waitKey()
2.cv2.destroyAllWindows()绕X轴翻转。如果您希望图像围绕X轴翻转,这意味着在贴图过程中:
x轴的值保持不变。y轴的值与作为对称轴的x轴交换。反映在地图1和地图2中:
map1的值保持不变。map2的值调整为“总行号-1-当前行号”。导入cv2
将numpy作为np导入
img=cv2.imread(img\\lena.jpg )
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
对于范围内的I(行):
对于范围内的j(列):
mapx.itemset((i,j),j)
mapy.itemset((i,j),rows-1-i)
rst=cv2.remap(img,mapx,mapy,cv2。INTER _线性)
cv2.imshow(原始,img)
cv2.imshow(result ,rst)
cv2.waitKey()
2.cv2.destroyAllWindows()绕y轴翻转。如果您希望图像围绕y轴翻转,这意味着在贴图过程中:
y轴的值保持不变。x轴的值与作为对称轴的y轴交换。反映在地图1和地图2中:
map2的值保持不变。map1的值调整为“总列数-1-当前列数”。导入cv2
将numpy作为np导入
img=cv2.imread(img\\lena.jpg )
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
对于范围内的I(行):
对于范围内的j(列):
mapx.itemset((i,j),cols-1-j)
mapy.itemset((i,j),I)
rst=cv2.remap(img,mapx,mapy,cv2。INTER _线性)
cv2.imshow(原始,img)
cv2.imshow(result ,rst)
cv2.waitKey()
2.cv2.destroyAllWindows()围绕x轴和y轴翻转x轴的值,并以y轴为对称轴进行交换。y轴的值与作为对称轴的x轴交换。反映在地图1和地图2中:
map1的值调整为“总列数-1-当前列数”。map2的值调整为“总行号-1-当前行号”。导入cv2
将numpy作为np导入
img=cv2.imread(img\\lena.jpg )
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
对于范围内的I(行):
对于范围内的j(列):
mapx.itemset((i,j),cols-1-j)
mapy.itemset((i,j),rows-1-i)
rst=cv2.remap(img,mapx,mapy,cv2。INTER _线性)
cv2.imshow(原始,img)
cv2.imshow(result ,rst)
cv2.waitKey()
2.破坏性的Windows () X轴和Y轴互换。如果要互换图像的X轴和Y轴,就意味着对于贴图过程中的任意一点,其X轴和Y轴坐标都需要互换。
反映在mapx和mapy上:
mapx的值被调整到该行的行号。mapy的值调整为该列的列号。
如果行数和列数不一致,可能会出现在上述操作中无法映射值的情况。默认情况下,无法映射的值被视为0。
导入cv2
将numpy作为np导入
img=cv2.imread(img\\lena.jpg )
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
对于范围内的I(行):
对于范围内的j(列):
mapx.itemset((i,j),I)
mapy.itemset((i,j),j)
rst=cv2.remap(img,mapx,mapy,cv2。INTER _线性)
cv2.imshow(原始,img)
cv2.imshow(result ,rst)
cv2.waitKey()
2.cv2.remap()图像缩放使用函数CV2.remap()缩小图像。
图像缩小后,可以固定在其中心周围的区域。
在目标图像的x轴(0.25x轴长度,0.75x轴长度)区间中生成缩小图像;x轴其余部分中的点是从x轴上任意点的值中采样的。在目标图像的y轴(0.25 y y轴长度,0.75 y y轴长度)区间中生成缩小图像;Y轴其余部分中的点是从Y轴上的任意点采样的。
为便于处理,不在上述区域的点取(0,0)坐标点的值。
导入cv2
将numpy作为np导入
img=cv2.imread(img\\lena.jpg )
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
对于范围内的I(行):
对于范围内的j(列):
如果0.25 *列i 0.75 *列和0.25 *行j 0.75 *行:
Mapx.itemset ((i,j),2 *(j-cols * 0.25)0.5)# x1 x(x:0,x1:0.25) (x:1,x1:0.75)的映射函数
mapy.itemset((i,j),2*( i行*0.25 ) 0.5)
否则:
mapx.itemset((i,j),0)
mapy.itemset((i,j),0)
rst=cv2.remap(img,mapx,mapy,cv2。INTER _线性)
cv2.imshow(原始,img)
cv2.imshow(result ,rst)
cv2.waitKey()
cv2.destroyAllWindows()
风暴中的白杨
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。