我是靠谱客的博主 哭泣哑铃,这篇文章主要介绍2D图像像素点操作——平移,旋转,缩放 tcy,现在分享给大家,希望可以做个参考。

复制代码
1
2
3
4
5
6
7
8
9
10
1.1.用途: 平移(Translation)、缩放(Scale)、翻转(Flip)、旋转(Rotation)和剪切(Shear) 2.1.平移 说明: 点(x,y)向x方向移动dx, y方向移动dy 变换后坐标: (x',y')=(x+dx,y+dy) 矩阵表示: [x',y',1]=[1 0 dx][0 1 dy] [0 0 1]*[[x],[y],[1]]
复制代码
1
2
3
4
5
6
7
2.2.缩放 说明: 设点(x,y)在x轴方向扩大sx倍,y轴方向扩大sy倍 变换后坐标: (x',y')=(sx * x,sy * y) 矩阵表示: [x',y',1]=[[sx 0 0] [0 sy 0][0 0 1]] *[[x],[y],[1]]#缩放矩阵
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2.3.旋转 说明: 设点A(x1,y1)以原点(x0,y0)为圆心旋转θ度,求旋转后 A'(x',y')坐标值. 变换后坐标: y = rows-y x' = x0 + (x1 - x0) cosθ - (y1 - y0)sinθ y' = y0 +(y1 - y0)cosθ + (x1 - x0) sinθ y' = rows-y' 变换后坐标(x',y'): x=rcos(b);y=rsin(b); x'=rcos(a+b)=rcosacosb−rsinasinb=xcosa−ysina;(合角公式) y'=rsin(a+b)=rsinacosb+rcosasinb=xsina+ycosa; 旋转变换矩阵: [[cosa −sina][sina cosa]]#逆时针
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2.4。翻转 [x',y',1]=[ [1 0 0 ][0 -1 N+1][0 0 1] ]*[x,y,1] ============================================================================================= 2.5.等距变换 R=[ [r11 r12 dx]#平移变换和旋转变换的复合;等距变换前后长度,面积,线段之间的夹角都不变 [r21 r22 dy]#左上角2×2矩阵为旋转部分,tx和ty为平移因子 [0 0 1 ]#有三自由度,即旋转,x方向平移,y方向平移。 ] ============================================================================================= 2.6.切向变换 相当于一个横向截切与一个纵向剪切的复合常用于产生弹性物体的变形处理 [ [ 1 shx 0] [shy 1 0] [ 0 0 1] ] #https://www.cnblogs.com/liekkas0626/p/5238564.html ============================================================================================= 2.7.相似变换 相似变换相当于是等距变换和均匀缩放的一个复合 相似变换前后长度比,夹角,虚圆点I,J保持不变。相似变换其实与相似三角形之间是有类似的 S=[ [s*r11 s*r12 dx]#左上角2×2矩阵为旋转部分,dx和dy为平移因子 [s*r21 s*r22 dy]#有4个自由度,即旋转,x方向平移,y方向平移和缩放因子s [ 0 0 1 ] ] ============================================================================================= 2.8.仿射变换 性质: 1)保持二维图形“平直性”和“平行性”,面积比保持不变; 2)不具有保角性和保持距离比的性质不能保持垂直性角度会改变 共线线段或者平行线段的长度比保持不变,矢量的线性组合不变 3)有6自由度,即旋转4个,也就是前述大矩形的4个元素都可以同时改变,x方向平移,y方向平移。 包括平移、旋转、缩放、倾斜(错切、剪切、偏移)、翻转变换 说明: 平直性:变换后直线还是直线、圆弧还是圆弧。 平行性:平行线还是平行线,直线上点的位置顺序不变 计算: [u,v,1]=[[a1 b1 c1] [a2 b2 c2 ][0 0 1]]*[x,y,1]

 

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
3.投影变换(透视变换,射影变换) 3.1.射影变换: 是最一般的线性变换。有8个自由度。 射影变换保持重合关系和交比不变。但不会保持平行性。即它会使得仿射变换产生非线性效应。 3.2.射影变换仿射变换区别: 射影变换变换矩阵[[a11 a12 a13] [a21 a22 a23 ][a31 a32 a33]] 仿射变换变换矩阵[[a11 a12 a13] [a21 a22 a23 ][0 0 1]] 在仿射的前提下,当左上角2×2矩阵正交时为欧式变换,左上角矩阵行列式为1时为定向欧式变换。 所以射影变换包含仿射变换,而仿射变换包含欧式变换。 [a11 a12 ] [a21 a22 ]表示线性变换如scaling(尺度),shearing(剪切)和ratotion(旋转) [a13 a23]表示平移参数,一个确定在x方向上的平移一个确定在y方向上的平移; [a31 a32]用于产生透视变换。从这里所以可以理解成仿射等是透视变换的特殊形式 名词解释: projective transformation(投影变换) = homography(单应性变换) = collineation( 直射变换) ============================================================================================= 4.备注最终变换矩阵 2D基本模型视图变换只有上面这3种 如某变换先经过平移(对应平移矩阵A)再旋转(对应旋转矩阵B)再缩放(对应缩放矩阵C) 最终变换矩阵 T = ABC. #即3个矩阵按变换先后顺序依次相乘(矩阵乘法不满足交换律,讲究先后顺序)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
5.实例: 旋转矩阵方法没有实现,有高手请补充 # !/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import cv2,math class Pixel(): def __int__(self):pass def __del__(self): pass def movePixelPoint(self,x,y,dx=0,dy=0)->list: b = [[1, 0, dx], [0, 1, dy], [0, 0, 1]]#平移矩阵 X = [[x], [y], [1]] R=np.dot(b, X) # X'=bX R=R.reshape(3)[0:2] return R.tolist() def zoomPixelPoint(self,x,y,sx=1,sy=1)->list: b = np.array([[sx, 0, 0], [0, sy, 0], [0, 0, 1]],dtype=np.float)#缩放矩阵 X = np.array([[x], [y], [1]],dtype=np.float) R = np.dot(b, X) # X'=bX R = np.uint8(R.round()) R = R.reshape(3)[0:2] return R.tolist() def rotatePixelPoint(self,x,y,θ:int=0.0,center=(0.0,0.0),rows=480)->list: cosθ=math.cos(math.radians(θ)) sinθ = math.sin(math.radians(θ)) x1 = x y1 = rows - y x0 = center[0] y0 = rows - center[1] x = (x1-x0)*cosθ - (y1 - y0)*sinθ + x0 y = (x1-x0)*sinθ + (y1 - y0)*cosθ + y0 x=x y = rows - y return x,y def rotatePixelPoint_(self,x,y,angle:int=0.0,center=(0.0,0.0))->list: scale=1 x0, y0 = center cosθ = math.cos(math.radians(angle)) sinθ = math.sin(math.radians(angle)) α ,β= scale*cosθ,scale*sinθ # b = [[ α,β,(1- α)*x0 - β*y0],[ -β,α,β*x0+(1 - α)*y0],[0, 0, 1]] b =[[cosθ ,- sinθ,(1 - cosθ)*x0 + y0 * sinθ],[sinθ , cosθ,(1 - cosθ)*y0 - x0 * sinθ], [0 , 0 , 1]] X = [[x], [y], [1]] R = np.dot(b, X) R = np.uint8(R.round()) R = R.reshape(3)[0:2] R=R.tolist() return R #==================================================================================== def __move__(self,src, pos: '(int,int)') -> np.ndarray: # 彩色平移 rows, cols = src.shape[:2] M = np.float32([[1, 0, pos[0]], [0, 1, pos[1]]]) # 平移转换矩阵: 右移动100;下移动50 dst = cv2.warpAffine(src, M, (cols, rows)) # 图像的宽度和高度 return dst def __rotation_Scale__(self,src, angle:'float',rotation_center:'(float,float)'=None,scale:'float'=1)->np.ndarray:#彩色:旋转缩放 rows, cols = src.shape[:2] cx=rotation_center[0] if rotation_center else cols/2.0 cy=rotation_center[1] if rotation_center else rows/2.0 # cols - 1 and rows - 1 are the coordinate limits. M = cv2.getRotationMatrix2D((cx, cy), angle, scale) dst = cv2.warpAffine(src, M, (int(2*cx), int(2*cy))) return dst def __polylines__(self,img,pts:'ndarray.int32', isClosed:'bool', color:'tuple',thickness=1,lineType=8)->np.ndarray: tmp=thickness if thickness<0:thickness=1 cv2.__polylines__(img, pts, isClosed, color, thickness, lineType)# 绘图多边形(pts多边形各定点int32, Isclosed是否封闭) if tmp<0: cv2.fillPoly(img, pts, color) return img def __getColorPicture__(self): img = np.zeros((480, 640, 3), dtype=np.uint8) pts = np.array([[100, 50], [200, 300], [70, 200], [50, 100]], np.int32) pts = pts.reshape((-1, 1, 2)) img = self.__polylines__(img, [pts], True, (125, 255, 0), -1) cv2.putText(img, 'A', (100, 50-10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255), 1, 8) cv2.putText(img, 'B', (200, 300 + 10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255), 1, 8) cv2.putText(img, 'C', (70-20, 200+10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255), 1, 8) return img def __getColorPictureInCenter__(self): rgb=self.__getColorPicture__() img,rect,box=self.__getContours__(rgb) # 移动到中心 cx_rect, cy_rect = int(round(rect[0][0], 0)), int(round(rect[0][1], 0)) cv2.drawMarker(rgb, (cx_rect, cy_rect), (0, 0, 255)) h, w = int(round(rgb.shape[0] / 2, 0)), int(round(rgb.shape[1] / 2, 0)) dx, dy = w - cx_rect, h - cy_rect rgb_center = self.__move__(rgb, (dx, dy)) return rgb_center def __getContours__(self,rgb): img=rgb.copy() gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY) # 寻找二值图像轮廓 ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[1] cv2.drawContours(img, [cnt], 0, (125, 125, 125), 2) # 获取最小外接矩形 rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box.round()) cv2.drawContours(img, [box], 0, (0, 255, 255), 2) return img,rect,box def test_movePixelPoint(self,dx=50,dy=50): rgb=self.__getColorPictureInCenter__() img1,rect1,box1=self.__getContours__(rgb) img_ = self.__move__(rgb, (dx, dy)) img2, rect2,box2 = self.__getContours__(img_) for i in range(4): x1,y1=box1[i] x2,y2=box2[i] x,y=self.movePixelPoint(x1,y1,dx,dy) x_,y_=x1+dx,y1+dy print('[%s %s %s %s ] [(x,y)=%s;(x1,y1)=%s;(x2,y2)=%s;]'%((x2-x1==dx),(y2-y1==dy),x2-x1-dx,y2-y1-dy,(x,y),(x1,y1),(x2,y2))) cv2.imshow('s1', img1) cv2.imshow('s2', img2) cv2.waitKey() def test_zoomPixelPoint(self,fx=0.5, fy=0.5): rgb = self.__getColorPictureInCenter__() img1, rect1, box1 = self.__getContours__(rgb) img_ = cv2.resize(rgb,None,fx=fx, fy=fy, interpolation = cv2.INTER_CUBIC) img2, rect2, box2 = self.__getContours__(img_) for i in range(4): x1, y1 = box1[i] x2, y2 = box2[i] x,y=self.zoomPixelPoint(x1, y1, sx=fx, sy=fy) print('[%s %s %s %s ] [(x,y)=%s;(x1,y1)=%s;(x2,y2)=%s;]' % ((x2 - x == 0), (y2 - y == 0), x2 - x , y2 - y, (x, y), (x1, y1), (x2, y2))) cv2.imshow('s1', img1) cv2.imshow('s2', img2) cv2.waitKey() def test_rotatePixelPoint(self): rotateangle = -180 center = (320, 240) rgb = self.__getColorPictureInCenter__() img1, rect1, box1 = self.__getContours__(rgb) img_ = self.__rotation_Scale__(rgb, angle=rotateangle,rotation_center=center,scale=1) img2, rect2, box2 = self.__getContours__(img_) for i in range(4): x1,y1=box1[i] x2, y2 = box2[i] x,y=self.rotatePixelPoint(x1, y1, rotateangle, center) print('[%s %s %s %s ] [(x,y)=%s;(x1,y1)=%s;(x2,y2)=%s;]' % ( (x2 - x == 0), (y2 - y == 0), x2 - x, y2 - y, (x, y), (x1, y1), (x2, y2))) cv2.imshow('s1', img1) cv2.imshow('s2', img2) cv2.waitKey() if __name__ =='__main__': a=Pixel() # a.test_movePixelPoint(dx=150,dy=50) """ [True True 0 0 ] [(x,y)=(481, 432);(x1,y1)=(331, 382);(x2,y2)=(481, 432);] [True True 0 0 ] [(x,y)=(380, 181);(x1,y1)=(230, 131);(x2,y2)=(380, 181);] [True True 0 0 ] [(x,y)=(460, 149);(x1,y1)=(310, 99);(x2,y2)=(460, 149);] [True True 0 0 ] [(x,y)=(561, 400);(x1,y1)=(411, 350);(x2,y2)=(561, 400);] """ # a.test_zoomPixelPoint() """ [False True -1 0 ] [(x,y)=(166, 191);(x1,y1)=(331, 382);(x2,y2)=(165, 191);] [True False 0 -1 ] [(x,y)=(115, 66);(x1,y1)=(230, 131);(x2,y2)=(115, 65);] [True False 0 -1 ] [(x,y)=(155, 50);(x1,y1)=(310, 99);(x2,y2)=(155, 49);] [False False -1 -1 ] [(x,y)=(206, 175);(x1,y1)=(411, 350);(x2,y2)=(205, 174);] """ a.test_rotatePixelPoint() """ (x,y)=(309.0, 98.0) (x1,y1)=(331, 382) C (x2,y2)=(330, 381) A (x,y)=(410.0, 349.0) (x1,y1)=(230, 131) D (x2,y2)=(229, 130) B (x,y)=(330.0, 381.0) (x1,y1)=(310, 99) A (x2,y2)=(309, 98) C (x,y)=(229.0, 130.0) (x1,y1)=(411, 350) B (x2,y2)=(410, 349) D (x,y)=(330.0, 381.0) (x1,y1)=(310, 99) A (x2,y2)=(330, 381) A (x,y)=(229.0, 130.0) (x1,y1)=(411, 350) B (x2,y2)=(229, 130) B (x,y)=(309.0, 98.0) (x1,y1)=(331, 382) C (x2,y2)=(309, 98) C (x,y)=(410.0, 349.0) (x1,y1)=(230, 131) D (x2,y2)=(410, 349) D """

 

 

 

 

最后

以上就是哭泣哑铃最近收集整理的关于2D图像像素点操作——平移,旋转,缩放 tcy的全部内容,更多相关2D图像像素点操作——平移,旋转,缩放内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(95)

评论列表共有 0 条评论

立即
投稿
返回
顶部